diff --git a/.babelrc b/.babelrc index 84ed5f15b..a5b818f53 100644 --- a/.babelrc +++ b/.babelrc @@ -1,3 +1,3 @@ { - "plugins": ["@babel/plugin-proposal-class-properties"] + "plugins": [] } diff --git a/.eslintrc b/.eslintrc index 3675d45a9..dc3471b20 100644 --- a/.eslintrc +++ b/.eslintrc @@ -2,7 +2,9 @@ "extends": "standard", "parser": "@babel/eslint-parser", "parserOptions": { - "ecmaVersion": 2020 + "ecmaVersion": 2020, + "requireConfigFile" : false, + "babelOptions": { "configFile": "./.babelrc" } }, "rules": { "indent": ["error", 4], @@ -14,5 +16,5 @@ "jasmine": true, "jest": true }, - "ignorePatterns": ["src/**/*.d.ts", "dist/*"] + "ignorePatterns": ["src/**/*.d.ts", "dist/*", "integration-test/extension/autofill.js"] } diff --git a/.github/workflows/password-rules.yml b/.github/workflows/password-rules.yml new file mode 100644 index 000000000..bdb240cbe --- /dev/null +++ b/.github/workflows/password-rules.yml @@ -0,0 +1,38 @@ +name: Password Rules + +on: + pull_request: + types: [opened] + +jobs: + test: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - name: Use Node.js 16 + uses: actions/setup-node@v1 + with: + node-version: 16.x + - uses: actions/cache@v2 + with: + path: ~/.npm + key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node- + - uses: actions/github-script@v6 + with: + #language=javascript + script: | + const current = require('./packages/password/rules.json') + const {summary, intoMarkdown, REMOTE_URL} = require('./packages/password/scripts/rules.js') + const result = await github.request(REMOTE_URL); + const lines = summary(current, JSON.parse(result.data)); + + if (lines.length === 0) return; + + await github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: intoMarkdown(lines), + }) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 000000000..8a16cc554 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,35 @@ +name: Test + +on: [push, pull_request] + +jobs: + test: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - name: Use Node.js 16 + uses: actions/setup-node@v1 + with: + node-version: 16.x + - uses: actions/cache@v2 + with: + path: ~/.npm + key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node- + - name: npm install + run: "npm install" + - name: "Clean tree" + run: "npm run test:clean-tree" + - name: "ESLint" + run: "npm run lint" + - name: "Typescript" + run: "npm run tsc" + - name: "Unit Tests" + run: "npm run test:unit" + - name: "Password unit tests" + run: "npm run test:passwords" + - name: "Install dependencies for CI integration tests" + run: sudo apt-get install xvfb + - run: npm rebuild puppeteer + - run: npm run test-int-x diff --git a/.gitignore b/.gitignore index 5dadf0471..184d03493 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ - +test-report.html .cache/ coverage/ !dist/index.html diff --git a/.nvmrc b/.nvmrc index b6a7d89c6..23d9c36a1 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -16 +16.13.2 diff --git a/Gruntfile.js b/Gruntfile.js index 770d9fc5c..de650f995 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -12,7 +12,12 @@ module.exports = function (grunt) { dist: { options: { transform: [ - ['babelify', { presets: ['@babel/preset-env'] }] + [ + 'babelify', { + presets: ['@babel/preset-env'], + global: true + } + ] ] }, files: { @@ -27,10 +32,8 @@ module.exports = function (grunt) { target: 'src/**/*.js' }, exec: { - copyAutofillStylesToCSS: 'cp src/UI/styles/autofill-tooltip-styles.js dist/autofill.css && sed -i "" \'/`/d\' dist/autofill.css', - copyHostStyles: 'cp src/UI/styles/autofill-host-styles.css dist/autofill-host-styles_chrome.css && cp src/UI/styles/autofill-host-styles.css dist/autofill-host-styles_firefox.css', - // Firefox and Chrome treat relative url differently in injected scripts. This fixes it. - updateFirefoxRelativeUrl: `sed -i "" "s/chrome-extension:\\/\\/__MSG_@@extension_id__\\/public/../g" dist/autofill-host-styles_firefox.css` + copyAssets: 'npm run copy-assets', + copyHtml: 'cp src/TopAutofill.html dist/TopAutofill.html' }, /** * Run predefined tasks whenever watched files are added, @@ -38,22 +41,24 @@ module.exports = function (grunt) { */ watch: { scripts: { - files: ['src/**/*.js'], - tasks: ['browserify'] + files: ['src/**/*.js', 'packages/password/**/*.{json,js}'], + tasks: ['browserify', 'exec:copyAssets'] + }, + html: { + files: ['src/**/*.html'], + tasks: ['exec:copyHtml'] }, styles: { - files: ['src/**/*.css'], - tasks: ['exec:copyAutofillStylesToCSS', 'exec:copyHostStyles', 'exec:updateFirefoxRelativeUrl'] + files: ['src/**/*.css', 'src/UI/styles/*'], + tasks: ['exec:copyAssets'] } } }) grunt.registerTask('default', [ - 'eslint', 'browserify', - 'exec:copyAutofillStylesToCSS', - 'exec:copyHostStyles', - 'exec:updateFirefoxRelativeUrl' + 'exec:copyHtml', + 'exec:copyAssets' ]) grunt.registerTask('dev', ['default', 'watch']) } diff --git a/dist/TopAutofill.html b/dist/TopAutofill.html new file mode 100644 index 000000000..107cc0130 --- /dev/null +++ b/dist/TopAutofill.html @@ -0,0 +1,13 @@ + + + + + +
+ + diff --git a/dist/autofill.css b/dist/autofill.css index bfcd24604..9239ca591 100644 --- a/dist/autofill.css +++ b/dist/autofill.css @@ -14,32 +14,36 @@ transform: translate(-1000px); z-index: 2147483647; } -.wrapper--data { +:not(.top-autofill).wrapper--data { font-family: 'SF Pro Text', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; } -.tooltip { +:not(.top-autofill) .tooltip { position: absolute; width: 300px; max-width: calc(100vw - 25px); z-index: 2147483647; } +.tooltip--data, #topAutofill { + background-color: rgba(242, 240, 240, 0.9); + -webkit-backdrop-filter: blur(40px); + backdrop-filter: blur(40px); +} .tooltip--data { + padding: 6px; + font-size: 13px; + line-height: 14px; + width: 315px; +} +:not(.top-autofill) .tooltip--data { top: 100%; left: 100%; - padding: 4px; border: 0.5px solid rgba(0, 0, 0, 0.2); border-radius: 6px; - background-color: rgba(242, 240, 240, 0.9); - -webkit-backdrop-filter: blur(40px); - backdrop-filter: blur(40px); - font-size: 13px; - line-height: 15px; - color: #222222; box-shadow: 0 10px 20px rgba(0, 0, 0, 0.32); } -.tooltip--email { +:not(.top-autofill) .tooltip--email { top: calc(100% + 6px); right: calc(100% - 46px); padding: 8px; @@ -76,12 +80,14 @@ .tooltip__button { display: flex; width: 100%; - padding: 4px 8px 7px; + padding: 8px 0px; font-family: inherit; + color: inherit; background: transparent; border: none; border-radius: 6px; } +.tooltip__button.currentFocus, .tooltip__button:hover { background-color: rgba(0, 121, 242, 0.8); color: #FFFFFF; @@ -92,11 +98,10 @@ min-height: 48px; flex-direction: row; justify-content: flex-start; - align-items: center; font-size: inherit; font-weight: 500; + line-height: 16px; text-align: left; - letter-spacing: -0.25px; } .tooltip__button--data > * { opacity: 0.9; @@ -109,33 +114,83 @@ } .tooltip__button--data::before { content: ''; + flex-shrink: 0; + display: block; + width: 32px; + height: 32px; + margin: 0 8px; + background-size: 24px 24px; + background-repeat: no-repeat; + background-position: center 1px; +} +.tooltip__button--data.currentFocus::before, +.tooltip__button--data:hover::before { + filter: invert(100%); +} +.tooltip__button__text-container { + margin: auto 0; +} +.label { display: block; - width: 26px; - height: 26px; - margin: auto 8px auto 0; - background-size: cover; + font-weight: 400; + letter-spacing: -0.25px; + color: rgba(0,0,0,.8); + line-height: 13px; +} +.label + .label { + margin-top: 5px; +} +.label.label--medium { + letter-spacing: -0.08px; + color: rgba(0,0,0,.9) } -.tooltip__button__secondary-text { +.label.label--small { font-size: 11px; + font-weight: 400; + letter-spacing: 0.06px; color: rgba(0,0,0,0.6); } -.tooltip__button:hover .tooltip__button__secondary-text { +.tooltip__button.currentFocus .label, +.tooltip__button:hover .label, +.tooltip__button.currentFocus .label, +.tooltip__button:hover .label { color: #FFFFFF; } /* Icons */ .tooltip__button--data--credentials::before { /* TODO: use dynamically from src/UI/img/ddgPasswordIcon.js */ - background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMjRweCIgaGVpZ2h0PSIyNHB4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8dGl0bGU+ZGRnLXBhc3N3b3JkLWljb24tYmFzZTwvdGl0bGU+CiAgICA8ZyBpZD0iZGRnLXBhc3N3b3JkLWljb24tYmFzZSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9IlVuaW9uIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0LjAwMDAwMCwgNC4wMDAwMDApIiBmaWxsPSIjMDAwMDAwIj4KICAgICAgICAgICAgPHBhdGggZD0iTTExLjMzMzMsMi42NjY2NyBDMTAuMjI4OCwyLjY2NjY3IDkuMzMzMzMsMy41NjIxIDkuMzMzMzMsNC42NjY2NyBDOS4zMzMzMyw1Ljc3MTI0IDEwLjIyODgsNi42NjY2NyAxMS4zMzMzLDYuNjY2NjcgQzEyLjQzNzksNi42NjY2NyAxMy4zMzMzLDUuNzcxMjQgMTMuMzMzMyw0LjY2NjY3IEMxMy4zMzMzLDMuNTYyMSAxMi40Mzc5LDIuNjY2NjcgMTEuMzMzMywyLjY2NjY3IFogTTEwLjY2NjcsNC42NjY2NyBDMTAuNjY2Nyw0LjI5ODQ4IDEwLjk2NTEsNCAxMS4zMzMzLDQgQzExLjcwMTUsNCAxMiw0LjI5ODQ4IDEyLDQuNjY2NjcgQzEyLDUuMDM0ODYgMTEuNzAxNSw1LjMzMzMzIDExLjMzMzMsNS4zMzMzMyBDMTAuOTY1MSw1LjMzMzMzIDEwLjY2NjcsNS4wMzQ4NiAxMC42NjY3LDQuNjY2NjcgWiIgaWQ9IlNoYXBlIj48L3BhdGg+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0xMC42NjY3LDAgQzcuNzIxMTUsMCA1LjMzMzMzLDIuMzg3ODEgNS4zMzMzMyw1LjMzMzMzIEM1LjMzMzMzLDUuNzYxMTkgNS4zODM4NSw2LjE3Nzk4IDUuNDc5NDUsNi41Nzc3NSBMMC4xOTUyNjIsMTEuODYxOSBDMC4wNzAyMzc5LDExLjk4NyAwLDEyLjE1NjUgMCwxMi4zMzMzIEwwLDE1LjMzMzMgQzAsMTUuNzAxNSAwLjI5ODQ3NywxNiAwLjY2NjY2NywxNiBMMy4zMzMzMywxNiBDNC4wNjk3MSwxNiA0LjY2NjY3LDE1LjQwMyA0LjY2NjY3LDE0LjY2NjcgTDQuNjY2NjcsMTQgTDUuMzMzMzMsMTQgQzYuMDY5NzEsMTQgNi42NjY2NywxMy40MDMgNi42NjY2NywxMi42NjY3IEw2LjY2NjY3LDExLjMzMzMgTDgsMTEuMzMzMyBDOC4xNzY4MSwxMS4zMzMzIDguMzQ2MzgsMTEuMjYzMSA4LjQ3MTQxLDExLjEzODEgTDkuMTU5MDYsMTAuNDUwNCBDOS42Mzc3MiwxMC41OTEyIDEwLjE0MzksMTAuNjY2NyAxMC42NjY3LDEwLjY2NjcgQzEzLjYxMjIsMTAuNjY2NyAxNiw4LjI3ODg1IDE2LDUuMzMzMzMgQzE2LDIuMzg3ODEgMTMuNjEyMiwwIDEwLjY2NjcsMCBaIE02LjY2NjY3LDUuMzMzMzMgQzYuNjY2NjcsMy4xMjQxOSA4LjQ1NzUzLDEuMzMzMzMgMTAuNjY2NywxLjMzMzMzIEMxMi44NzU4LDEuMzMzMzMgMTQuNjY2NywzLjEyNDE5IDE0LjY2NjcsNS4zMzMzMyBDMTQuNjY2Nyw3LjU0MjQ3IDEyLjg3NTgsOS4zMzMzMyAxMC42NjY3LDkuMzMzMzMgQzEwLjE1NTgsOS4zMzMzMyA5LjY2ODg2LDkuMjM3OSA5LjIyMTUyLDkuMDY0NSBDOC45NzUyOCw4Ljk2OTA1IDguNjk1OTEsOS4wMjc5NSA4LjUwOTE2LDkuMjE0NjkgTDcuNzIzODYsMTAgTDYsMTAgQzUuNjMxODEsMTAgNS4zMzMzMywxMC4yOTg1IDUuMzMzMzMsMTAuNjY2NyBMNS4zMzMzMywxMi42NjY3IEw0LDEyLjY2NjcgQzMuNjMxODEsMTIuNjY2NyAzLjMzMzMzLDEyLjk2NTEgMy4zMzMzMywxMy4zMzMzIEwzLjMzMzMzLDE0LjY2NjcgTDEuMzMzMzMsMTQuNjY2NyBMMS4zMzMzMywxMi42MDk1IEw2LjY5Nzg3LDcuMjQ0OTQgQzYuODc1MDIsNy4wNjc3OSA2LjkzNzksNi44MDYyOSA2Ljg2MDY1LDYuNTY3OTggQzYuNzM0ODksNi4xNzk5NyA2LjY2NjY3LDUuNzY1MjcgNi42NjY2Nyw1LjMzMzMzIFoiIGlkPSJTaGFwZSI+PC9wYXRoPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+'); -} -.tooltip__button--data--credentials:hover::before { - background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMjRweCIgaGVpZ2h0PSIyNHB4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8dGl0bGU+ZGRnLXBhc3N3b3JkLWljb24tYmFzZS13aGl0ZTwvdGl0bGU+CiAgICA8ZyBpZD0iZGRnLXBhc3N3b3JkLWljb24tYmFzZS13aGl0ZSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9IlVuaW9uIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0LjAwMDAwMCwgNC4wMDAwMDApIiBmaWxsPSIjRkZGRkZGIj4KICAgICAgICAgICAgPHBhdGggZD0iTTExLjMzMzMsMi42NjY2NyBDMTAuMjI4OCwyLjY2NjY3IDkuMzMzMzMsMy41NjIxIDkuMzMzMzMsNC42NjY2NyBDOS4zMzMzMyw1Ljc3MTI0IDEwLjIyODgsNi42NjY2NyAxMS4zMzMzLDYuNjY2NjcgQzEyLjQzNzksNi42NjY2NyAxMy4zMzMzLDUuNzcxMjQgMTMuMzMzMyw0LjY2NjY3IEMxMy4zMzMzLDMuNTYyMSAxMi40Mzc5LDIuNjY2NjcgMTEuMzMzMywyLjY2NjY3IFogTTEwLjY2NjcsNC42NjY2NyBDMTAuNjY2Nyw0LjI5ODQ4IDEwLjk2NTEsNCAxMS4zMzMzLDQgQzExLjcwMTUsNCAxMiw0LjI5ODQ4IDEyLDQuNjY2NjcgQzEyLDUuMDM0ODYgMTEuNzAxNSw1LjMzMzMzIDExLjMzMzMsNS4zMzMzMyBDMTAuOTY1MSw1LjMzMzMzIDEwLjY2NjcsNS4wMzQ4NiAxMC42NjY3LDQuNjY2NjcgWiIgaWQ9IlNoYXBlIj48L3BhdGg+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0xMC42NjY3LDAgQzcuNzIxMTUsMCA1LjMzMzMzLDIuMzg3ODEgNS4zMzMzMyw1LjMzMzMzIEM1LjMzMzMzLDUuNzYxMTkgNS4zODM4NSw2LjE3Nzk4IDUuNDc5NDUsNi41Nzc3NSBMMC4xOTUyNjIsMTEuODYxOSBDMC4wNzAyMzc5LDExLjk4NyAwLDEyLjE1NjUgMCwxMi4zMzMzIEwwLDE1LjMzMzMgQzAsMTUuNzAxNSAwLjI5ODQ3NywxNiAwLjY2NjY2NywxNiBMMy4zMzMzMywxNiBDNC4wNjk3MSwxNiA0LjY2NjY3LDE1LjQwMyA0LjY2NjY3LDE0LjY2NjcgTDQuNjY2NjcsMTQgTDUuMzMzMzMsMTQgQzYuMDY5NzEsMTQgNi42NjY2NywxMy40MDMgNi42NjY2NywxMi42NjY3IEw2LjY2NjY3LDExLjMzMzMgTDgsMTEuMzMzMyBDOC4xNzY4MSwxMS4zMzMzIDguMzQ2MzgsMTEuMjYzMSA4LjQ3MTQxLDExLjEzODEgTDkuMTU5MDYsMTAuNDUwNCBDOS42Mzc3MiwxMC41OTEyIDEwLjE0MzksMTAuNjY2NyAxMC42NjY3LDEwLjY2NjcgQzEzLjYxMjIsMTAuNjY2NyAxNiw4LjI3ODg1IDE2LDUuMzMzMzMgQzE2LDIuMzg3ODEgMTMuNjEyMiwwIDEwLjY2NjcsMCBaIE02LjY2NjY3LDUuMzMzMzMgQzYuNjY2NjcsMy4xMjQxOSA4LjQ1NzUzLDEuMzMzMzMgMTAuNjY2NywxLjMzMzMzIEMxMi44NzU4LDEuMzMzMzMgMTQuNjY2NywzLjEyNDE5IDE0LjY2NjcsNS4zMzMzMyBDMTQuNjY2Nyw3LjU0MjQ3IDEyLjg3NTgsOS4zMzMzMyAxMC42NjY3LDkuMzMzMzMgQzEwLjE1NTgsOS4zMzMzMyA5LjY2ODg2LDkuMjM3OSA5LjIyMTUyLDkuMDY0NSBDOC45NzUyOCw4Ljk2OTA1IDguNjk1OTEsOS4wMjc5NSA4LjUwOTE2LDkuMjE0NjkgTDcuNzIzODYsMTAgTDYsMTAgQzUuNjMxODEsMTAgNS4zMzMzMywxMC4yOTg1IDUuMzMzMzMsMTAuNjY2NyBMNS4zMzMzMywxMi42NjY3IEw0LDEyLjY2NjcgQzMuNjMxODEsMTIuNjY2NyAzLjMzMzMzLDEyLjk2NTEgMy4zMzMzMywxMy4zMzMzIEwzLjMzMzMzLDE0LjY2NjcgTDEuMzMzMzMsMTQuNjY2NyBMMS4zMzMzMywxMi42MDk1IEw2LjY5Nzg3LDcuMjQ0OTQgQzYuODc1MDIsNy4wNjc3OSA2LjkzNzksNi44MDYyOSA2Ljg2MDY1LDYuNTY3OTggQzYuNzM0ODksNi4xNzk5NyA2LjY2NjY3LDUuNzY1MjcgNi42NjY2Nyw1LjMzMzMzIFoiIGlkPSJTaGFwZSI+PC9wYXRoPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+'); + background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik05LjYzNiA4LjY4MkM5LjYzNiA1LjU0NCAxMi4xOCAzIDE1LjMxOCAzIDE4LjQ1NiAzIDIxIDUuNTQ0IDIxIDguNjgyYzAgMy4xMzgtMi41NDQgNS42ODItNS42ODIgNS42ODItLjY5MiAwLTEuMzUzLS4xMjQtMS45NjQtLjM0OS0uMzcyLS4xMzctLjc5LS4wNDEtMS4wNjYuMjQ1bC0uNzEzLjc0SDEwYy0uNTUyIDAtMSAuNDQ4LTEgMXYySDdjLS41NTIgMC0xIC40NDgtMSAxdjJIM3YtMi44ODFsNi42NjgtNi42NjhjLjI2NS0uMjY2LjM2LS42NTguMjQ0LTEuMDE1LS4xNzktLjU1MS0uMjc2LTEuMTQtLjI3Ni0xLjc1NHpNMTUuMzE4IDFjLTQuMjQyIDAtNy42ODIgMy40NC03LjY4MiA3LjY4MiAwIC42MDcuMDcxIDEuMi4yMDUgMS43NjdsLTYuNTQ4IDYuNTQ4Yy0uMTg4LjE4OC0uMjkzLjQ0Mi0uMjkzLjcwOFYyMmMwIC4yNjUuMTA1LjUyLjI5My43MDcuMTg3LjE4OC40NDIuMjkzLjcwNy4yOTNoNGMxLjEwNSAwIDItLjg5NSAyLTJ2LTFoMWMxLjEwNSAwIDItLjg5NSAyLTJ2LTFoMWMuMjcyIDAgLjUzMi0uMTEuNzItLjMwNmwuNTc3LS42Yy42NDUuMTc2IDEuMzIzLjI3IDIuMDIxLjI3IDQuMjQzIDAgNy42ODItMy40NCA3LjY4Mi03LjY4MkMyMyA0LjQzOSAxOS41NiAxIDE1LjMxOCAxek0xNSA4YzAtLjU1Mi40NDgtMSAxLTFzMSAuNDQ4IDEgMS0uNDQ4IDEtMSAxLTEtLjQ0OC0xLTF6bTEtM2MtMS42NTcgMC0zIDEuMzQzLTMgM3MxLjM0MyAzIDMgMyAzLTEuMzQzIDMtMy0xLjM0My0zLTMtM3oiIGZpbGw9IiMwMDAiIGZpbGwtb3BhY2l0eT0iLjkiLz4KPC9zdmc+'); } .tooltip__button--data--creditCard::before { background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+CiAgICA8cGF0aCBkPSJNNSA5Yy0uNTUyIDAtMSAuNDQ4LTEgMXYyYzAgLjU1Mi40NDggMSAxIDFoM2MuNTUyIDAgMS0uNDQ4IDEtMXYtMmMwLS41NTItLjQ0OC0xLTEtMUg1eiIgZmlsbD0iIzAwMCIvPgogICAgPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xIDZjMC0yLjIxIDEuNzktNCA0LTRoMTRjMi4yMSAwIDQgMS43OSA0IDR2MTJjMCAyLjIxLTEuNzkgNC00IDRINWMtMi4yMSAwLTQtMS43OS00LTRWNnptNC0yYy0xLjEwNSAwLTIgLjg5NS0yIDJ2OWgxOFY2YzAtMS4xMDUtLjg5NS0yLTItMkg1em0wIDE2Yy0xLjEwNSAwLTItLjg5NS0yLTJoMThjMCAxLjEwNS0uODk1IDItMiAySDV6IiBmaWxsPSIjMDAwIi8+Cjwvc3ZnPgo='); } -.tooltip__button--data--creditCard:hover::before { - background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+CiAgICA8cGF0aCBkPSJNNSA5Yy0uNTUyIDAtMSAuNDQ4LTEgMXYyYzAgLjU1Mi40NDggMSAxIDFoM2MuNTUyIDAgMS0uNDQ4IDEtMXYtMmMwLS41NTItLjQ0OC0xLTEtMUg1eiIgZmlsbD0iI2ZmZiIvPgogICAgPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xIDZjMC0yLjIxIDEuNzktNCA0LTRoMTRjMi4yMSAwIDQgMS43OSA0IDR2MTJjMCAyLjIxLTEuNzkgNC00IDRINWMtMi4yMSAwLTQtMS43OS00LTRWNnptNC0yYy0xLjEwNSAwLTIgLjg5NS0yIDJ2OWgxOFY2YzAtMS4xMDUtLjg5NS0yLTItMkg1em0wIDE2Yy0xLjEwNSAwLTItLjg5NS0yLTJoMThjMCAxLjEwNS0uODk1IDItMiAySDV6IiBmaWxsPSIjZmZmIi8+Cjwvc3ZnPgo='); +.tooltip__button--data--identities::before { + background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+CiAgICA8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTEyIDIxYzIuMTQzIDAgNC4xMTEtLjc1IDUuNjU3LTItLjYyNi0uNTA2LTEuMzE4LS45MjctMi4wNi0xLjI1LTEuMS0uNDgtMi4yODUtLjczNS0zLjQ4Ni0uNzUtMS4yLS4wMTQtMi4zOTIuMjExLTMuNTA0LjY2NC0uODE3LjMzMy0xLjU4Ljc4My0yLjI2NCAxLjMzNiAxLjU0NiAxLjI1IDMuNTE0IDIgNS42NTcgMnptNC4zOTctNS4wODNjLjk2Ny40MjIgMS44NjYuOTggMi42NzIgMS42NTVDMjAuMjc5IDE2LjAzOSAyMSAxNC4xMDQgMjEgMTJjMC00Ljk3LTQuMDMtOS05LTlzLTkgNC4wMy05IDljMCAyLjEwNC43MjIgNC4wNCAxLjkzMiA1LjU3Mi44NzQtLjczNCAxLjg2LTEuMzI4IDIuOTIxLTEuNzYgMS4zNi0uNTU0IDIuODE2LS44MyA0LjI4My0uODExIDEuNDY3LjAxOCAyLjkxNi4zMyA0LjI2LjkxNnpNMTIgMjNjNi4wNzUgMCAxMS00LjkyNSAxMS0xMVMxOC4wNzUgMSAxMiAxIDEgNS45MjUgMSAxMnM0LjkyNSAxMSAxMSAxMXptMy0xM2MwIDEuNjU3LTEuMzQzIDMtMyAzcy0zLTEuMzQzLTMtMyAxLjM0My0zIDMtMyAzIDEuMzQzIDMgM3ptMiAwYzAgMi43NjEtMi4yMzkgNS01IDVzLTUtMi4yMzktNS01IDIuMjM5LTUgNS01IDUgMi4yMzkgNSA1eiIgZmlsbD0iIzAwMCIvPgo8L3N2Zz4='); +} + +hr { + display: block; + margin: 5px 10px; + border: none; /* reset the border */ + border-top: 1px solid rgba(0,0,0,.1); +} + +hr:first-child { + display: none; +} + +#privateAddress { + align-items: flex-start; +} +#personalAddress::before, +#privateAddress::before, +#personalAddress.currentFocus::before, +#personalAddress:hover::before, +#privateAddress.currentFocus::before, +#privateAddress:hover::before { + filter: none; + background-image: url('data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgNDQgNDQiIHdpZHRoPSIyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+PGxpbmVhckdyYWRpZW50IGlkPSJhIj48c3RvcCBvZmZzZXQ9Ii4wMSIgc3RvcC1jb2xvcj0iIzYxNzZiOSIvPjxzdG9wIG9mZnNldD0iLjY5IiBzdG9wLWNvbG9yPSIjMzk0YTlmIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImIiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMTMuOTI5NyIgeDI9IjE3LjA3MiIgeGxpbms6aHJlZj0iI2EiIHkxPSIxNi4zOTgiIHkyPSIxNi4zOTgiLz48bGluZWFyR3JhZGllbnQgaWQ9ImMiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMjMuODExNSIgeDI9IjI2LjY3NTIiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMTQuOTY3OSIgeTI9IjE0Ljk2NzkiLz48bWFzayBpZD0iZCIgaGVpZ2h0PSI0MCIgbWFza1VuaXRzPSJ1c2VyU3BhY2VPblVzZSIgd2lkdGg9IjQwIiB4PSIyIiB5PSIyIj48cGF0aCBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Im0yMi4wMDAzIDQxLjA2NjljMTAuNTMwMiAwIDE5LjA2NjYtOC41MzY0IDE5LjA2NjYtMTkuMDY2NiAwLTEwLjUzMDMtOC41MzY0LTE5LjA2NjcxLTE5LjA2NjYtMTkuMDY2NzEtMTAuNTMwMyAwLTE5LjA2NjcxIDguNTM2NDEtMTkuMDY2NzEgMTkuMDY2NzEgMCAxMC41MzAyIDguNTM2NDEgMTkuMDY2NiAxOS4wNjY3MSAxOS4wNjY2eiIgZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIi8+PC9tYXNrPjxwYXRoIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0ibTIyIDQ0YzEyLjE1MDMgMCAyMi05Ljg0OTcgMjItMjIgMC0xMi4xNTAyNi05Ljg0OTctMjItMjItMjItMTIuMTUwMjYgMC0yMiA5Ljg0OTc0LTIyIDIyIDAgMTIuMTUwMyA5Ljg0OTc0IDIyIDIyIDIyeiIgZmlsbD0iI2RlNTgzMyIgZmlsbC1ydWxlPSJldmVub2RkIi8+PGcgbWFzaz0idXJsKCNkKSI+PHBhdGggY2xpcC1ydWxlPSJldmVub2RkIiBkPSJtMjYuMDgxMyA0MS42Mzg2Yy0uOTIwMy0xLjc4OTMtMS44MDAzLTMuNDM1Ni0yLjM0NjYtNC41MjQ2LTEuNDUyLTIuOTA3Ny0yLjkxMTQtNy4wMDctMi4yNDc3LTkuNjUwNy4xMjEtLjQ4MDMtMS4zNjc3LTE3Ljc4Njk5LTIuNDItMTguMzQ0MzItMS4xNjk3LS42MjMzMy0zLjcxMDctMS40NDQ2Ny01LjAyNy0xLjY2NDY3LS45MTY3LS4xNDY2Ni0xLjEyNTcuMTEtMS41MTA3LjE2ODY3LjM2My4wMzY2NyAyLjA5Ljg4NzMzIDIuNDIzNy45MzUtLjMzMzcuMjI3MzMtMS4zMi0uMDA3MzMtMS45NTA3LjI3MTMzLS4zMTkuMTQ2NjctLjU1NzMuNjg5MzQtLjU1Ljk0NiAxLjc5NjctLjE4MzMzIDQuNjA1NC0uMDAzNjYgNi4yNy43MzMyOS0xLjMyMzYuMTUwNC0zLjMzMy4zMTktNC4xOTgzLjc3MzctMi41MDggMS4zMi0zLjYxNTMgNC40MTEtMi45NTUzIDguMTE0My42NTYzIDMuNjk2IDMuNTY0IDE3LjE3ODQgNC40OTE2IDIxLjY4MS45MjQgNC40OTkgMTEuNTUzNyAzLjU1NjcgMTAuMDE3NC41NjF6IiBmaWxsPSIjZDVkN2Q4IiBmaWxsLXJ1bGU9ImV2ZW5vZGQiLz48cGF0aCBkPSJtMjIuMjg2NSAyNi44NDM5Yy0uNjYgMi42NDM2Ljc5MiA2LjczOTMgMi4yNDc2IDkuNjUwNi40ODkxLjk3MjcgMS4yNDM4IDIuMzkyMSAyLjA1NTggMy45NjM3LTEuODk0LjQ2OTMtNi40ODk1IDEuMTI2NC05LjcxOTEgMC0uOTI0LTQuNDkxNy0zLjgzMTctMTcuOTc3Ny00LjQ5NTMtMjEuNjgxLS42Ni0zLjcwMzMgMC02LjM0NyAyLjUxNTMtNy42NjcuODYxNy0uNDU0NyAyLjA5MzctLjc4NDcgMy40MTM3LS45MzEzLTEuNjY0Ny0uNzQwNy0zLjYzNzQtMS4wMjY3LTUuNDQxNC0uODQzMzYtLjAwNzMtLjc2MjY3IDEuMzM4NC0uNzE4NjcgMS44NDQ0LTEuMDYzMzQtLjMzMzctLjA0NzY2LTEuMTYyNC0uNzk1NjYtMS41MjktLjgzMjMzIDIuMjg4My0uMzkyNDQgNC42NDIzLS4wMjEzOCA2LjY5OSAxLjA1NiAxLjA0ODYuNTYxIDEuNzg5MyAxLjE2MjMzIDIuMjQ3NiAxLjc5MzAzIDEuMTk1NC4yMjczIDIuMjUxNC42NiAyLjk0MDcgMS4zNDkzIDIuMTE5MyAyLjExNTcgNC4wMTEzIDYuOTUyIDMuMjE5MyA5LjczMTMtLjIyMzYuNzctLjczMzMgMS4zMzEtMS4zNzEzIDEuNzk2Ny0xLjIzOTMuOTAyLTEuMDE5My0xLjA0NS00LjEwMy45NzE3LS4zOTk3LjI2MDMtLjM5OTcgMi4yMjU2LS41MjQzIDIuNzA2eiIgZmlsbD0iI2ZmZiIvPjwvZz48ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCI+PHBhdGggZD0ibTE2LjY3MjQgMjAuMzU0Yy43Njc1IDAgMS4zODk2LS42MjIxIDEuMzg5Ni0xLjM4OTZzLS42MjIxLTEuMzg5Ny0xLjM4OTYtMS4zODk3LTEuMzg5Ny42MjIyLTEuMzg5NyAxLjM4OTcuNjIyMiAxLjM4OTYgMS4zODk3IDEuMzg5NnoiIGZpbGw9IiMyZDRmOGUiLz48cGF0aCBkPSJtMTcuMjkyNCAxOC44NjE3Yy4xOTg1IDAgLjM1OTQtLjE2MDguMzU5NC0uMzU5M3MtLjE2MDktLjM1OTMtLjM1OTQtLjM1OTNjLS4xOTg0IDAtLjM1OTMuMTYwOC0uMzU5My4zNTkzcy4xNjA5LjM1OTMuMzU5My4zNTkzeiIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Im0yNS45NTY4IDE5LjMzMTFjLjY1ODEgMCAxLjE5MTctLjUzMzUgMS4xOTE3LTEuMTkxNyAwLS42NTgxLS41MzM2LTEuMTkxNi0xLjE5MTctMS4xOTE2cy0xLjE5MTcuNTMzNS0xLjE5MTcgMS4xOTE2YzAgLjY1ODIuNTMzNiAxLjE5MTcgMS4xOTE3IDEuMTkxN3oiIGZpbGw9IiMyZDRmOGUiLz48cGF0aCBkPSJtMjYuNDg4MiAxOC4wNTExYy4xNzAxIDAgLjMwOC0uMTM3OS4zMDgtLjMwOHMtLjEzNzktLjMwOC0uMzA4LS4zMDgtLjMwOC4xMzc5LS4zMDguMzA4LjEzNzkuMzA4LjMwOC4zMDh6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTE3LjA3MiAxNC45NDJzLTEuMDQ4Ni0uNDc2Ni0yLjA2NDMuMTY1Yy0xLjAxNTcuNjM4LS45NzkgMS4yOTA3LS45NzkgMS4yOTA3cy0uNTM5LTEuMjAyNy44OTgzLTEuNzkzYzEuNDQxLS41ODY3IDIuMTQ1LjMzNzMgMi4xNDUuMzM3M3oiIGZpbGw9InVybCgjYikiLz48cGF0aCBkPSJtMjYuNjc1MiAxNC44NDY3cy0uNzUxNy0uNDI5LTEuMzM4My0uNDIxN2MtMS4xOTkuMDE0Ny0xLjUyNTQuNTQyNy0xLjUyNTQuNTQyN3MuMjAxNy0xLjI2MTQgMS43MzQ0LTEuMDA4NGMuNDk5Ny4wOTE0LjkyMjMuNDIzNCAxLjEyOTMuODg3NHoiIGZpbGw9InVybCgjYykiLz48cGF0aCBkPSJtMjAuOTI1OCAyNC4zMjFjLjEzOTMtLjg0MzMgMi4zMS0yLjQzMSAzLjg1LTIuNTMgMS41NC0uMDk1MyAyLjAxNjctLjA3MzMgMy4zLS4zODEzIDEuMjg3LS4zMDQzIDQuNTk4LTEuMTI5MyA1LjUxMS0xLjU1NDcuOTE2Ny0uNDIxNiA0LjgwMzMuMjA5IDIuMDY0MyAxLjczOC0xLjE4NDMuNjYzNy00LjM3OCAxLjg4MS02LjY2MjMgMi41NjMtMi4yODA3LjY4Mi0zLjY2My0uNjUyNi00LjQyMi40Njk0LS42MDEzLjg5MS0uMTIxIDIuMTEyIDIuNjAzMyAyLjM2NSAzLjY4MTQuMzQxIDcuMjA4Ny0xLjY1NzQgNy41OTc0LS41OTQuMzg4NiAxLjA2MzMtMy4xNjA3IDIuMzgzMy01LjMyNCAyLjQyNzMtMi4xNjM0LjA0MDMtNi41MTk0LTEuNDMtNy4xNzItMS44ODQ3LS42NTY0LS40NTEtMS41MjU0LTEuNTE0My0xLjM0NTctMi42MTh6IiBmaWxsPSIjZmRkMjBhIi8+PHBhdGggZD0ibTI4Ljg4MjUgMzEuODM4NmMtLjc3NzMtLjE3MjQtNC4zMTIgMi41MDA2LTQuMzEyIDIuNTAwNmguMDAzN2wtLjE2NSAyLjA1MzRzNC4wNDA2IDEuNjUzNiA0LjczIDEuMzk3Yy42ODkzLS4yNjQuNTE3LTUuNzc1LS4yNTY3LTUuOTUxem0tMTEuNTQ2MyAxLjAzNGMuMDg0My0xLjExODQgNS4yNTQzIDEuNjQyNiA1LjI1NDMgMS42NDI2bC4wMDM3LS4wMDM2LjI1NjYgMi4xNTZzLTQuMzA4MyAyLjU4MTMtNC45MTMzIDIuMjM2NmMtLjYwMTMtLjM0NDYtLjY4OTMtNC45MDk2LS42MDEzLTYuMDMxNnoiIGZpbGw9IiM2NWJjNDYiLz48cGF0aCBkPSJtMjEuMzQgMzQuODA0OWMwIDEuODA3Ny0uMjYwNCAyLjU4NS41MTMzIDIuNzU3NC43NzczLjE3MjMgMi4yNDAzIDAgMi43NjEtLjM0NDcuNTEzMy0uMzQ0Ny4wODQzLTIuNjY5My0uMDg4LTMuMTAycy0zLjE5LS4wODgtMy4xOS42ODkzeiIgZmlsbD0iIzQzYTI0NCIvPjxwYXRoIGQ9Im0yMS42NzAxIDM0LjQwNTFjMCAxLjgwNzYtLjI2MDQgMi41ODEzLjUxMzMgMi43NTM2Ljc3MzcuMTc2IDIuMjM2NyAwIDIuNzU3My0uMzQ0Ni41MTctLjM0NDcuMDg4LTIuNjY5NC0uMDg0My0zLjEwMi0uMTcyMy0uNDMyNy0zLjE5LS4wODQ0LTMuMTkuNjg5M3oiIGZpbGw9IiM2NWJjNDYiLz48cGF0aCBkPSJtMjIuMDAwMiA0MC40NDgxYzEwLjE4ODUgMCAxOC40NDc5LTguMjU5NCAxOC40NDc5LTE4LjQ0NzlzLTguMjU5NC0xOC40NDc5NS0xOC40NDc5LTE4LjQ0Nzk1LTE4LjQ0Nzk1IDguMjU5NDUtMTguNDQ3OTUgMTguNDQ3OTUgOC4yNTk0NSAxOC40NDc5IDE4LjQ0Nzk1IDE4LjQ0Nzl6bTAgMS43MTg3YzExLjEzNzcgMCAyMC4xNjY2LTkuMDI4OSAyMC4xNjY2LTIwLjE2NjYgMC0xMS4xMzc4LTkuMDI4OS0yMC4xNjY3LTIwLjE2NjYtMjAuMTY2Ny0xMS4xMzc4IDAtMjAuMTY2NyA5LjAyODktMjAuMTY2NyAyMC4xNjY3IDAgMTEuMTM3NyA5LjAyODkgMjAuMTY2NiAyMC4xNjY3IDIwLjE2NjZ6IiBmaWxsPSIjZmZmIi8+PC9nPjwvc3ZnPg=='); } /* Email tooltip specific */ @@ -144,6 +199,7 @@ justify-content: center; align-items: flex-start; font-size: 14px; + padding: 4px 8px; } .tooltip__button--email__primary-text { font-weight: bold; diff --git a/dist/autofill.js b/dist/autofill.js index 6fb4f78b0..fd8592bf1 100644 --- a/dist/autofill.js +++ b/dist/autofill.js @@ -1,1634 +1,7088 @@ (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i 1 && !unprotectedDomain) { + const partialDomain = domainParts.join('.'); + unprotectedDomain = featureList.filter(domain => domain.domain === partialDomain).length > 0; + domainParts.shift(); + } -function _classApplyDescriptorGet(receiver, descriptor) { if (descriptor.get) { return descriptor.get.call(receiver); } return descriptor.value; } + return unprotectedDomain; +} -const EmailAutofill = require('./UI/EmailAutofill'); +function processConfig(data, userList, preferences) { + const topLevelUrl = getTopLevelURL(); + const allowlisted = userList.filter(domain => domain === topLevelUrl.host).length > 0; + const enabledFeatures = Object.keys(data.features).filter(featureName => { + const feature = data.features[featureName]; + return feature.state === 'enabled' && !isUnprotectedDomain(topLevelUrl, feature.exceptions); + }); + const isBroken = isUnprotectedDomain(topLevelUrl, data.unprotectedTemporary); + preferences.site = { + domain: topLevelUrl.hostname, + isBroken, + allowlisted, + enabledFeatures + }; // TODO + + preferences.cookie = {}; + return preferences; +} -const DataAutofill = require('./UI/DataAutofill'); +},{}],2:[function(require,module,exports){ +"use strict"; const { - isApp, - notifyWebApp, - isDDGApp, - isAndroid, - isDDGDomain, - sendAndWaitForAnswer, - setValue, - formatAddress, - isMobileApp -} = require('./autofill-utils'); + Password +} = require('./lib/apple.password'); const { - wkSend, - wkSendAndWait -} = require('./appleDeviceUtils/appleDeviceUtils'); + ParserError +} = require('./lib/rules-parser'); const { - scanForInputs, - forms -} = require('./scanForInputs.js'); - -const getInputConfig = require('./Form/inputTypeConfig'); - -const SIGN_IN_MSG = { - signMeIn: true -}; + constants +} = require('./lib/constants'); +/** + * @typedef {{ + * domain?: string | null | undefined; + * input?: string | null | undefined; + * rules?: RulesFormat | null | undefined; + * onError?: ((error: unknown) => void) | null | undefined; + * }} GenerateOptions + */ -const attachTooltip = function (form, input) { - if (isMobileApp) { - form.activeInput = input; - this.getAlias().then(alias => { - if (alias) form.autofillEmail(alias);else form.activeInput.focus(); - }); - } else { - if (form.tooltip) return; - form.activeInput = input; - const inputType = getInputConfig(input).type; - form.tooltip = inputType === 'emailNew' ? new EmailAutofill(input, form, this) : new DataAutofill(input, form, this); - form.intObs.observe(input); - window.addEventListener('pointerdown', form.removeTooltip, { - capture: true - }); - window.addEventListener('input', form.removeTooltip, { - once: true - }); - } -}; +/** + * Generate a random password based on the following attempts + * + * 1) using `options.input` if provided -> falling back to default ruleset + * 2) using `options.domain` if provided -> falling back to default ruleset + * 3) using default ruleset + * + * Note: This API is designed to never throw - if you want to observe errors + * during development, you can provide an `onError` callback + * + * @param {GenerateOptions} [options] + */ -let attempts = 0; -var _addresses = new WeakMap(); +function generate() { + let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; -var _data = new WeakMap(); + try { + if (typeof (options === null || options === void 0 ? void 0 : options.input) === 'string') { + return Password.generateOrThrow(options.input); + } -class InterfacePrototype { - constructor() { - _addresses.set(this, { - writable: true, - value: {} - }); + if (typeof (options === null || options === void 0 ? void 0 : options.domain) === 'string') { + if (options !== null && options !== void 0 && options.rules) { + const rules = _selectPasswordRules(options.domain, options.rules); - _data.set(this, { - writable: true, - value: { - credentials: [], - creditCards: [], - identities: [] + if (rules) { + return Password.generateOrThrow(rules); + } } - }); - } - - get hasLocalAddresses() { - var _classPrivateFieldGet2, _classPrivateFieldGet3; - - return !!((_classPrivateFieldGet2 = _classPrivateFieldGet(this, _addresses)) !== null && _classPrivateFieldGet2 !== void 0 && _classPrivateFieldGet2.privateAddress && (_classPrivateFieldGet3 = _classPrivateFieldGet(this, _addresses)) !== null && _classPrivateFieldGet3 !== void 0 && _classPrivateFieldGet3.personalAddress); - } + } + } catch (e) { + // if an 'onError' callback was provided, forward all errors + if (options !== null && options !== void 0 && options.onError && typeof (options === null || options === void 0 ? void 0 : options.onError) === 'function') { + options.onError(e); + } else { + // otherwise, only console.error unknown errors (which could be implementation bugs) + const isKnownError = e instanceof ParserError || e instanceof HostnameInputError; - getLocalAddresses() { - return _classPrivateFieldGet(this, _addresses); - } + if (!isKnownError) { + console.error(e); + } + } + } // At this point, we have to trust the generation will not throw + // as it is NOT using any user/page-provided data - storeLocalAddresses(addresses) { - _classPrivateFieldSet(this, _addresses, addresses); - } - /** @type { PMData } */ + return Password.generateDefault(); +} // An extension type to differentiate between known errors - /** - * Stores init data coming from the device - * @param { PMData } data - */ - storeLocalData(data) { - data.credentials.forEach(cred => delete cred.password); - data.creditCards.forEach(cc => delete cc.cardNumber && delete cc.cardSecurityCode); - _classPrivateFieldSet(this, _data, data); - } +class HostnameInputError extends Error {} +/** + * @typedef {Record} RulesFormat + */ - get hasLocalCredentials() { - return _classPrivateFieldGet(this, _data).credentials.length > 0; - } +/** + * @private + * @param {string} inputHostname + * @param {RulesFormat} rules + * @returns {string | undefined} + * @throws {HostnameInputError} + */ - getLocalCredentials() { - return _classPrivateFieldGet(this, _data).credentials.map(cred => delete cred.password && cred); - } - get hasLocalIdentities() { - return _classPrivateFieldGet(this, _data).identities.length > 0; - } +function _selectPasswordRules(inputHostname, rules) { + const hostname = _safeHostname(inputHostname); // direct match - getLocalIdentities() { - return _classPrivateFieldGet(this, _data).identities; - } - get hasLocalCreditCards() { - return _classPrivateFieldGet(this, _data).creditCards.length > 0; - } + if (rules[hostname]) { + return rules[hostname]['password-rules']; + } // otherwise, start chopping off subdomains and re-joining to compare - getLocalCreditCards() { - return _classPrivateFieldGet(this, _data).creditCards; - } - init() { - this.attachTooltip = attachTooltip.bind(this); + const pieces = hostname.split('.'); - const start = () => { - this.addDeviceListeners(); - this.setupAutofill(); - }; + while (pieces.length > 1) { + pieces.shift(); + const joined = pieces.join('.'); - if (document.readyState === 'complete') { - start(); - } else { - window.addEventListener('load', start); + if (rules[joined]) { + return rules[joined]['password-rules']; } } - setupAutofill() {} - - getAddresses() {} + return undefined; +} +/** + * @private + * @param {string} inputHostname; + * @throws {HostnameInputError} + * @returns {string} + */ - refreshAlias() {} - async trySigningIn() { - if (isDDGDomain()) { - if (attempts < 10) { - attempts++; - const data = await sendAndWaitForAnswer(SIGN_IN_MSG, 'addUserData'); // This call doesn't send a response, so we can't know if it succeeded +function _safeHostname(inputHostname) { + if (inputHostname.startsWith('http:') || inputHostname.startsWith('https:')) { + throw new HostnameInputError('invalid input, you can only provide a hostname but you gave a scheme'); + } - this.storeUserData(data); - this.setupAutofill({ - shouldLog: true - }); - } else { - console.warn('max attempts reached, bailing'); - } - } + if (inputHostname.includes(':')) { + throw new HostnameInputError('invalid input, you can only provide a hostname but you gave a :port'); } - storeUserData() {} + try { + const asUrl = new URL('https://' + inputHostname); + return asUrl.hostname; + } catch (e) { + throw new HostnameInputError("could not instantiate a URL from that hostname ".concat(inputHostname)); + } +} - addDeviceListeners() {} +module.exports.generate = generate; +module.exports._selectPasswordRules = _selectPasswordRules; +module.exports.HostnameInputError = HostnameInputError; +module.exports.ParserError = ParserError; +module.exports.constants = constants; - addLogoutListener() {} +},{"./lib/apple.password":3,"./lib/constants":4,"./lib/rules-parser":5}],3:[function(require,module,exports){ +"use strict"; - attachTooltip() {} +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - isDeviceSignedIn() {} +/* + * + * NOTE: + * + * This file was created with inspiration from https://developer.apple.com/password-rules + * + * * The changes made by DuckDuckGo employees are: + * + * 1) removed all logic relating to 'more typeable passwords' + * 2) reduced the number of password styles from 4 to only the 1 which suits our needs + * 2) added JSDoc comments (for Typescript checking) + * + */ +const parser = require('./rules-parser'); - getAlias() {} // PM endpoints +const { + constants +} = require('./constants'); +/** + * @typedef {{ + * PasswordAllowedCharacters?: string, + * PasswordRequiredCharacters?: string[], + * PasswordRepeatedCharacterLimit?: number, + * PasswordConsecutiveCharacterLimit?: number, + * PasswordMinLength?: number, + * PasswordMaxLength?: number, + * }} Requirements + */ +/** + * @typedef {{ + * NumberOfRequiredRandomCharacters: number, + * PasswordAllowedCharacters: string, + * RequiredCharacterSets: string[] + * }} PasswordParameters + */ - storeCredentials() {} - getAccounts() {} +const defaults = Object.freeze({ + SCAN_SET_ORDER: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\\\"'<>,.?/ ]", + defaultUnambiguousCharacters: 'abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789', + defaultPasswordLength: constants.MIN_LENGTH, + defaultPasswordRules: constants.DEFAULT_PASSWORD_RULES, + defaultRequiredCharacterSets: ['abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', '0123456789'], - getAutofillCredentials() {} + /** + * @type {typeof window.crypto.getRandomValues | typeof import("crypto").randomFillSync | null} + */ + getRandomValues: null +}); +/** + * This is added here to ensure: + * + * 1) `getRandomValues` is called with the correct prototype chain + * 2) `window` is not accessed when in a node environment + * 3) `bind` is not called in a hot code path + * + * @type {{ getRandomValues: typeof window.crypto.getRandomValues }} + */ - openManagePasswords() {} +const safeGlobals = {}; +if (typeof window !== 'undefined') { + safeGlobals.getRandomValues = window.crypto.getRandomValues.bind(window.crypto); } -class ExtensionInterface extends InterfacePrototype { +class Password { + /** + * @type {typeof defaults} + */ + + /** + * @param {Partial} [options] + */ constructor() { - super(); + let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - this.isDeviceSignedIn = () => this.hasLocalAddresses; + _defineProperty(this, "options", void 0); - this.setupAutofill = ({ - shouldLog - } = { - shouldLog: false - }) => { - this.getAddresses().then(addresses => { - if (this.hasLocalAddresses) { - notifyWebApp({ - deviceSignedIn: { - value: true, - shouldLog - } - }); - scanForInputs(this); - } else { - this.trySigningIn(); - } - }); + this.options = { ...defaults, + ...options }; + return this; + } + /** + * This is here to provide external access to un-modified defaults + * in case they are needed for tests/verifications + * @type {typeof defaults} + */ - this.getAddresses = () => new Promise(resolve => chrome.runtime.sendMessage({ - getAddresses: true - }, data => { - this.storeLocalAddresses(data); - return resolve(data); - })); - - this.refreshAlias = () => chrome.runtime.sendMessage({ - refreshAlias: true - }, addresses => this.storeLocalAddresses(addresses)); - - this.trySigningIn = () => { - if (isDDGDomain()) { - sendAndWaitForAnswer(SIGN_IN_MSG, 'addUserData').then(data => this.storeUserData(data)); - } - }; - this.storeUserData = data => chrome.runtime.sendMessage(data); + /** + * Generates a password from the given input. + * + * Note: This method will throw an error if parsing fails - use with caution + * + * @example + * + * ```javascript + * const password = Password.generateOrThrow("minlength: 20") + * ``` + * @public + * @param {string} inputString + * @param {Partial} [options] + * @throws {ParserError|Error} + * @returns {string} + */ + static generateOrThrow(inputString) { + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + return new Password(options).parse(inputString).generate(); + } + /** + * Generates a password using the default ruleset. + * + * @example + * + * ```javascript + * const password = Password.generateDefault() + * ``` + * + * @public + * @param {Partial} [options] + * @returns {string} + */ - this.addDeviceListeners = () => { - // Add contextual menu listeners - let activeEl = null; - document.addEventListener('contextmenu', e => { - activeEl = e.target; - }); - chrome.runtime.onMessage.addListener((message, sender) => { - if (sender.id !== chrome.runtime.id) return; - switch (message.type) { - case 'ddgUserReady': - this.setupAutofill({ - shouldLog: true - }); - break; + static generateDefault() { + let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + return new Password(options).parse(Password.defaults.defaultPasswordRules).generate(); + } + /** + * Convert a ruleset into it's internally-used component pieces. + * + * @param {string} inputString + * @throws {parser.ParserError|Error} + * @returns {{ + * requirements: Requirements; + * parameters: PasswordParameters; + * rules: parser.Rule[], + * get entropy(): number; + * generate: () => string; + * }} + */ - case 'contextualAutofill': - setValue(activeEl, formatAddress(message.alias)); - activeEl.classList.add('ddg-autofilled'); - this.refreshAlias(); // If the user changes the alias, remove the decoration - activeEl.addEventListener('input', e => e.target.classList.remove('ddg-autofilled'), { - once: true - }); - break; + parse(inputString) { + const rules = parser.parsePasswordRules(inputString); - default: - break; - } - }); - }; + const requirements = this._requirementsFromRules(rules); - this.addLogoutListener = handler => { - // Cleanup on logout events - chrome.runtime.onMessage.addListener((message, sender) => { - if (sender.id === chrome.runtime.id && message.type === 'logout') { - handler(); - } - }); - }; - } + if (!requirements) throw new Error('could not generate requirements for ' + JSON.stringify(inputString)); -} + const parameters = this._passwordGenerationParametersDictionary(requirements); -class AndroidInterface extends InterfacePrototype { - constructor() { - super(); + return { + requirements, + parameters, + rules, - this.getAlias = () => sendAndWaitForAnswer(() => window.EmailInterface.showTooltip(), 'getAliasResponse').then(({ - alias - }) => alias); + get entropy() { + return Math.log2(parameters.PasswordAllowedCharacters.length ** parameters.NumberOfRequiredRandomCharacters); + }, - this.isDeviceSignedIn = () => { - // isDeviceSignedIn is only available on DDG domains... - if (isDDGDomain()) return window.EmailInterface.isSignedIn() === 'true'; // ...on other domains we assume true because the script wouldn't exist otherwise + generate: () => { + const password = this._generatedPasswordMatchingRequirements(requirements, parameters); + /** + * The following is unreachable because if user input was incorrect then + * the parsing phase would throw. The following lines is to satisfy Typescript + */ - return true; - }; - this.setupAutofill = ({ - shouldLog - } = { - shouldLog: false - }) => { - if (this.isDeviceSignedIn()) { - notifyWebApp({ - deviceSignedIn: { - value: true, - shouldLog - } - }); - scanForInputs(this); - } else { - this.trySigningIn(); + if (password === '') throw new Error('unreachable'); + return password; } }; - - this.storeUserData = ({ - addUserData: { - token, - userName, - cohort - } - }) => window.EmailInterface.storeCredentials(token, userName, cohort); } + /** + * Given an array of `Rule's`, convert into `Requirements` + * + * @param {parser.Rule[]} passwordRules + * @returns {Requirements | null} + */ -} -class AppleDeviceInterface extends InterfacePrototype { - constructor() { - super(); + _requirementsFromRules(passwordRules) { + /** @type {Requirements} */ + const requirements = {}; - this.setupAutofill = async ({ - shouldLog - } = { - shouldLog: false - }) => { - if (isDDGDomain()) { - // Tell the web app whether we're in the app - notifyWebApp({ - isApp - }); - } + for (let rule of passwordRules) { + if (rule.name === parser.RuleName.ALLOWED) { + console.assert(!('PasswordAllowedCharacters' in requirements)); - if (isApp) { - await this.getAutofillInitData(); - } + const chars = this._charactersFromCharactersClasses(rule.value); - const signedIn = await this._checkDeviceSignedIn(); + const scanSet = this._canonicalizedScanSetFromCharacters(chars); - if (signedIn) { - if (isApp) { - await this.getAddresses(); + if (scanSet) { + requirements.PasswordAllowedCharacters = scanSet; + } + } else if (rule.name === parser.RuleName.MAX_CONSECUTIVE) { + console.assert(!('PasswordRepeatedCharacterLimit' in requirements)); + requirements.PasswordRepeatedCharacterLimit = rule.value; + } else if (rule.name === parser.RuleName.REQUIRED) { + let requiredCharacters = requirements.PasswordRequiredCharacters; + + if (!requiredCharacters) { + requiredCharacters = requirements.PasswordRequiredCharacters = []; } - notifyWebApp({ - deviceSignedIn: { - value: true, - shouldLog - } - }); - forms.forEach(form => form.redecorateAllInputs()); - } else { - this.trySigningIn(); + requiredCharacters.push(this._canonicalizedScanSetFromCharacters(this._charactersFromCharactersClasses(rule.value))); + } else if (rule.name === parser.RuleName.MIN_LENGTH) { + requirements.PasswordMinLength = rule.value; + } else if (rule.name === parser.RuleName.MAX_LENGTH) { + requirements.PasswordMaxLength = rule.value; } + } // Only include an allowed rule matching SCAN_SET_ORDER (all characters) when a required rule is also present. - scanForInputs(this); - }; - this.getAddresses = async () => { - if (!isApp) return this.getAlias(); - const { - addresses - } = await wkSendAndWait('emailHandlerGetAddresses'); - this.storeLocalAddresses(addresses); - return addresses; - }; + if (requirements.PasswordAllowedCharacters === this.options.SCAN_SET_ORDER && !requirements.PasswordRequiredCharacters) { + delete requirements.PasswordAllowedCharacters; + } // Fix up PasswordRequiredCharacters, if needed. - this.getAlias = async () => { - const { - alias - } = await wkSendAndWait('emailHandlerGetAlias', { - requiresUserPermission: !isApp, - shouldConsumeAliasIfProvided: !isApp - }); - return formatAddress(alias); - }; - this.refreshAlias = () => wkSend('emailHandlerRefreshAlias'); + if (requirements.PasswordRequiredCharacters && requirements.PasswordRequiredCharacters.length === 1 && requirements.PasswordRequiredCharacters[0] === this.options.SCAN_SET_ORDER) { + delete requirements.PasswordRequiredCharacters; + } + + return Object.keys(requirements).length ? requirements : null; + } + /** + * @param {number} range + * @returns {number} + */ + + + _randomNumberWithUniformDistribution(range) { + const getRandomValues = this.options.getRandomValues || safeGlobals.getRandomValues; // Based on the algorithm described in https://pthree.org/2018/06/13/why-the-multiply-and-floor-rng-method-is-biased/ + + const max = Math.floor(2 ** 32 / range) * range; + let x; + + do { + x = getRandomValues(new Uint32Array(1))[0]; + } while (x >= max); + + return x % range; + } + /** + * @param {number} numberOfRequiredRandomCharacters + * @param {string} allowedCharacters + */ + + + _classicPassword(numberOfRequiredRandomCharacters, allowedCharacters) { + const length = allowedCharacters.length; + const randomCharArray = Array(numberOfRequiredRandomCharacters); + + for (let i = 0; i < numberOfRequiredRandomCharacters; i++) { + const index = this._randomNumberWithUniformDistribution(length); + + randomCharArray[i] = allowedCharacters[index]; + } + + return randomCharArray.join(''); + } + /** + * @param {string} password + * @param {number} consecutiveCharLimit + * @returns {boolean} + */ + + + _passwordHasNotExceededConsecutiveCharLimit(password, consecutiveCharLimit) { + let longestConsecutiveCharLength = 1; + let firstConsecutiveCharIndex = 0; // Both "123" or "abc" and "321" or "cba" are considered consecutive. + + let isSequenceAscending; + + for (let i = 1; i < password.length; i++) { + const currCharCode = password.charCodeAt(i); + const prevCharCode = password.charCodeAt(i - 1); + + if (isSequenceAscending) { + // If `isSequenceAscending` is defined, then we know that we are in the middle of an existing + // pattern. Check if the pattern continues based on whether the previous pattern was + // ascending or descending. + if (isSequenceAscending.valueOf() && currCharCode === prevCharCode + 1 || !isSequenceAscending.valueOf() && currCharCode === prevCharCode - 1) { + continue; + } // Take into account the case when the sequence transitions from descending + // to ascending. + + + if (currCharCode === prevCharCode + 1) { + firstConsecutiveCharIndex = i - 1; + isSequenceAscending = Boolean(true); + continue; + } // Take into account the case when the sequence transitions from ascending + // to descending. + + + if (currCharCode === prevCharCode - 1) { + firstConsecutiveCharIndex = i - 1; + isSequenceAscending = Boolean(false); + continue; + } + + isSequenceAscending = null; + } else if (currCharCode === prevCharCode + 1) { + isSequenceAscending = Boolean(true); + continue; + } else if (currCharCode === prevCharCode - 1) { + isSequenceAscending = Boolean(false); + continue; + } + + const currConsecutiveCharLength = i - firstConsecutiveCharIndex; + + if (currConsecutiveCharLength > longestConsecutiveCharLength) { + longestConsecutiveCharLength = currConsecutiveCharLength; + } + + firstConsecutiveCharIndex = i; + } + + if (isSequenceAscending) { + const currConsecutiveCharLength = password.length - firstConsecutiveCharIndex; + + if (currConsecutiveCharLength > longestConsecutiveCharLength) { + longestConsecutiveCharLength = currConsecutiveCharLength; + } + } + + return longestConsecutiveCharLength <= consecutiveCharLimit; + } + /** + * @param {string} password + * @param {number} repeatedCharLimit + * @returns {boolean} + */ + + + _passwordHasNotExceededRepeatedCharLimit(password, repeatedCharLimit) { + let longestRepeatedCharLength = 1; + let lastRepeatedChar = password.charAt(0); + let lastRepeatedCharIndex = 0; + + for (let i = 1; i < password.length; i++) { + const currChar = password.charAt(i); + + if (currChar === lastRepeatedChar) { + continue; + } + + const currRepeatedCharLength = i - lastRepeatedCharIndex; + + if (currRepeatedCharLength > longestRepeatedCharLength) { + longestRepeatedCharLength = currRepeatedCharLength; + } + + lastRepeatedChar = currChar; + lastRepeatedCharIndex = i; + } + + return longestRepeatedCharLength <= repeatedCharLimit; + } + /** + * @param {string} password + * @param {string[]} requiredCharacterSets + * @returns {boolean} + */ + + + _passwordContainsRequiredCharacters(password, requiredCharacterSets) { + const requiredCharacterSetsLength = requiredCharacterSets.length; + const passwordLength = password.length; + + for (let i = 0; i < requiredCharacterSetsLength; i++) { + const requiredCharacterSet = requiredCharacterSets[i]; + let hasRequiredChar = false; + + for (let j = 0; j < passwordLength; j++) { + const char = password.charAt(j); + + if (requiredCharacterSet.indexOf(char) !== -1) { + hasRequiredChar = true; + break; + } + } + + if (!hasRequiredChar) { + return false; + } + } + + return true; + } + /** + * @param {string} string1 + * @param {string} string2 + * @returns {boolean} + */ + + + _stringsHaveAtLeastOneCommonCharacter(string1, string2) { + const string2Length = string2.length; + + for (let i = 0; i < string2Length; i++) { + const char = string2.charAt(i); + + if (string1.indexOf(char) !== -1) { + return true; + } + } + + return false; + } + /** + * @param {Requirements} requirements + * @returns {PasswordParameters} + */ + + + _passwordGenerationParametersDictionary(requirements) { + let minPasswordLength = requirements.PasswordMinLength; + const maxPasswordLength = requirements.PasswordMaxLength; // @ts-ignore + + if (minPasswordLength > maxPasswordLength) { + // Resetting invalid value of min length to zero means "ignore min length parameter in password generation". + minPasswordLength = 0; + } + + const requiredCharacterArray = requirements.PasswordRequiredCharacters; + let allowedCharacters = requirements.PasswordAllowedCharacters; + let requiredCharacterSets = this.options.defaultRequiredCharacterSets; + + if (requiredCharacterArray) { + const mutatedRequiredCharacterSets = []; + const requiredCharacterArrayLength = requiredCharacterArray.length; + + for (let i = 0; i < requiredCharacterArrayLength; i++) { + const requiredCharacters = requiredCharacterArray[i]; + + if (allowedCharacters && this._stringsHaveAtLeastOneCommonCharacter(requiredCharacters, allowedCharacters)) { + mutatedRequiredCharacterSets.push(requiredCharacters); + } + } + + requiredCharacterSets = mutatedRequiredCharacterSets; + } // If requirements allow, we will generateOrThrow the password in default format: "xxx-xxx-xxx-xxx". + + + let numberOfRequiredRandomCharacters = this.options.defaultPasswordLength; + + if (minPasswordLength && minPasswordLength > numberOfRequiredRandomCharacters) { + numberOfRequiredRandomCharacters = minPasswordLength; + } + + if (maxPasswordLength && maxPasswordLength < numberOfRequiredRandomCharacters) { + numberOfRequiredRandomCharacters = maxPasswordLength; + } + + if (!allowedCharacters) { + allowedCharacters = this.options.defaultUnambiguousCharacters; + } // In default password format, we use dashes only as separators, not as symbols you can encounter at a random position. + + + if (!requiredCharacterSets) { + requiredCharacterSets = this.options.defaultRequiredCharacterSets; + } // If we have more requirements of the type "need a character from set" than the length of the password we want to generateOrThrow, then + // we will never be able to meet these requirements, and we'll end up in an infinite loop generating passwords. To avoid this, + // reset required character sets if the requirements are impossible to meet. + + + if (requiredCharacterSets.length > numberOfRequiredRandomCharacters) { + requiredCharacterSets = []; + } // Do not require any character sets that do not contain allowed characters. + + + const requiredCharacterSetsLength = requiredCharacterSets.length; + const mutatedRequiredCharacterSets = []; + const allowedCharactersLength = allowedCharacters.length; + + for (let i = 0; i < requiredCharacterSetsLength; i++) { + const requiredCharacterSet = requiredCharacterSets[i]; + let requiredCharacterSetContainsAllowedCharacters = false; + + for (let j = 0; j < allowedCharactersLength; j++) { + const character = allowedCharacters.charAt(j); + + if (requiredCharacterSet.indexOf(character) !== -1) { + requiredCharacterSetContainsAllowedCharacters = true; + break; + } + } + + if (requiredCharacterSetContainsAllowedCharacters) { + mutatedRequiredCharacterSets.push(requiredCharacterSet); + } + } + + requiredCharacterSets = mutatedRequiredCharacterSets; + return { + NumberOfRequiredRandomCharacters: numberOfRequiredRandomCharacters, + PasswordAllowedCharacters: allowedCharacters, + RequiredCharacterSets: requiredCharacterSets + }; + } + /** + * @param {Requirements | null} requirements + * @param {PasswordParameters} [parameters] + * @returns {string} + */ + + + _generatedPasswordMatchingRequirements(requirements, parameters) { + requirements = requirements || {}; + parameters = parameters || this._passwordGenerationParametersDictionary(requirements); + const numberOfRequiredRandomCharacters = parameters.NumberOfRequiredRandomCharacters; + const repeatedCharLimit = requirements.PasswordRepeatedCharacterLimit; + const allowedCharacters = parameters.PasswordAllowedCharacters; + const shouldCheckRepeatedCharRequirement = !!repeatedCharLimit; + + while (true) { + const password = this._classicPassword(numberOfRequiredRandomCharacters, allowedCharacters); + + if (!this._passwordContainsRequiredCharacters(password, parameters.RequiredCharacterSets)) { + continue; + } + + if (shouldCheckRepeatedCharRequirement) { + if (repeatedCharLimit !== undefined && repeatedCharLimit >= 1 && !this._passwordHasNotExceededRepeatedCharLimit(password, repeatedCharLimit)) { + continue; + } + } + + const consecutiveCharLimit = requirements.PasswordConsecutiveCharacterLimit; + + if (consecutiveCharLimit && consecutiveCharLimit >= 1) { + if (!this._passwordHasNotExceededConsecutiveCharLimit(password, consecutiveCharLimit)) { + continue; + } + } + + return password || ''; + } + } + /** + * @param {parser.CustomCharacterClass | parser.NamedCharacterClass} characterClass + * @returns {string[]} + */ + + + _scanSetFromCharacterClass(characterClass) { + if (characterClass instanceof parser.CustomCharacterClass) { + return characterClass.characters; + } + + console.assert(characterClass instanceof parser.NamedCharacterClass); + + switch (characterClass.name) { + case parser.Identifier.ASCII_PRINTABLE: + case parser.Identifier.UNICODE: + return this.options.SCAN_SET_ORDER.split(''); + + case parser.Identifier.DIGIT: + return this.options.SCAN_SET_ORDER.substring(this.options.SCAN_SET_ORDER.indexOf('0'), this.options.SCAN_SET_ORDER.indexOf('9') + 1).split(''); + + case parser.Identifier.LOWER: + return this.options.SCAN_SET_ORDER.substring(this.options.SCAN_SET_ORDER.indexOf('a'), this.options.SCAN_SET_ORDER.indexOf('z') + 1).split(''); + + case parser.Identifier.SPECIAL: + return this.options.SCAN_SET_ORDER.substring(this.options.SCAN_SET_ORDER.indexOf('-'), this.options.SCAN_SET_ORDER.indexOf(']') + 1).split(''); + + case parser.Identifier.UPPER: + return this.options.SCAN_SET_ORDER.substring(this.options.SCAN_SET_ORDER.indexOf('A'), this.options.SCAN_SET_ORDER.indexOf('Z') + 1).split(''); + } + + console.assert(false, parser.SHOULD_NOT_BE_REACHED); + return []; + } + /** + * @param {(parser.CustomCharacterClass | parser.NamedCharacterClass)[]} characterClasses + */ + + + _charactersFromCharactersClasses(characterClasses) { + const output = []; + + for (let characterClass of characterClasses) { + output.push(...this._scanSetFromCharacterClass(characterClass)); + } + + return output; + } + /** + * @param {string[]} characters + * @returns {string} + */ + + + _canonicalizedScanSetFromCharacters(characters) { + if (!characters.length) { + return ''; + } + + let shadowCharacters = Array.prototype.slice.call(characters); + shadowCharacters.sort((a, b) => this.options.SCAN_SET_ORDER.indexOf(a) - this.options.SCAN_SET_ORDER.indexOf(b)); + let uniqueCharacters = [shadowCharacters[0]]; + + for (let i = 1, length = shadowCharacters.length; i < length; ++i) { + if (shadowCharacters[i] === shadowCharacters[i - 1]) { + continue; + } + + uniqueCharacters.push(shadowCharacters[i]); + } + + return uniqueCharacters.join(''); + } + +} + +_defineProperty(Password, "defaults", defaults); + +module.exports.Password = Password; + +},{"./constants":4,"./rules-parser":5}],4:[function(require,module,exports){ +"use strict"; + +const MIN_LENGTH = 20; +const MAX_LENGTH = 30; +const DEFAULT_PASSWORD_RULES = "minlength: ".concat(MIN_LENGTH, "; maxlength: ").concat(MAX_LENGTH, ";"); +const constants = { + MIN_LENGTH, + MAX_LENGTH, + DEFAULT_PASSWORD_RULES +}; +module.exports.constants = constants; + +},{}],5:[function(require,module,exports){ +"use strict"; + +// Copyright (c) 2019 - 2020 Apple Inc. Licensed under MIT License. + +/* + * + * NOTE: + * + * This file was taken as intended from https://github.com/apple/password-manager-resources. + * + * The only additions from DuckDuckGo employees are + * + * 1) exporting some identifiers + * 2) adding some JSDoc comments + * 3) making this parser throw when it cannot produce any rules + * ^ the default implementation still returns a base-line ruleset, which we didn't want. + * + */ +const Identifier = { + ASCII_PRINTABLE: 'ascii-printable', + DIGIT: 'digit', + LOWER: 'lower', + SPECIAL: 'special', + UNICODE: 'unicode', + UPPER: 'upper' +}; +const RuleName = { + ALLOWED: 'allowed', + MAX_CONSECUTIVE: 'max-consecutive', + REQUIRED: 'required', + MIN_LENGTH: 'minlength', + MAX_LENGTH: 'maxlength' +}; +const CHARACTER_CLASS_START_SENTINEL = '['; +const CHARACTER_CLASS_END_SENTINEL = ']'; +const PROPERTY_VALUE_SEPARATOR = ','; +const PROPERTY_SEPARATOR = ';'; +const PROPERTY_VALUE_START_SENTINEL = ':'; +const SPACE_CODE_POINT = ' '.codePointAt(0); +const SHOULD_NOT_BE_REACHED = 'Should not be reached'; + +class Rule { + constructor(name, value) { + this._name = name; + this.value = value; + } + + get name() { + return this._name; + } + + toString() { + return JSON.stringify(this); + } + +} + +; + +class NamedCharacterClass { + constructor(name) { + console.assert(_isValidRequiredOrAllowedPropertyValueIdentifier(name)); + this._name = name; + } + + get name() { + return this._name.toLowerCase(); + } + + toString() { + return this._name; + } + + toHTMLString() { + return this._name; + } + +} + +; + +class ParserError extends Error {} + +; + +class CustomCharacterClass { + constructor(characters) { + console.assert(characters instanceof Array); + this._characters = characters; + } + + get characters() { + return this._characters; + } + + toString() { + return "[".concat(this._characters.join(''), "]"); + } + + toHTMLString() { + return "[".concat(this._characters.join('').replace('"', '"'), "]"); + } + +} + +; // MARK: Lexer functions + +function _isIdentifierCharacter(c) { + console.assert(c.length === 1); // eslint-disable-next-line no-mixed-operators + + return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c === '-'; +} + +function _isASCIIDigit(c) { + console.assert(c.length === 1); + return c >= '0' && c <= '9'; +} + +function _isASCIIPrintableCharacter(c) { + console.assert(c.length === 1); + return c >= ' ' && c <= '~'; +} + +function _isASCIIWhitespace(c) { + console.assert(c.length === 1); + return c === ' ' || c === '\f' || c === '\n' || c === '\r' || c === '\t'; +} // MARK: ASCII printable character bit set and canonicalization functions + + +function _bitSetIndexForCharacter(c) { + console.assert(c.length === 1); // @ts-ignore + + return c.codePointAt(0) - SPACE_CODE_POINT; +} + +function _characterAtBitSetIndex(index) { + return String.fromCodePoint(index + SPACE_CODE_POINT); +} + +function _markBitsForNamedCharacterClass(bitSet, namedCharacterClass) { + console.assert(bitSet instanceof Array); + console.assert(namedCharacterClass.name !== Identifier.UNICODE); + console.assert(namedCharacterClass.name !== Identifier.ASCII_PRINTABLE); + + if (namedCharacterClass.name === Identifier.UPPER) { + bitSet.fill(true, _bitSetIndexForCharacter('A'), _bitSetIndexForCharacter('Z') + 1); + } else if (namedCharacterClass.name === Identifier.LOWER) { + bitSet.fill(true, _bitSetIndexForCharacter('a'), _bitSetIndexForCharacter('z') + 1); + } else if (namedCharacterClass.name === Identifier.DIGIT) { + bitSet.fill(true, _bitSetIndexForCharacter('0'), _bitSetIndexForCharacter('9') + 1); + } else if (namedCharacterClass.name === Identifier.SPECIAL) { + bitSet.fill(true, _bitSetIndexForCharacter(' '), _bitSetIndexForCharacter('/') + 1); + bitSet.fill(true, _bitSetIndexForCharacter(':'), _bitSetIndexForCharacter('@') + 1); + bitSet.fill(true, _bitSetIndexForCharacter('['), _bitSetIndexForCharacter('`') + 1); + bitSet.fill(true, _bitSetIndexForCharacter('{'), _bitSetIndexForCharacter('~') + 1); + } else { + console.assert(false, SHOULD_NOT_BE_REACHED, namedCharacterClass); + } +} + +function _markBitsForCustomCharacterClass(bitSet, customCharacterClass) { + for (let character of customCharacterClass.characters) { + bitSet[_bitSetIndexForCharacter(character)] = true; + } +} + +function _canonicalizedPropertyValues(propertyValues, keepCustomCharacterClassFormatCompliant) { + // @ts-ignore + let asciiPrintableBitSet = new Array('~'.codePointAt(0) - ' '.codePointAt(0) + 1); + + for (let propertyValue of propertyValues) { + if (propertyValue instanceof NamedCharacterClass) { + if (propertyValue.name === Identifier.UNICODE) { + return [new NamedCharacterClass(Identifier.UNICODE)]; + } + + if (propertyValue.name === Identifier.ASCII_PRINTABLE) { + return [new NamedCharacterClass(Identifier.ASCII_PRINTABLE)]; + } + + _markBitsForNamedCharacterClass(asciiPrintableBitSet, propertyValue); + } else if (propertyValue instanceof CustomCharacterClass) { + _markBitsForCustomCharacterClass(asciiPrintableBitSet, propertyValue); + } + } + + let charactersSeen = []; + + function checkRange(start, end) { + let temp = []; + + for (let i = _bitSetIndexForCharacter(start); i <= _bitSetIndexForCharacter(end); ++i) { + if (asciiPrintableBitSet[i]) { + temp.push(_characterAtBitSetIndex(i)); + } + } + + let result = temp.length === _bitSetIndexForCharacter(end) - _bitSetIndexForCharacter(start) + 1; + + if (!result) { + charactersSeen = charactersSeen.concat(temp); + } + + return result; + } + + let hasAllUpper = checkRange('A', 'Z'); + let hasAllLower = checkRange('a', 'z'); + let hasAllDigits = checkRange('0', '9'); // Check for special characters, accounting for characters that are given special treatment (i.e. '-' and ']') + + let hasAllSpecial = false; + let hasDash = false; + let hasRightSquareBracket = false; + let temp = []; + + for (let i = _bitSetIndexForCharacter(' '); i <= _bitSetIndexForCharacter('/'); ++i) { + if (!asciiPrintableBitSet[i]) { + continue; + } + + let character = _characterAtBitSetIndex(i); + + if (keepCustomCharacterClassFormatCompliant && character === '-') { + hasDash = true; + } else { + temp.push(character); + } + } + + for (let i = _bitSetIndexForCharacter(':'); i <= _bitSetIndexForCharacter('@'); ++i) { + if (asciiPrintableBitSet[i]) { + temp.push(_characterAtBitSetIndex(i)); + } + } + + for (let i = _bitSetIndexForCharacter('['); i <= _bitSetIndexForCharacter('`'); ++i) { + if (!asciiPrintableBitSet[i]) { + continue; + } + + let character = _characterAtBitSetIndex(i); + + if (keepCustomCharacterClassFormatCompliant && character === ']') { + hasRightSquareBracket = true; + } else { + temp.push(character); + } + } + + for (let i = _bitSetIndexForCharacter('{'); i <= _bitSetIndexForCharacter('~'); ++i) { + if (asciiPrintableBitSet[i]) { + temp.push(_characterAtBitSetIndex(i)); + } + } + + if (hasDash) { + temp.unshift('-'); + } + + if (hasRightSquareBracket) { + temp.push(']'); + } + + let numberOfSpecialCharacters = _bitSetIndexForCharacter('/') - _bitSetIndexForCharacter(' ') + 1 + (_bitSetIndexForCharacter('@') - _bitSetIndexForCharacter(':') + 1) + (_bitSetIndexForCharacter('`') - _bitSetIndexForCharacter('[') + 1) + (_bitSetIndexForCharacter('~') - _bitSetIndexForCharacter('{') + 1); + hasAllSpecial = temp.length === numberOfSpecialCharacters; + + if (!hasAllSpecial) { + charactersSeen = charactersSeen.concat(temp); + } + + let result = []; + + if (hasAllUpper && hasAllLower && hasAllDigits && hasAllSpecial) { + return [new NamedCharacterClass(Identifier.ASCII_PRINTABLE)]; + } + + if (hasAllUpper) { + result.push(new NamedCharacterClass(Identifier.UPPER)); + } + + if (hasAllLower) { + result.push(new NamedCharacterClass(Identifier.LOWER)); + } + + if (hasAllDigits) { + result.push(new NamedCharacterClass(Identifier.DIGIT)); + } + + if (hasAllSpecial) { + result.push(new NamedCharacterClass(Identifier.SPECIAL)); + } + + if (charactersSeen.length) { + result.push(new CustomCharacterClass(charactersSeen)); + } + + return result; +} // MARK: Parser functions + + +function _indexOfNonWhitespaceCharacter(input) { + let position = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + console.assert(position >= 0); + console.assert(position <= input.length); + let length = input.length; + + while (position < length && _isASCIIWhitespace(input[position])) { + ++position; + } + + return position; +} + +function _parseIdentifier(input, position) { + console.assert(position >= 0); + console.assert(position < input.length); + console.assert(_isIdentifierCharacter(input[position])); + let length = input.length; + let seenIdentifiers = []; + + do { + let c = input[position]; + + if (!_isIdentifierCharacter(c)) { + break; + } + + seenIdentifiers.push(c); + ++position; + } while (position < length); + + return [seenIdentifiers.join(''), position]; +} + +function _isValidRequiredOrAllowedPropertyValueIdentifier(identifier) { + return identifier && Object.values(Identifier).includes(identifier.toLowerCase()); +} + +function _parseCustomCharacterClass(input, position) { + console.assert(position >= 0); + console.assert(position < input.length); + console.assert(input[position] === CHARACTER_CLASS_START_SENTINEL); + let length = input.length; + ++position; + + if (position >= length) { + // console.error('Found end-of-line instead of character class character') + return [null, position]; + } + + let initialPosition = position; + let result = []; + + do { + let c = input[position]; + + if (!_isASCIIPrintableCharacter(c)) { + ++position; + continue; + } + + if (c === '-' && position - initialPosition > 0) { + // FIXME: Should this be an error? + console.warn("Ignoring '-'; a '-' may only appear as the first character in a character class"); + ++position; + continue; + } + + result.push(c); + ++position; + + if (c === CHARACTER_CLASS_END_SENTINEL) { + break; + } + } while (position < length); + + if (position < length && input[position] !== CHARACTER_CLASS_END_SENTINEL) { + // Fix up result; we over consumed. + result.pop(); + return [result, position]; + } else if (position === length && input[position - 1] === CHARACTER_CLASS_END_SENTINEL) { + // Fix up result; we over consumed. + result.pop(); + return [result, position]; + } + + if (position < length && input[position] === CHARACTER_CLASS_END_SENTINEL) { + return [result, position + 1]; + } // console.error('Found end-of-line instead of end of character class') + + + return [null, position]; +} + +function _parsePasswordRequiredOrAllowedPropertyValue(input, position) { + console.assert(position >= 0); + console.assert(position < input.length); + let length = input.length; + let propertyValues = []; + + while (true) { + if (_isIdentifierCharacter(input[position])) { + let identifierStartPosition = position; // eslint-disable-next-line no-redeclare + + var [propertyValue, position] = _parseIdentifier(input, position); + + if (!_isValidRequiredOrAllowedPropertyValueIdentifier(propertyValue)) { + // console.error('Unrecognized property value identifier: ' + propertyValue) + return [null, identifierStartPosition]; + } + + propertyValues.push(new NamedCharacterClass(propertyValue)); + } else if (input[position] === CHARACTER_CLASS_START_SENTINEL) { + // eslint-disable-next-line no-redeclare + var [propertyValue, position] = _parseCustomCharacterClass(input, position); + + if (propertyValue && propertyValue.length) { + propertyValues.push(new CustomCharacterClass(propertyValue)); + } + } else { + // console.error('Failed to find start of property value: ' + input.substr(position)) + return [null, position]; + } + + position = _indexOfNonWhitespaceCharacter(input, position); + + if (position >= length || input[position] === PROPERTY_SEPARATOR) { + break; + } + + if (input[position] === PROPERTY_VALUE_SEPARATOR) { + position = _indexOfNonWhitespaceCharacter(input, position + 1); + + if (position >= length) { + // console.error('Found end-of-line instead of start of next property value') + return [null, position]; + } + + continue; + } // console.error('Failed to find start of next property or property value: ' + input.substr(position)) + + + return [null, position]; + } + + return [propertyValues, position]; +} +/** + * @param input + * @param position + * @returns {[Rule|null, number, string|undefined]} + * @private + */ + + +function _parsePasswordRule(input, position) { + console.assert(position >= 0); + console.assert(position < input.length); + console.assert(_isIdentifierCharacter(input[position])); + let length = input.length; + var mayBeIdentifierStartPosition = position; // eslint-disable-next-line no-redeclare + + var [identifier, position] = _parseIdentifier(input, position); + + if (!Object.values(RuleName).includes(identifier)) { + // console.error('Unrecognized property name: ' + identifier) + return [null, mayBeIdentifierStartPosition, undefined]; + } + + if (position >= length) { + // console.error('Found end-of-line instead of start of property value') + return [null, position, undefined]; + } + + if (input[position] !== PROPERTY_VALUE_START_SENTINEL) { + // console.error('Failed to find start of property value: ' + input.substr(position)) + return [null, position, undefined]; + } + + let property = { + name: identifier, + value: null + }; + position = _indexOfNonWhitespaceCharacter(input, position + 1); // Empty value + + if (position >= length || input[position] === PROPERTY_SEPARATOR) { + return [new Rule(property.name, property.value), position, undefined]; + } + + switch (identifier) { + case RuleName.ALLOWED: + case RuleName.REQUIRED: + { + // eslint-disable-next-line no-redeclare + var [propertyValue, position] = _parsePasswordRequiredOrAllowedPropertyValue(input, position); + + if (propertyValue) { + property.value = propertyValue; + } + + return [new Rule(property.name, property.value), position, undefined]; + } + + case RuleName.MAX_CONSECUTIVE: + { + // eslint-disable-next-line no-redeclare + var [propertyValue, position] = _parseMaxConsecutivePropertyValue(input, position); + + if (propertyValue) { + property.value = propertyValue; + } + + return [new Rule(property.name, property.value), position, undefined]; + } + + case RuleName.MIN_LENGTH: + case RuleName.MAX_LENGTH: + { + // eslint-disable-next-line no-redeclare + var [propertyValue, position] = _parseMinLengthMaxLengthPropertyValue(input, position); + + if (propertyValue) { + property.value = propertyValue; + } + + return [new Rule(property.name, property.value), position, undefined]; + } + } + + console.assert(false, SHOULD_NOT_BE_REACHED); + return [null, -1, undefined]; +} + +function _parseMinLengthMaxLengthPropertyValue(input, position) { + return _parseInteger(input, position); +} + +function _parseMaxConsecutivePropertyValue(input, position) { + return _parseInteger(input, position); +} + +function _parseInteger(input, position) { + console.assert(position >= 0); + console.assert(position < input.length); + + if (!_isASCIIDigit(input[position])) { + // console.error('Failed to parse value of type integer; not a number: ' + input.substr(position)) + return [null, position]; + } + + let length = input.length; // let initialPosition = position + + let result = 0; + + do { + result = 10 * result + parseInt(input[position], 10); + ++position; + } while (position < length && input[position] !== PROPERTY_SEPARATOR && _isASCIIDigit(input[position])); + + if (position >= length || input[position] === PROPERTY_SEPARATOR) { + return [result, position]; + } // console.error('Failed to parse value of type integer; not a number: ' + input.substr(initialPosition)) + + + return [null, position]; +} +/** + * @param input + * @returns {[Rule[]|null, string|undefined]} + * @private + */ + + +function _parsePasswordRulesInternal(input) { + let parsedProperties = []; + let length = input.length; + + var position = _indexOfNonWhitespaceCharacter(input); + + while (position < length) { + if (!_isIdentifierCharacter(input[position])) { + // console.warn('Failed to find start of property: ' + input.substr(position)) + return [parsedProperties, undefined]; + } // eslint-disable-next-line no-redeclare + + + var [parsedProperty, position, message] = _parsePasswordRule(input, position); + + if (parsedProperty && parsedProperty.value) { + parsedProperties.push(parsedProperty); + } + + position = _indexOfNonWhitespaceCharacter(input, position); + + if (position >= length) { + break; + } + + if (input[position] === PROPERTY_SEPARATOR) { + position = _indexOfNonWhitespaceCharacter(input, position + 1); + + if (position >= length) { + return [parsedProperties, undefined]; + } + + continue; + } // console.error('Failed to find start of next property: ' + input.substr(position)) + + + return [null, message || 'Failed to find start of next property: ' + input.substr(position)]; + } + + return [parsedProperties, undefined]; +} +/** + * @param {string} input + * @param {boolean} [formatRulesForMinifiedVersion] + * @returns {Rule[]} + */ + + +function parsePasswordRules(input, formatRulesForMinifiedVersion) { + let [passwordRules, maybeMessage] = _parsePasswordRulesInternal(input); + + if (!passwordRules) { + throw new ParserError(maybeMessage); + } + + if (passwordRules.length === 0) { + throw new ParserError('No valid rules were provided'); + } // When formatting rules for minified version, we should keep the formatted rules + // as similar to the input as possible. Avoid copying required rules to allowed rules. + + + let suppressCopyingRequiredToAllowed = formatRulesForMinifiedVersion; + let requiredRules = []; + let newAllowedValues = []; + let minimumMaximumConsecutiveCharacters = null; + let maximumMinLength = 0; + let minimumMaxLength = null; + + for (let rule of passwordRules) { + switch (rule.name) { + case RuleName.MAX_CONSECUTIVE: + minimumMaximumConsecutiveCharacters = minimumMaximumConsecutiveCharacters ? Math.min(rule.value, minimumMaximumConsecutiveCharacters) : rule.value; + break; + + case RuleName.MIN_LENGTH: + maximumMinLength = Math.max(rule.value, maximumMinLength); + break; + + case RuleName.MAX_LENGTH: + minimumMaxLength = minimumMaxLength ? Math.min(rule.value, minimumMaxLength) : rule.value; + break; + + case RuleName.REQUIRED: + rule.value = _canonicalizedPropertyValues(rule.value, formatRulesForMinifiedVersion); + requiredRules.push(rule); + + if (!suppressCopyingRequiredToAllowed) { + newAllowedValues = newAllowedValues.concat(rule.value); + } + + break; + + case RuleName.ALLOWED: + newAllowedValues = newAllowedValues.concat(rule.value); + break; + } + } + + let newPasswordRules = []; + + if (maximumMinLength > 0) { + newPasswordRules.push(new Rule(RuleName.MIN_LENGTH, maximumMinLength)); + } + + if (minimumMaxLength !== null) { + newPasswordRules.push(new Rule(RuleName.MAX_LENGTH, minimumMaxLength)); + } + + if (minimumMaximumConsecutiveCharacters !== null) { + newPasswordRules.push(new Rule(RuleName.MAX_CONSECUTIVE, minimumMaximumConsecutiveCharacters)); + } + + let sortedRequiredRules = requiredRules.sort(function (a, b) { + const namedCharacterClassOrder = [Identifier.LOWER, Identifier.UPPER, Identifier.DIGIT, Identifier.SPECIAL, Identifier.ASCII_PRINTABLE, Identifier.UNICODE]; + let aIsJustOneNamedCharacterClass = a.value.length === 1 && a.value[0] instanceof NamedCharacterClass; + let bIsJustOneNamedCharacterClass = b.value.length === 1 && b.value[0] instanceof NamedCharacterClass; + + if (aIsJustOneNamedCharacterClass && !bIsJustOneNamedCharacterClass) { + return -1; + } + + if (!aIsJustOneNamedCharacterClass && bIsJustOneNamedCharacterClass) { + return 1; + } + + if (aIsJustOneNamedCharacterClass && bIsJustOneNamedCharacterClass) { + let aIndex = namedCharacterClassOrder.indexOf(a.value[0].name); + let bIndex = namedCharacterClassOrder.indexOf(b.value[0].name); + return aIndex - bIndex; + } + + return 0; + }); + newPasswordRules = newPasswordRules.concat(sortedRequiredRules); + newAllowedValues = _canonicalizedPropertyValues(newAllowedValues, suppressCopyingRequiredToAllowed); + + if (!suppressCopyingRequiredToAllowed && !newAllowedValues.length) { + newAllowedValues = [new NamedCharacterClass(Identifier.ASCII_PRINTABLE)]; + } + + if (newAllowedValues.length) { + newPasswordRules.push(new Rule(RuleName.ALLOWED, newAllowedValues)); + } + + return newPasswordRules; +} + +module.exports.parsePasswordRules = parsePasswordRules; +module.exports.Identifier = Identifier; +module.exports.RuleName = RuleName; +module.exports.SHOULD_NOT_BE_REACHED = SHOULD_NOT_BE_REACHED; +module.exports.Rule = Rule; +module.exports.ParserError = ParserError; +module.exports.NamedCharacterClass = NamedCharacterClass; +module.exports.CustomCharacterClass = CustomCharacterClass; + +},{}],6:[function(require,module,exports){ +module.exports={ + "163.com": { + "password-rules": "minlength: 6; maxlength: 16;" + }, + "1800flowers.com": { + "password-rules": "minlength: 6; required: lower, upper; required: digit;" + }, + "access.service.gov.uk": { + "password-rules": "minlength: 10; required: lower; required: upper; required: digit; required: special;" + }, + "admiral.com": { + "password-rules": "minlength: 8; required: digit; required: [- !\"#$&'()*+,.:;<=>?@[^_`{|}~]]; allowed: lower, upper;" + }, + "ae.com": { + "password-rules": "minlength: 8; maxlength: 25; required: lower; required: upper; required: digit;" + }, + "aetna.com": { + "password-rules": "minlength: 8; maxlength: 20; max-consecutive: 2; required: upper; required: digit; allowed: lower, [-_&#@];" + }, + "airasia.com": { + "password-rules": "minlength: 8; maxlength: 15; required: lower; required: upper; required: digit;" + }, + "ajisushionline.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; allowed: [ !#$%&*?@];" + }, + "aliexpress.com": { + "password-rules": "minlength: 6; maxlength: 20; allowed: lower, upper, digit;" + }, + "alliantcreditunion.com": { + "password-rules": "minlength: 8; maxlength: 20; max-consecutive: 3; required: lower, upper; required: digit; allowed: [!#$*];" + }, + "allianz.com.br": { + "password-rules": "minlength: 4; maxlength: 4;" + }, + "americanexpress.com": { + "password-rules": "minlength: 8; maxlength: 20; max-consecutive: 4; required: lower, upper; required: digit; allowed: [%&_?#=];" + }, + "anatel.gov.br": { + "password-rules": "minlength: 6; maxlength: 15; allowed: lower, upper, digit;" + }, + "ancestry.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: [-!\"#$%&'()*+,./:;<=>?@[^_`{|}~]];" + }, + "angieslist.com": { + "password-rules": "minlength: 6; maxlength: 15;" + }, + "anthem.com": { + "password-rules": "minlength: 8; maxlength: 20; max-consecutive: 3; required: lower, upper; required: digit; allowed: [!$*?@|];" + }, + "app.digio.in": { + "password-rules": "minlength: 8; maxlength: 15;" + }, + "app.parkmobile.io": { + "password-rules": "minlength: 8; maxlength: 25; required: lower; required: upper; required: digit; required: [!@#$%^&];" + }, + "apple.com": { + "password-rules": "minlength: 8; maxlength: 63; required: lower; required: upper; required: digit; allowed: ascii-printable;" + }, + "areariservata.bancaetica.it": { + "password-rules": "minlength: 8; maxlength: 10; required: lower; required: upper; required: digit; required: [!#&*+/=@_];" + }, + "artscyclery.com": { + "password-rules": "minlength: 6; maxlength: 19;" + }, + "astonmartinf1.com": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; allowed: special;" + }, + "autify.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: [!\"#$%&'()*+,./:;<=>?@[^_`{|}~]];" + }, + "axa.de": { + "password-rules": "minlength: 8; maxlength: 65; required: lower; required: upper; required: digit; allowed: [-!\"§$%&/()=?;:_+*'#];" + }, + "baidu.com": { + "password-rules": "minlength: 6; maxlength: 14;" + }, + "bancochile.cl": { + "password-rules": "minlength: 8; maxlength: 8; required: lower; required: upper; required: digit;" + }, + "bankofamerica.com": { + "password-rules": "minlength: 8; maxlength: 20; max-consecutive: 3; required: lower; required: upper; required: digit; allowed: [-@#*()+={}/?~;,._];" + }, + "battle.net": { + "password-rules": "minlength: 8; maxlength: 16; required: lower, upper; allowed: digit, special;" + }, + "bcassessment.ca": { + "password-rules": "minlength: 8; maxlength: 14;" + }, + "belkin.com": { + "password-rules": "minlength: 8; required: lower, upper; required: digit; required: [$!@~_,%&];" + }, + "benefitslogin.discoverybenefits.com": { + "password-rules": "minlength: 10; required: upper; required: digit; required: [!#$%&*?@]; allowed: lower;" + }, + "benjerry.com": { + "password-rules": "required: upper; required: upper; required: digit; required: digit; required: special; required: special; allowed: lower;" + }, + "bestbuy.com": { + "password-rules": "minlength: 20; required: lower; required: upper; required: digit; required: special;" + }, + "bhphotovideo.com": { + "password-rules": "maxlength: 15;" + }, + "billerweb.com": { + "password-rules": "minlength: 8; max-consecutive: 2; required: digit; required: upper,lower;" + }, + "biovea.com": { + "password-rules": "maxlength: 19;" + }, + "bitly.com": { + "password-rules": "minlength: 6; required: lower; required: upper; required: digit; required: [`!@#$%^&*()+~{}'\";:<>?]];" + }, + "bloomingdales.com": { + "password-rules": "minlength: 7; maxlength: 16; required: lower, upper; required: digit; required: [`!@#$%^&*()+~{}'\";:<>?]];" + }, + "bluesguitarunleashed.com": { + "password-rules": "allowed: lower, upper, digit, [!$#@];" + }, + "bochk.com": { + "password-rules": "minlength: 8; maxlength: 12; max-consecutive: 3; required: lower; required: upper; required: digit; allowed: [#$%&()*+,.:;<=>?@_];" + }, + "box.com": { + "password-rules": "minlength: 6; maxlength: 20; required: lower; required: upper; required: digit; required: digit;" + }, + "brighthorizons.com": { + "password-rules": "minlength: 8; maxlength: 16;" + }, + "callofduty.com": { + "password-rules": "minlength: 8; maxlength: 20; max-consecutive: 2; required: lower, upper; required: digit;" + }, + "capitalone.com": { + "password-rules": "minlength: 8; maxlength: 32; required: lower, upper; required: digit; allowed: [-_./\\@$*&!#];" + }, + "cardbenefitservices.com": { + "password-rules": "minlength: 7; maxlength: 100; required: lower, upper; required: digit;" + }, + "cb2.com": { + "password-rules": "minlength: 7; maxlength: 18; required: lower, upper; required: digit;" + }, + "cecredentialtrust.com": { + "password-rules": "minlength: 12; required: lower; required: upper; required: digit; required: [!#$%&*@^];" + }, + "chase.com": { + "password-rules": "minlength: 8; maxlength: 32; max-consecutive: 2; required: lower, upper; required: digit; required: [!#$%+/=@~];" + }, + "cigna.co.uk": { + "password-rules": "minlength: 8; maxlength: 12; required: lower; required: upper; required: digit;" + }, + "cigna.com": { + "password-rules": "minlength: 8; maxlength: 12; required: upper; required: digit; required: [_!.&@]; allowed: lower;" + }, + "citi.com": { + "password-rules": "minlength: 6; maxlength: 50; max-consecutive: 2; required: lower, upper; required: digit; allowed: [_!@$]" + }, + "claimlookup.com": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; required: [@#$%^&+=!];" + }, + "claro.com.br": { + "password-rules": "minlength: 8; required: lower; allowed: upper, digit, [-!@#$%&*_+=<>];" + }, + "clien.net": { + "password-rules": "minlength: 5; required: lower, upper; required: digit;" + }, + "collectivehealth.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit;" + }, + "comcastpaymentcenter.com": { + "password-rules": "minlength: 8; maxlength: 20; max-consecutive: 2;required: lower, upper; required: digit;" + }, + "comed.com": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; allowed: [-~!@#$%^&*_+=`|(){}[:;\"'<>,.?/\\]];" + }, + "commerzbank.de": { + "password-rules": "minlength: 5; maxlength: 8; required: lower, upper; required: digit;" + }, + "consorsbank.de": { + "password-rules": "minlength: 5; maxlength: 5; required: lower, upper, digit;" + }, + "consorsfinanz.de": { + "password-rules": "minlength: 6; maxlength: 15; allowed: lower, upper, digit, [-.];" + }, + "costco.com": { + "password-rules": "minlength: 8; maxlength: 20; required: lower, upper; allowed: digit, [-!#$%&'()*+/:;=?@[^_`{|}~]];" + }, + "coursera.com": { + "password-rules": "minlength: 8; maxlength: 72;" + }, + "cox.com": { + "password-rules": "minlength: 8; maxlength: 24; required: digit; required: upper,lower; allowed: [!#$%()*@^];" + }, + "crateandbarrel.com": { + "password-rules": "minlength: 9; maxlength: 64; required: lower; required: upper; required: digit; required: [!\"#$%&()*,.:<>?@^_{|}];" + }, + "cvs.com": { + "password-rules": "minlength: 8; maxlength: 25; required: lower, upper; required: digit; allowed: [!@#$%^&*()];" + }, + "dailymail.co.uk": { + "password-rules": "minlength: 5; maxlength: 15;" + }, + "dan.org": { + "password-rules": "minlength: 8; maxlength: 25; required: lower; required: upper; required: digit; required: [!@$%^&*];" + }, + "danawa.com": { + "password-rules": "minlength: 8; maxlength: 21; required: lower, upper; required: digit; required: [!@$%^&*];" + }, + "darty.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit;" + }, + "dbs.com.hk": { + "password-rules": "minlength: 8; maxlength: 30; required: lower; required: upper; required: digit;" + }, + "decluttr.com": { + "password-rules": "minlength: 8; maxlength: 45; required: lower; required: upper; required: digit;" + }, + "delta.com": { + "password-rules": "minlength: 8; maxlength: 20; required: lower; required: upper; required: digit;" + }, + "deutsche-bank.de": { + "password-rules": "minlength: 5; maxlength: 5; required: lower, upper, digit;" + }, + "devstore.cn": { + "password-rules": "minlength: 6; maxlength: 12;" + }, + "dickssportinggoods.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: [!#$%&*?@^];" + }, + "dkb.de": { + "password-rules": "minlength: 8; maxlength: 38; required: lower, upper; required: digit; allowed: [-äüöÄÜÖß!$%&/()=?+#,.:];" + }, + "dmm.com": { + "password-rules": "minlength: 4; maxlength: 16; required: lower; required: upper; required: digit;" + }, + "dowjones.com": { + "password-rules": "maxlength: 15;" + }, + "ea.com": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; allowed: special;" + }, + "easycoop.com": { + "password-rules": "minlength: 8; required: upper; required: special; allowed: lower, digit;" + }, + "easyjet.com": { + "password-rules": "minlength: 6; maxlength: 20; required: lower; required: upper; required: digit; required: [-];" + }, + "ebrap.org": { + "password-rules": "minlength: 15; required: lower; required: lower; required: upper; required: upper; required: digit; required: digit; required: [-!@#$%^&*()_+|~=`{}[:\";'?,./.]]; required: [-!@#$%^&*()_+|~=`{}[:\";'?,./.]];" + }, + "ecompanystore.com": { + "password-rules": "minlength: 8; maxlength: 16; max-consecutive: 2; required: lower; required: upper; required: digit; required: [#$%*+.=@^_];" + }, + "eddservices.edd.ca.gov": { + "password-rules": "minlength: 8; maxlength: 12; required: lower; required: upper; required: digit; required: [!@#$%^&*()];" + }, + "empower-retirement.com": { + "password-rules": "minlength: 8; maxlength: 16;" + }, + "epicgames.com": { + "password-rules": "minlength: 7; required: lower; required: upper; required: digit; required: [-!\"#$%&'()*+,./:;<=>?@[^_`{|}~]];" + }, + "epicmix.com": { + "password-rules": "minlength: 8; maxlength: 16;" + }, + "equifax.com": { + "password-rules": "minlength: 8; maxlength: 20; required: lower; required: upper; required: digit; required: [!$*+@];" + }, + "essportal.excelityglobal.com": { + "password-rules": "minlength: 6; maxlength: 8; allowed: lower, upper, digit;" + }, + "ettoday.net": { + "password-rules": "minlength: 6; maxlength: 12;" + }, + "examservice.com.tw": { + "password-rules": "minlength: 6; maxlength: 8;" + }, + "expertflyer.com": { + "password-rules": "minlength: 5; maxlength: 16; required: lower, upper; required: digit;" + }, + "extraspace.com": { + "password-rules": "minlength: 8; maxlength: 20; allowed: lower; required: upper, digit, [!#$%&*?@];" + }, + "ezpassva.com": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; required: special;" + }, + "fc2.com": { + "password-rules": "minlength: 8; maxlength: 16;" + }, + "fedex.com": { + "password-rules": "minlength: 8; max-consecutive: 3; required: lower; required: upper; required: digit; allowed: [-!@#$%^&*_+=`|(){}[:;,.?]];" + }, + "fidelity.com": { + "password-rules": "minlength: 6; maxlength: 20; required: lower; allowed: upper,digit,[!$%'()+,./:;=?@^_|~];" + }, + "flysas.com": { + "password-rules": "minlength: 8; maxlength: 14; required: lower; required: upper; required: digit; required: [-~!@#$%^&_+=`|(){}[:\"'<>,.?]];" + }, + "fnac.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit;" + }, + "fuelrewards.com": { + "password-rules": "minlength: 8; maxlength: 16; allowed: upper,lower,digit,[!#$%@];" + }, + "gamestop.com": { + "password-rules": "minlength: 8; maxlength: 225; required: lower; required: upper; required: digit; required: [!@#$%];" + }, + "getflywheel.com": { + "password-rules": "minlength: 7; maxlength: 72;" + }, + "girlscouts.org": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; allowed: [$#!];" + }, + "gmx.net": { + "password-rules": "minlength: 8; maxlength: 40; allowed: lower, upper, digit, [-<=>~!|()@#{}$%,.?^'&*_+`:;\"[]];" + }, + "google.com": { + "password-rules": "minlength: 8; allowed: lower, upper, digit, [-!\"#$%&'()*+,./:;<=>?@[^_{|}~]];" + }, + "guardiananytime.com": { + "password-rules": "minlength: 8; maxlength: 50; max-consecutive: 2; required: lower; required: upper; required: digit, [-~!@#$%^&*_+=`|(){}[:;,.?]];" + }, + "gwl.greatwestlife.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: [-!#$%_=+<>];" + }, + "hangseng.com": { + "password-rules": "minlength: 8; maxlength: 30; required: lower; required: upper; required: digit;" + }, + "hawaiianairlines.com": { + "password-rules": "maxlength: 16;" + }, + "hertz.com": { + "password-rules": "minlength: 8; maxlength: 30; max-consecutive: 3; required: lower; required: upper; required: digit; required: [#$%^&!@];" + }, + "hetzner.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit, special;" + }, + "hilton.com": { + "password-rules": "minlength: 8; maxlength: 32; required: lower; required: upper; required: digit;" + }, + "hkbea.com": { + "password-rules": "minlength: 8; maxlength: 12; required: lower; required: upper; required: digit;" + }, + "hkexpress.com": { + "password-rules": "minlength: 8; maxlength: 15; required: lower; required: upper; required: digit; required: special;" + }, + "hotels.com": { + "password-rules": "minlength: 6; maxlength: 20; required: digit; allowed: lower, upper, [@$!#()&^*%];" + }, + "hotwire.com": { + "password-rules": "minlength: 6; maxlength: 30; allowed: lower, upper, digit, [-~!@#$%^&*_+=`|(){}[:;\"'<>,.?]];" + }, + "hrblock.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: [$#%!];" + }, + "hsbc.com.hk": { + "password-rules": "minlength: 6; maxlength: 30; required: lower; required: upper; required: digit; allowed: ['.@_];" + }, + "hsbc.com.my": { + "password-rules": "minlength: 8; maxlength: 30; required: lower, upper; required: digit; allowed: [-!$*.=?@_'];" + }, + "hypovereinsbank.de": { + "password-rules": "minlength: 6; maxlength: 10; required: lower, upper, digit; allowed: [!\"#$%&()*+:;<=>?@[{}~]];" + }, + "hyresbostader.se": { + "password-rules": "minlength: 6; maxlength: 20; required: lower, upper; required: digit;" + }, + "id.sonyentertainmentnetwork.com": { + "password-rules": "minlength: 8; maxlength: 30; required: lower, upper; required: digit; allowed: [-!@#^&*=+;:];" + }, + "identitytheft.gov": { + "password-rules": "allowed: lower, upper, digit, [!#%&*@^];" + }, + "idestination.info": { + "password-rules": "maxlength: 15;" + }, + "impots.gouv.fr": { + "password-rules": "minlength: 12; maxlength: 128; required: lower; required: digit; allowed: [-!#$%&*+/=?^_'.{|}];" + }, + "indochino.com": { + "password-rules": "minlength: 6; maxlength: 15; required: upper; required: digit; allowed: lower, special;" + }, + "internationalsos.com": { + "password-rules": "required: lower; required: upper; required: digit; required: [@#$%^&+=_];" + }, + "irctc.co.in": { + "password-rules": "minlength: 8; maxlength: 15; required: lower; required: upper; required: digit; required: [!@#$%^&*()+];" + }, + "irs.gov": { + "password-rules": "minlength: 8; maxlength: 32; required: lower; required: upper; required: digit; required: [!#$%&*@];" + }, + "jal.co.jp": { + "password-rules": "minlength: 8; maxlength: 16;" + }, + "japanpost.jp": { + "password-rules": "minlength: 8; maxlength: 16; required: digit; required: upper,lower;" + }, + "jordancu-onlinebanking.org": { + "password-rules": "minlength: 6; maxlength: 32; allowed: upper, lower, digit,[-!\"#$%&'()*+,.:;<=>?@[^_`{|}~]];" + }, + "keldoc.com": { + "password-rules": "minlength: 12; required: lower; required: upper; required: digit; required: [!@#$%^&*];" + }, + "key.harvard.edu": { + "password-rules": "minlength: 10; maxlength: 100; required: lower; required: upper; required: digit; allowed: [-@_#!&$`%*+()./,;~:{}|?>=<^[']];" + }, + "kfc.ca": { + "password-rules": "minlength: 6; maxlength: 15; required: lower; required: upper; required: digit; required: [!@#$%&?*];" + }, + "klm.com": { + "password-rules": "minlength: 8; maxlength: 12;" + }, + "la-z-boy.com": { + "password-rules": "minlength: 6; maxlength: 15; required: lower, upper; required: digit;" + }, + "ladwp.com": { + "password-rules": "minlength: 8; maxlength: 20; required: digit; allowed: lower, upper;" + }, + "launtel.net.au": { + "password-rules": "minlength: 8; required: digit; required: digit; allowed: lower, upper;" + }, + "leetchi.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: [!#$%&()*+,./:;<>?@\"_];" + }, + "lg.com": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; allowed: [-!#$%&'()*+,.:;=?@[^_{|}~]];" + }, + "live.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; allowed: [-@_#!&$`%*+()./,;~:{}|?>=<^'[]];" + }, + "lloydsbank.co.uk": { + "password-rules": "minlength: 8; maxlength: 15; required: lower; required: digit; allowed: upper;" + }, + "lowes.com": { + "password-rules": "minlength: 8; maxlength: 12; required: lower, upper; required: digit;" + }, + "lsacsso.b2clogin.com": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit, [-!#$%&*?@^_];" + }, + "lufthansa.com": { + "password-rules": "minlength: 8; maxlength: 32; required: lower; required: upper; required: digit; required: [!#$%&()*+,./:;<>?@\"_];" + }, + "macys.com": { + "password-rules": "minlength: 7; maxlength: 16; allowed: lower, upper, digit, [~!@#$%^&*+`(){}[:;\"'<>?]];" + }, + "mailbox.org": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; allowed: [-!$\"%&/()=*+#.,;:@?{}[]];" + }, + "makemytrip.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: [@$!%*#?&];" + }, + "marriott.com": { + "password-rules": "minlength: 8; maxlength: 20; required: lower; required: upper; required: digit; allowed: [$!#&@?%=];" + }, + "maybank2u.com.my": { + "password-rules": "minlength: 8; maxlength: 12; max-consecutive: 2; required: lower; required: upper; required: digit; required: [-~!@#$%^&*_+=`|(){}[:;\"'<>,.?];" + }, + "medicare.gov": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; required: [@!$%^*()];" + }, + "metlife.com": { + "password-rules": "minlength: 6; maxlength: 20;" + }, + "microsoft.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: special;" + }, + "minecraft.com": { + "password-rules": "minlength: 8; required: lower, upper; required: digit; allowed: ascii-printable;" + }, + "mintmobile.com": { + "password-rules": "minlength: 8; maxlength: 20; required: lower; required: upper; required: digit; required: special; allowed: [!#$%&()*+:;=@[^_`{}~]];" + }, + "mlb.com": { + "password-rules": "minlength: 8; maxlength: 15; required: lower; required: upper; required: digit; allowed: [!\"#$%&'()*+,./:;<=>?[\\^_`{|}~]];" + }, + "mpv.tickets.com": { + "password-rules": "minlength: 8; maxlength: 15; required: lower; required: upper; required: digit;" + }, + "my.konami.net": { + "password-rules": "minlength: 8; maxlength: 32; required: lower; required: upper; required: digit;" + }, + "myaccess.dmdc.osd.mil": { + "password-rules": "minlength: 9; maxlength: 20; required: lower; required: upper; required: digit; allowed: [-@_#!&$`%*+()./,;~:{}|?>=<^'[]];" + }, + "mygoodtogo.com": { + "password-rules": "minlength: 8; maxlength: 16; required: lower, upper, digit;" + }, + "myhealthrecord.com": { + "password-rules": "minlength: 8; maxlength: 20; allowed: lower, upper, digit, [_.!$*=];" + }, + "mysubaru.com": { + "password-rules": "minlength: 8; maxlength: 15; required: lower; required: upper; required: digit; allowed: [!#$%()*+,./:;=?@\\^`~];" + }, + "naver.com": { + "password-rules": "minlength: 6; maxlength: 16;" + }, + "nelnet.net": { + "password-rules": "minlength: 8; maxlength: 15; required: lower; required: upper; required: digit, [!@#$&*];" + }, + "netflix.com": { + "password-rules": "minlength: 4; maxlength: 60; required: lower, upper, digit; allowed: special;" + }, + "netgear.com": { + "password-rules": "minlength: 6; maxlength: 128; allowed: lower, upper, digit, [!@#$%^&*()];" + }, + "nowinstock.net": { + "password-rules": "minlength: 6; maxlength: 20; allowed: lower, upper, digit;" + }, + "order.wendys.com": { + "password-rules": "minlength: 6; maxlength: 20; required: lower; required: upper; required: digit; allowed: [!#$%&()*+/=?^_{}];" + }, + "ototoy.jp": { + "password-rules": "minlength: 8; allowed: upper,lower,digit,[- .=_];" + }, + "packageconciergeadmin.com": { + "password-rules": "minlength: 4; maxlength: 4; allowed: digit;" + }, + "paypal.com": { + "password-rules": "minlength: 8; maxlength: 20; max-consecutive: 3; required: lower, upper; required: digit, [!@#$%^&*()];" + }, + "payvgm.youraccountadvantage.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: special;" + }, + "pilotflyingj.com": { + "password-rules": "minlength: 7; required: digit; allowed: lower, upper;" + }, + "pixnet.cc": { + "password-rules": "minlength: 4; maxlength: 16; allowed: lower, upper;" + }, + "planetary.org": { + "password-rules": "minlength: 5; maxlength: 20; required: lower; required: upper; required: digit; allowed: ascii-printable;" + }, + "portal.edd.ca.gov": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: [!#$%&()*@^];" + }, + "portals.emblemhealth.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: [!#$%&'()*+,./:;<>?@\\^_`{|}~[]];" + }, + "portlandgeneral.com": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; allowed: [!#$%&*?@];" + }, + "poste.it": { + "password-rules": "minlength: 8; maxlength: 16; max-consecutive: 2; required: lower; required: upper; required: digit; required: special;" + }, + "posteo.de": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit, [-~!#$%&_+=|(){}[:;\"’<>,.? ]];" + }, + "powells.com": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; required: [\"!@#$%^&*(){}[]];" + }, + "preferredhotels.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: [!#$%&()*+@^_];" + }, + "premier.ticketek.com.au": { + "password-rules": "minlength: 6; maxlength: 16;" + }, + "prepaid.bankofamerica.com": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; required: [!@#$%^&*()+~{}'\";:<>?];" + }, + "prestocard.ca": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit,[!\"#$%&'()*+,<>?@];" + }, + "propelfuels.com": { + "password-rules": "minlength: 6; maxlength: 16;" + }, + "qdosstatusreview.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: [!#$%&@^];" + }, + "questdiagnostics.com": { + "password-rules": "minlength: 8; maxlength: 30; required: upper, lower; required: digit, [!#$%&()*+<>?@^_~];" + }, + "rejsekort.dk": { + "password-rules": "minlength: 7; maxlength: 15; required: lower; required: upper; required: digit;" + }, + "renaud-bray.com": { + "password-rules": "minlength: 8; maxlength: 38; allowed: upper,lower,digit;" + }, + "ring.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: [!@#$%^&*<>?];" + }, + "riteaid.com": { + "password-rules": "minlength: 8; maxlength: 15; required: lower; required: upper; required: digit;" + }, + "robinhood.com": { + "password-rules": "minlength: 10;" + }, + "rogers.com": { + "password-rules": "minlength: 8; required: lower, upper; required: digit; required: [!@#$];" + }, + "ruc.dk": { + "password-rules": "minlength: 6; maxlength: 8; required: lower, upper; required: [-!#%&(){}*+;%/<=>?_];" + }, + "runescape.com": { + "password-rules": "minlength: 5; maxlength: 20; required: lower; required: upper; required: digit;" + }, + "ruten.com.tw": { + "password-rules": "minlength: 6; maxlength: 15; required: lower, upper;" + }, + "salslimo.com": { + "password-rules": "minlength: 8; maxlength: 50; required: upper; required: lower; required: digit; required: [!@#$&*];" + }, + "santahelenasaude.com.br": { + "password-rules": "minlength: 8; maxlength: 15; required: lower; required: upper; required: digit; required: [-!@#$%&*_+=<>];" + }, + "santander.de": { + "password-rules": "minlength: 8; maxlength: 12; required: lower, upper; required: digit; allowed: [-!#$%&'()*,.:;=?^{}];" + }, + "sbisec.co.jp": { + "password-rules": "minlength: 10; maxlength: 20; allowed: upper,lower,digit;" + }, + "secure-arborfcu.org": { + "password-rules": "minlength: 8; maxlength: 15; required: lower; required: upper; required: digit; required: [!#$%&'()+,.:?@[_`~]];" + }, + "secure.orclinic.com": { + "password-rules": "minlength: 6; maxlength: 15; required: lower; required: digit; allowed: ascii-printable;" + }, + "secure.snnow.ca": { + "password-rules": "minlength: 7; maxlength: 16; required: digit; allowed: lower, upper;" + }, + "secure.wa.aaa.com": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; allowed: ascii-printable;" + }, + "sephora.com": { + "password-rules": "minlength: 6; maxlength: 12;" + }, + "serviziconsolari.esteri.it": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; required: special;" + }, + "servizioelettriconazionale.it": { + "password-rules": "minlength: 8; maxlength: 20; required: lower; required: upper; required: digit; required: [!#$%&*?@^_~];" + }, + "sfwater.org": { + "password-rules": "minlength: 10; maxlength: 30; required: digit; allowed: lower, upper, [!@#$%*()_+^}{:;?.];" + }, + "signin.ea.com": { + "password-rules": "minlength: 8; maxlength: 64; required: lower, upper; required: digit; allowed: [-!@#^&*=+;:];" + }, + "southwest.com": { + "password-rules": "minlength: 8; maxlength: 16; required: upper; required: digit; allowed: lower, [!@#$%^*(),.;:/\\];" + }, + "speedway.com": { + "password-rules": "minlength: 4; maxlength: 8; required: digit;" + }, + "spirit.com": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; required: [!@#$%^&*()];" + }, + "splunk.com": { + "password-rules": "minlength: 8; maxlength: 64; required: lower; required: upper; required: digit; required: [-!@#$%&*_+=<>];" + }, + "ssa.gov": { + "password-rules": "required: lower; required: upper; required: digit; required: [~!@#$%^&*];" + }, + "store.nvidia.com": { + "password-rules": "minlength: 8; maxlength: 32; required: lower; required: upper; required: digit; required: [-!@#$%^*~:;&><[{}|_+=?]];" + }, + "store.steampowered.com": { + "password-rules": "minlength: 6; required: lower; required: upper; required: digit; allowed: [~!@#$%^&*];" + }, + "successfactors.eu": { + "password-rules": "minlength: 8; maxlength: 18; required: lower; required: upper; required: digit,[-!\"#$%&'()*+,.:;<=>?@[^_`{|}~]];" + }, + "sulamericaseguros.com.br": { + "password-rules": "minlength: 6; maxlength: 6;" + }, + "sunlife.com": { + "password-rules": "minlength: 8; maxlength: 10; required: digit; required: lower, upper;" + }, + "t-mobile.net": { + "password-rules": "minlength: 8; maxlength: 16;" + }, + "target.com": { + "password-rules": "minlength: 8; maxlength: 20; required: lower, upper; required: digit, [-!\"#$%&'()*+,./:;=?@[\\^_`{|}~];" + }, + "telekom-dienste.de": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; required: [#$%&()*+,./<=>?@_{|}~];" + }, + "thameswater.co.uk": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; required: special;" + }, + "tix.soundrink.com": { + "password-rules": "minlength: 6; maxlength: 16;" + }, + "training.confluent.io": { + "password-rules": "minlength: 6; maxlength: 16; required: lower; required: upper; required: digit; allowed: [!#$%*@^_~];" + }, + "twitter.com": { + "password-rules": "minlength: 8;" + }, + "ubisoft.com": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; required: [-]; required: [!@#$%^&*()+];" + }, + "udel.edu": { + "password-rules": "minlength: 12; maxlength: 30; required: lower; required: upper; required: digit; required: [!@#$%^&*()+];" + }, + "user.ornl.gov": { + "password-rules": "minlength: 8; maxlength: 30; max-consecutive: 3; required: lower, upper; required: digit; allowed: [!#$%./_];" + }, + "usps.com": { + "password-rules": "minlength: 8; maxlength: 50; max-consecutive: 2; required: lower; required: upper; required: digit; allowed: [-!\"#&'()+,./?@];" + }, + "vanguard.com": { + "password-rules": "minlength: 6; maxlength: 20; required: lower; required: upper; required: digit; required: digit;" + }, + "vanguardinvestor.co.uk": { + "password-rules": "minlength: 8; maxlength: 50; required: lower; required: upper; required: digit; required: digit;" + }, + "ventrachicago.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit, [!@#$%^];" + }, + "verizonwireless.com": { + "password-rules": "minlength: 8; maxlength: 20; required: lower, upper; required: digit; allowed: unicode;" + }, + "vetsfirstchoice.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; allowed: [?!@$%^+=&];" + }, + "virginmobile.ca": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: [!#$@];" + }, + "visa.com": { + "password-rules": "minlength: 6; maxlength: 32;" + }, + "visabenefits-auth.axa-assistance.us": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: [!\"#$%&()*,.:<>?@^{|}];" + }, + "vivo.com.br": { + "password-rules": "maxlength: 6; max-consecutive: 3; allowed: digit;" + }, + "walkhighlands.co.uk": { + "password-rules": "minlength: 9; maxlength: 15; required: lower; required: upper; required: digit; allowed: special;" + }, + "walmart.com": { + "password-rules": "allowed: lower, upper, digit, [-(~!@#$%^&*_+=`|(){}[:;\"'<>,.?]];" + }, + "waze.com": { + "password-rules": "minlength: 8; maxlength: 64; required: lower, upper, digit;" + }, + "wccls.org": { + "password-rules": "minlength: 4; maxlength: 16; allowed: lower, upper, digit;" + }, + "web.de": { + "password-rules": "minlength: 8; maxlength: 40; allowed: lower, upper, digit, [-<=>~!|()@#{}$%,.?^'&*_+`:;\"[]];" + }, + "wegmans.com": { + "password-rules": "minlength: 8; required: digit; required: upper,lower; required: [!#$%&*+=?@^];" + }, + "weibo.com": { + "password-rules": "minlength: 6; maxlength: 16;" + }, + "wsj.com": { + "password-rules": "minlength: 5; maxlength: 15; required: digit; allowed: lower, upper, [-~!@#$^*_=`|(){}[:;\"'<>,.?]];" + }, + "xfinity.com": { + "password-rules": "minlength: 8; maxlength: 16; required: lower, upper; required: digit;" + }, + "xvoucher.com": { + "password-rules": "minlength: 11; required: upper; required: digit; required: [!@#$%&_];" + }, + "yatra.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: [!#$%&'()+,.:?@[_`~]];" + }, + "zdf.de": { + "password-rules": "minlength: 8; required: upper; required: digit; allowed: lower, special;" + }, + "zoom.us": { + "password-rules": "minlength: 8; maxlength: 32; max-consecutive: 6; required: lower; required: upper; required: digit;" + } +} +},{}],7:[function(require,module,exports){ +"use strict"; + +const { + isDDGApp, + isAndroid +} = require('./autofill-utils'); + +const AndroidInterface = require('./DeviceInterface/AndroidInterface'); + +const ExtensionInterface = require('./DeviceInterface/ExtensionInterface'); + +const AppleDeviceInterface = require('./DeviceInterface/AppleDeviceInterface'); // Exports a device interface instance + + +const deviceInterface = (() => { + if (isDDGApp) { + return isAndroid ? new AndroidInterface() : new AppleDeviceInterface(); + } + + return new ExtensionInterface(); +})(); + +module.exports = deviceInterface; + +},{"./DeviceInterface/AndroidInterface":8,"./DeviceInterface/AppleDeviceInterface":9,"./DeviceInterface/ExtensionInterface":10,"./autofill-utils":36}],8:[function(require,module,exports){ +"use strict"; + +const InterfacePrototype = require('./InterfacePrototype.js'); + +const { + isDDGDomain, + sendAndWaitForAnswer +} = require('../autofill-utils'); + +const { + scanForInputs +} = require('../scanForInputs.js'); + +class AndroidInterface extends InterfacePrototype { + async getAlias() { + const { + alias + } = await sendAndWaitForAnswer(() => { + return window.EmailInterface.showTooltip(); + }, 'getAliasResponse'); + return alias; + } + + isDeviceSignedIn() { + // isDeviceSignedIn is only available on DDG domains... + if (isDDGDomain()) return window.EmailInterface.isSignedIn() === 'true'; // ...on other domains we assume true because the script wouldn't exist otherwise + + return true; + } + + async setupAutofill() { + if (this.isDeviceSignedIn()) { + const cleanup = scanForInputs(this).init(); + this.addLogoutListener(cleanup); + } + } + + getUserData() { + let userData = null; + + try { + userData = JSON.parse(window.EmailInterface.getUserData()); + } catch (e) {} + + return Promise.resolve(userData); + } + + storeUserData(_ref) { + let { + addUserData: { + token, + userName, + cohort + } + } = _ref; + return window.EmailInterface.storeCredentials(token, userName, cohort); + } + +} + +module.exports = AndroidInterface; + +},{"../autofill-utils":36,"../scanForInputs.js":40,"./InterfacePrototype.js":11}],9:[function(require,module,exports){ +"use strict"; + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); } + +function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } } + +function _classPrivateFieldGet(receiver, privateMap) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "get"); return _classApplyDescriptorGet(receiver, descriptor); } + +function _classExtractFieldDescriptor(receiver, privateMap, action) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to " + action + " private field on non-instance"); } return privateMap.get(receiver); } + +function _classApplyDescriptorGet(receiver, descriptor) { if (descriptor.get) { return descriptor.get.call(receiver); } return descriptor.value; } + +const InterfacePrototype = require('./InterfacePrototype.js'); + +const { + wkSend, + wkSendAndWait +} = require('../appleDeviceUtils/appleDeviceUtils'); + +const { + isApp, + isTopFrame, + supportsTopFrame, + formatDuckAddress, + autofillEnabled +} = require('../autofill-utils'); + +const { + scanForInputs, + forms +} = require('../scanForInputs.js'); + +const { + processConfig +} = require('@duckduckgo/content-scope-scripts/src/apple-utils'); +/** + * @implements {FeatureToggles} + */ + + +var _supportedFeatures = /*#__PURE__*/new WeakMap(); + +class AppleDeviceInterface extends InterfacePrototype { + /** @type {FeatureToggleNames[]} */ + + /* @type {Timeout | undefined} */ + async isEnabled() { + return autofillEnabled(processConfig); + } + + constructor() { + super(); + + _classPrivateFieldInitSpec(this, _supportedFeatures, { + writable: true, + value: ['password.generation'] + }); + + _defineProperty(this, "pollingTimeout", void 0); + + if (isTopFrame) { + this.stripCredentials = false; + window.addEventListener('mouseMove', this); + } else { + // This is always added as a child frame needs to be informed of a parent frame scroll + window.addEventListener('scroll', this); + } + } + + postInit() { + if (!isTopFrame) return; + this.setupTopFrame(); + } + + async setupTopFrame() { + const topContextData = this.getTopContextData(); + if (!topContextData) throw new Error('unreachable, topContextData should be available'); // Provide dummy values, they're not used + + const getPosition = () => { + return { + x: 0, + y: 0, + height: 50, + width: 50 + }; + }; + + const tooltip = this.createTooltip(getPosition, topContextData); + this.setActiveTooltip(tooltip); + } + /** + * Poll the native listener until the user has selected a credential. + * Message return types are: + * - 'stop' is returned whenever the message sent doesn't match the native last opened tooltip. + * - This also is triggered when the close event is called and prevents any edge case continued polling. + * - 'ok' is when the user has selected a credential and the value can be injected into the page. + * - 'none' is when the tooltip is open in the native window however hasn't been entered. + * @returns {Promise} + */ + + + async listenForSelectedCredential() { + // Prevent two timeouts from happening + clearTimeout(this.pollingTimeout); + const response = await wkSendAndWait('getSelectedCredentials'); + + switch (response.type) { + case 'none': + // Parent hasn't got a selected credential yet + this.pollingTimeout = setTimeout(() => { + this.listenForSelectedCredential(); + }, 100); + return; + + case 'ok': + return this.activeFormSelectedDetail(response.data, response.configType); + + case 'stop': + // Parent wants us to stop polling + break; + } + } + + handleEvent(event) { + switch (event.type) { + case 'mouseMove': + this.processMouseMove(event); + break; + + case 'scroll': + this.removeTooltip(); + break; + + default: + super.handleEvent(event); + } + } + + processMouseMove(event) { + var _this$currentTooltip; + + (_this$currentTooltip = this.currentTooltip) === null || _this$currentTooltip === void 0 ? void 0 : _this$currentTooltip.focus(event.detail.x, event.detail.y); + } + + async setupAutofill() { + if (isApp) { + await this.getAutofillInitData(); + } + + const signedIn = await this._checkDeviceSignedIn(); + + if (signedIn) { + if (isApp) { + await this.getAddresses(); + } + + forms.forEach(form => form.redecorateAllInputs()); + } + + const cleanup = scanForInputs(this).init(); + this.addLogoutListener(cleanup); + } + + getUserData() { + return wkSendAndWait('emailHandlerGetUserData'); + } + + async getAddresses() { + if (!isApp) return this.getAlias(); + const { + addresses + } = await wkSendAndWait('emailHandlerGetAddresses'); + this.storeLocalAddresses(addresses); + return addresses; + } + + async refreshAlias() { + await wkSendAndWait('emailHandlerRefreshAlias'); // On macOS we also update the addresses stored locally + + if (isApp) this.getAddresses(); + } + + async _checkDeviceSignedIn() { + const { + isAppSignedIn + } = await wkSendAndWait('emailHandlerCheckAppSignedInStatus'); + + this.isDeviceSignedIn = () => !!isAppSignedIn; + + return !!isAppSignedIn; + } + + async setSize(details) { + await wkSend('setSize', details); + } + /** + * @param {import("../Form/Form").Form} form + * @param {HTMLInputElement} input + * @param {() => { x: number; y: number; height: number; width: number; }} getPosition + * @param {{ x: number; y: number; }} click + * @param {TopContextData} topContextData + */ + + + attachTooltipInner(form, input, getPosition, click, topContextData) { + if (!isTopFrame && supportsTopFrame) { + // TODO currently only mouse initiated events are supported + if (!click) { + return; + } + + this.showTopTooltip(click, getPosition(), topContextData); + return; + } + + super.attachTooltipInner(form, input, getPosition, click, topContextData); + } + /** + * @param {{ x: number; y: number; }} click + * @param {{ x: number; y: number; height: number; width: number; }} inputDimensions + * @param {TopContextData} [data] + */ + + + async showTopTooltip(click, inputDimensions, data) { + let diffX = Math.floor(click.x - inputDimensions.x); + let diffY = Math.floor(click.y - inputDimensions.y); + const details = { + inputTop: diffY, + inputLeft: diffX, + inputHeight: Math.floor(inputDimensions.height), + inputWidth: Math.floor(inputDimensions.width), + serializedInputContext: JSON.stringify(data) + }; + await wkSend('showAutofillParent', details); // Start listening for the user initiated credential + + this.listenForSelectedCredential(); + } + + async removeTooltip() { + if (!supportsTopFrame) return super.removeTooltip(); + await wkSend('closeAutofillParent', {}); + } + + storeUserData(_ref) { + let { + addUserData: { + token, + userName, + cohort + } + } = _ref; + return wkSend('emailHandlerStoreToken', { + token, + username: userName, + cohort + }); + } + /** + * PM endpoints + */ + + /** + * Sends credentials to the native layer + * @param {{username: string, password: string}} credentials + */ + + + storeCredentials(credentials) { + return wkSend('pmHandlerStoreCredentials', credentials); + } + /** + * Gets the init data from the device + * @returns {APIResponse} + */ + + + async getAutofillInitData() { + const response = await wkSendAndWait('pmHandlerGetAutofillInitData'); + this.storeLocalData(response.success); + return response; + } + /** + * Gets credentials ready for autofill + * @param {Number} id - the credential id + * @returns {APIResponse} + */ + + + getAutofillCredentials(id) { + return wkSendAndWait('pmHandlerGetAutofillCredentials', { + id + }); + } + /** + * Opens the native UI for managing passwords + */ + + + openManagePasswords() { + return wkSend('pmHandlerOpenManagePasswords'); + } + /** + * Opens the native UI for managing identities + */ + + + openManageIdentities() { + return wkSend('pmHandlerOpenManageIdentities'); + } + /** + * Opens the native UI for managing credit cards + */ + + + openManageCreditCards() { + return wkSend('pmHandlerOpenManageCreditCards'); + } + /** + * Gets a single identity obj once the user requests it + * @param {Number} id + * @returns {Promise<{success: IdentityObject|undefined}>} + */ + + + getAutofillIdentity(id) { + const identity = this.getLocalIdentities().find(_ref2 => { + let { + id: identityId + } = _ref2; + return "".concat(identityId) === "".concat(id); + }); + return Promise.resolve({ + success: identity + }); + } + /** + * Gets a single complete credit card obj once the user requests it + * @param {Number} id + * @returns {APIResponse} + */ + + + getAutofillCreditCard(id) { + return wkSendAndWait('pmHandlerGetCreditCard', { + id + }); + } // Used to encode data to send back to the child autofill + + + async selectedDetail(detailIn, configType) { + if (isTopFrame) { + let detailsEntries = Object.entries(detailIn).map(_ref3 => { + let [key, value] = _ref3; + return [key, String(value)]; + }); + const data = Object.fromEntries(detailsEntries); + wkSend('selectedDetail', { + data, + configType + }); + } else { + this.activeFormSelectedDetail(detailIn, configType); + } + } + + async getCurrentInputType() { + const { + inputType + } = this.getTopContextData() || {}; + return inputType; + } + + async getAlias() { + const { + alias + } = await wkSendAndWait('emailHandlerGetAlias', { + requiresUserPermission: !isApp, + shouldConsumeAliasIfProvided: !isApp + }); + return formatDuckAddress(alias); + } + /** @param {FeatureToggleNames} name */ + + + supportsFeature(name) { + return _classPrivateFieldGet(this, _supportedFeatures).includes(name); + } + +} + +module.exports = AppleDeviceInterface; + +},{"../appleDeviceUtils/appleDeviceUtils":34,"../autofill-utils":36,"../scanForInputs.js":40,"./InterfacePrototype.js":11,"@duckduckgo/content-scope-scripts/src/apple-utils":1}],10:[function(require,module,exports){ +"use strict"; + +const InterfacePrototype = require('./InterfacePrototype.js'); + +const { + SIGN_IN_MSG, + isDDGDomain, + sendAndWaitForAnswer, + setValue, + formatDuckAddress, + autofillEnabled +} = require('../autofill-utils'); + +const { + scanForInputs +} = require('../scanForInputs.js'); + +class ExtensionInterface extends InterfacePrototype { + async isEnabled() { + if (!autofillEnabled()) return false; + return new Promise(resolve => { + // Check if the site is marked to skip autofill + chrome.runtime.sendMessage({ + registeredTempAutofillContentScript: true, + documentUrl: window.location.href + }, response => { + var _response$site, _response$site$broken; + + if (!(response !== null && response !== void 0 && (_response$site = response.site) !== null && _response$site !== void 0 && (_response$site$broken = _response$site.brokenFeatures) !== null && _response$site$broken !== void 0 && _response$site$broken.includes('autofill'))) { + resolve(true); + } + + resolve(false); + }); + }); + } + + isDeviceSignedIn() { + return this.hasLocalAddresses; + } + + setupAutofill() { + return this.getAddresses().then(_addresses => { + if (this.hasLocalAddresses) { + const cleanup = scanForInputs(this).init(); + this.addLogoutListener(cleanup); + } + }); + } + + getAddresses() { + return new Promise(resolve => chrome.runtime.sendMessage({ + getAddresses: true + }, data => { + this.storeLocalAddresses(data); + return resolve(data); + })); + } + + getUserData() { + return new Promise(resolve => chrome.runtime.sendMessage({ + getUserData: true + }, data => resolve(data))); + } + + refreshAlias() { + return chrome.runtime.sendMessage({ + refreshAlias: true + }, addresses => this.storeLocalAddresses(addresses)); + } + + async trySigningIn() { + if (isDDGDomain()) { + const data = await sendAndWaitForAnswer(SIGN_IN_MSG, 'addUserData'); + this.storeUserData(data); + } + } + + storeUserData(data) { + return chrome.runtime.sendMessage(data); + } + + addDeviceListeners() { + // Add contextual menu listeners + let activeEl = null; + document.addEventListener('contextmenu', e => { + activeEl = e.target; + }); + chrome.runtime.onMessage.addListener((message, sender) => { + if (sender.id !== chrome.runtime.id) return; + + switch (message.type) { + case 'ddgUserReady': + this.setupAutofill().then(() => { + this.setupSettingsPage({ + shouldLog: true + }); + }); + break; + + case 'contextualAutofill': + setValue(activeEl, formatDuckAddress(message.alias)); + activeEl.classList.add('ddg-autofilled'); + this.refreshAlias(); // If the user changes the alias, remove the decoration + + activeEl.addEventListener('input', e => e.target.classList.remove('ddg-autofilled'), { + once: true + }); + break; + + default: + break; + } + }); + } + + addLogoutListener(handler) { + // Cleanup on logout events + chrome.runtime.onMessage.addListener((message, sender) => { + if (sender.id === chrome.runtime.id && message.type === 'logout') { + handler(); + } + }); + } + +} + +module.exports = ExtensionInterface; + +},{"../autofill-utils":36,"../scanForInputs.js":40,"./InterfacePrototype.js":11}],11:[function(require,module,exports){ +"use strict"; + +function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); } + +function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +function _classPrivateFieldSet(receiver, privateMap, value) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "set"); _classApplyDescriptorSet(receiver, descriptor, value); return value; } + +function _classApplyDescriptorSet(receiver, descriptor, value) { if (descriptor.set) { descriptor.set.call(receiver, value); } else { if (!descriptor.writable) { throw new TypeError("attempted to set read only private field"); } descriptor.value = value; } } + +function _classPrivateFieldGet(receiver, privateMap) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "get"); return _classApplyDescriptorGet(receiver, descriptor); } + +function _classExtractFieldDescriptor(receiver, privateMap, action) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to " + action + " private field on non-instance"); } return privateMap.get(receiver); } + +function _classApplyDescriptorGet(receiver, descriptor) { if (descriptor.get) { return descriptor.get.call(receiver); } return descriptor.value; } + +const { + ADDRESS_DOMAIN, + SIGN_IN_MSG, + isApp, + isMobileApp, + isDDGDomain, + sendAndWaitForAnswer, + formatDuckAddress, + autofillEnabled, + notifyWebApp +} = require('../autofill-utils'); + +const { + getInputType, + getSubtypeFromType +} = require('../Form/matching'); + +const { + formatFullName +} = require('../Form/formatters'); + +const EmailAutofill = require('../UI/EmailAutofill'); + +const DataAutofill = require('../UI/DataAutofill'); + +const { + getInputConfigFromType +} = require('../Form/inputTypeConfig'); + +const listenForGlobalFormSubmission = require('../Form/listenForFormSubmission'); + +const { + forms +} = require('../scanForInputs'); + +const { + fromPassword, + GENERATED_ID +} = require('../InputTypes/Credentials'); + +const { + PasswordGenerator +} = require('../PasswordGenerator'); // This may get replaced by a test script + + +let isDDGTestMode = false; +/** + * @implements {FeatureToggles} + */ + +var _addresses = /*#__PURE__*/new WeakMap(); + +var _data2 = /*#__PURE__*/new WeakMap(); + +class InterfacePrototype { + constructor() { + _defineProperty(this, "mode", isDDGTestMode ? 'test' : 'production'); + + _defineProperty(this, "attempts", 0); + + _defineProperty(this, "currentAttached", null); + + _defineProperty(this, "currentTooltip", null); + + _defineProperty(this, "stripCredentials", true); + + _defineProperty(this, "passwordGenerator", new PasswordGenerator()); + + _classPrivateFieldInitSpec(this, _addresses, { + writable: true, + value: { + privateAddress: '', + personalAddress: '' + } + }); + + _classPrivateFieldInitSpec(this, _data2, { + writable: true, + value: { + credentials: [], + creditCards: [], + identities: [], + topContextData: undefined + } + }); + } + + get hasLocalAddresses() { + var _classPrivateFieldGet2, _classPrivateFieldGet3; + + return !!((_classPrivateFieldGet2 = _classPrivateFieldGet(this, _addresses)) !== null && _classPrivateFieldGet2 !== void 0 && _classPrivateFieldGet2.privateAddress && (_classPrivateFieldGet3 = _classPrivateFieldGet(this, _addresses)) !== null && _classPrivateFieldGet3 !== void 0 && _classPrivateFieldGet3.personalAddress); + } + + getLocalAddresses() { + return _classPrivateFieldGet(this, _addresses); + } + + storeLocalAddresses(addresses) { + _classPrivateFieldSet(this, _addresses, addresses); // When we get new duck addresses, add them to the identities list + + + const identities = this.getLocalIdentities(); + const privateAddressIdentity = identities.find(_ref => { + let { + id + } = _ref; + return id === 'privateAddress'; + }); // If we had previously stored them, just update the private address + + if (privateAddressIdentity) { + privateAddressIdentity.emailAddress = formatDuckAddress(addresses.privateAddress); + } else { + // Otherwise, add both addresses + _classPrivateFieldGet(this, _data2).identities = this.addDuckAddressesToIdentities(identities); + } + } + /** @type { PMData } */ + + + /** + * @returns {Promise} + */ + async getCurrentInputType() { + throw new Error('Not implemented'); + } + + addDuckAddressesToIdentities(identities) { + if (!this.hasLocalAddresses) return identities; + const newIdentities = []; + let { + privateAddress, + personalAddress + } = this.getLocalAddresses(); + privateAddress = formatDuckAddress(privateAddress); + personalAddress = formatDuckAddress(personalAddress); // Get the duck addresses in identities + + const duckEmailsInIdentities = identities.reduce((duckEmails, _ref2) => { + let { + emailAddress: email + } = _ref2; + return email.includes(ADDRESS_DOMAIN) ? duckEmails.concat(email) : duckEmails; + }, []); // Only add the personal duck address to identities if the user hasn't + // already manually added it + + if (!duckEmailsInIdentities.includes(personalAddress)) { + newIdentities.push({ + id: 'personalAddress', + emailAddress: personalAddress, + title: 'Blocks Email Trackers' + }); + } + + newIdentities.push({ + id: 'privateAddress', + emailAddress: privateAddress, + title: 'Blocks Email Trackers and hides Your Address' + }); + return [...identities, ...newIdentities]; + } + /** + * Stores init data coming from the device + * @param { InboundPMData } data + */ + + + storeLocalData(data) { + if (this.stripCredentials) { + data.credentials.forEach(cred => delete cred.password); + data.creditCards.forEach(cc => delete cc.cardNumber && delete cc.cardSecurityCode); + } // Store the full name as a separate field to simplify autocomplete + + + const updatedIdentities = data.identities.map(identity => ({ ...identity, + fullName: formatFullName(identity) + })); // Add addresses + + _classPrivateFieldGet(this, _data2).identities = this.addDuckAddressesToIdentities(updatedIdentities); + _classPrivateFieldGet(this, _data2).creditCards = data.creditCards; + _classPrivateFieldGet(this, _data2).credentials = data.credentials; // Top autofill only + + if (data.serializedInputContext) { + try { + _classPrivateFieldGet(this, _data2).topContextData = JSON.parse(data.serializedInputContext); + } catch (e) { + console.error(e); + this.removeTooltip(); + } + } + } + + getTopContextData() { + return _classPrivateFieldGet(this, _data2).topContextData; + } + + get hasLocalCredentials() { + return _classPrivateFieldGet(this, _data2).credentials.length > 0; + } + + getLocalCredentials() { + return _classPrivateFieldGet(this, _data2).credentials.map(cred => { + const { + password, + ...rest + } = cred; + return rest; + }); + } + + get hasLocalIdentities() { + return _classPrivateFieldGet(this, _data2).identities.length > 0; + } + + getLocalIdentities() { + return _classPrivateFieldGet(this, _data2).identities; + } + + get hasLocalCreditCards() { + return _classPrivateFieldGet(this, _data2).creditCards.length > 0; + } + /** @return {CreditCardObject[]} */ + + + getLocalCreditCards() { + return _classPrivateFieldGet(this, _data2).creditCards; + } + + async startInit() { + window.addEventListener('pointerdown', this, true); + listenForGlobalFormSubmission(); + this.addDeviceListeners(); + await this.setupAutofill(); + await this.setupSettingsPage(); + this.postInit(); + } + + postInit() {} + + async isEnabled() { + return autofillEnabled(); + } + + async init() { + const isEnabled = await this.isEnabled(); + if (!isEnabled) return; + + if (document.readyState === 'complete') { + this.startInit(); + } else { + window.addEventListener('load', () => { + this.startInit(); + }); + } + } // Global listener for event delegation + + + pointerDownListener(e) { + if (!e.isTrusted) return; // @ts-ignore + + if (e.target.nodeName === 'DDG-AUTOFILL') { + e.preventDefault(); + e.stopImmediatePropagation(); + const activeTooltip = this.getActiveTooltip(); + activeTooltip === null || activeTooltip === void 0 ? void 0 : activeTooltip.dispatchClick(); + } else { + this.removeTooltip(); + } + + if (!isApp) return; // Check for clicks on submit buttons + + const matchingForm = [...forms.values()].find(form => { + const btns = [...form.submitButtons]; // @ts-ignore + + if (btns.includes(e.target)) return true; // @ts-ignore + + if (btns.find(btn => btn.contains(e.target))) return true; + }); + matchingForm === null || matchingForm === void 0 ? void 0 : matchingForm.submitHandler(); + } + /** + * @param {IdentityObject|CreditCardObject|CredentialsObject|{email:string, id: string}} data + * @param {string} type + */ + + + async selectedDetail(data, type) { + this.activeFormSelectedDetail(data, type); + } + /** + * @param {IdentityObject|CreditCardObject|CredentialsObject|{email:string, id: string}} data + * @param {string} type + */ + + + activeFormSelectedDetail(data, type) { + const form = this.currentAttached; + + if (!form) { + return; + } + + if (data.id === 'privateAddress') { + this.refreshAlias(); + } + + if (type === 'email' && 'email' in data) { + form.autofillEmail(data.email); + } else { + form.autofillData(data, type); + } + + this.removeTooltip(); + } + /** + * @param {()=>void} getPosition + * @param {TopContextData} topContextData + */ + + + createTooltip(getPosition, topContextData) { + const config = getInputConfigFromType(topContextData.inputType); // Attach close listeners + + window.addEventListener('input', () => this.removeTooltip(), { + once: true + }); + + if (isApp) { + // collect the data for each item to display + const data = this.dataForAutofill(config, topContextData.inputType, topContextData); // convert the data into tool tip item renderers + + const asRenderers = data.map(d => config.tooltipItem(d)); // construct the autofill + + return new DataAutofill(config, topContextData.inputType, getPosition, this).render(config, asRenderers, { + onSelect: id => this.onSelect(config, data, id) + }); + } else { + return new EmailAutofill(config, topContextData.inputType, getPosition, this); + } + } + /** + * Before the DataAutofill opens, we collect the data based on the config.type + * @param {InputTypeConfigs} config + * @param {import('../Form/matching').SupportedTypes} inputType + * @param {TopContextData} [data] + * @returns {(CredentialsObject|CreditCardObject|IdentityObject)[]} + */ + + + dataForAutofill(config, inputType, data) { + const subtype = getSubtypeFromType(inputType); + + if (config.type === 'identities') { + return this.getLocalIdentities().filter(identity => !!identity[subtype]); + } + + if (config.type === 'creditCard') { + return this.getLocalCreditCards(); + } + + if (config.type === 'credentials') { + if (data) { + if (Array.isArray(data.credentials) && data.credentials.length > 0) { + return data.credentials; + } else { + return this.getLocalCredentials(); + } + } + } + + return []; + } + /** + * @param {import("../Form/Form").Form} form + * @param {HTMLInputElement} input + * @param {{ (): { x: number; y: number; height: number; width: number; }; (): void; }} getPosition + * @param {{ x: number; y: number; }} click + */ + + + attachTooltip(form, input, getPosition, click) { + form.activeInput = input; + this.currentAttached = form; + const inputType = getInputType(input); + + if (isMobileApp) { + this.getAlias().then(alias => { + var _form$activeInput; + + if (alias) form.autofillEmail(alias);else (_form$activeInput = form.activeInput) === null || _form$activeInput === void 0 ? void 0 : _form$activeInput.focus(); + }); + return; + } + /** @type {TopContextData} */ + + + const topContextData = { + inputType + }; // A list of checks to determine if we need to generate a password + + const checks = [inputType === 'credentials.password', this.supportsFeature('password.generation'), form.isSignup]; // if all checks pass, generate and save a password + + if (checks.every(Boolean)) { + const password = this.passwordGenerator.generate({ + input: input.getAttribute('passwordrules'), + domain: window.location.hostname + }); // append the new credential to the topContextData so that the top autofill can display it + + topContextData.credentials = [fromPassword(password)]; + } + + this.attachTooltipInner(form, input, getPosition, click, topContextData); + } + /** + * If the device was capable of generating password, and it + * previously did so for the form in question, then offer to + * save the credentials + * + * @param {{ formElement?: HTMLFormElement; }} options + */ + + + shouldPromptToStoreCredentials(options) { + if (!options.formElement) return false; + if (!this.supportsFeature('password.generation')) return false; // if we previously generated a password, allow it to be saved + + if (this.passwordGenerator.generated) { + return true; + } + + return false; + } + /** + * When an item was selected, we then call back to the device + * to fetch the full suite of data needed to complete the autofill + * + * @param {InputTypeConfigs} config + * @param {(CreditCardObject|IdentityObject|CredentialsObject)[]} items + * @param {string|number} id + */ + + + onSelect(config, items, id) { + id = String(id); + const matchingData = items.find(item => String(item.id) === id); + if (!matchingData) throw new Error('unreachable (fatal)'); + + const dataPromise = (() => { + switch (config.type) { + case 'creditCard': + return this.getAutofillCreditCard(id); + + case 'identities': + return this.getAutofillIdentity(id); + + case 'credentials': + { + if (id === GENERATED_ID) { + return Promise.resolve({ + success: matchingData + }); + } + + return this.getAutofillCredentials(id); + } + + default: + throw new Error('unreachable!'); + } + })(); // wait for the data back from the device + + + dataPromise.then(response => { + if (response.success) { + return this.selectedDetail(response.success, config.type); + } else { + return Promise.reject(new Error('none-success response')); + } + }).catch(e => { + console.error(e); + return this.removeTooltip(); + }); + } + /** + * @param {import("../Form/Form").Form} form + * @param {any} input + * @param {{ (): { x: number; y: number; height: number; width: number; }; (): void; }} getPosition + * @param {{ x: number; y: number; }} _click + * @param {TopContextData} data + */ + + + attachTooltipInner(form, input, getPosition, _click, data) { + if (this.currentTooltip) return; + this.currentTooltip = this.createTooltip(getPosition, data); + form.showingTooltip(input); + } + + async removeTooltip() { + if (this.currentTooltip) { + this.currentTooltip.remove(); + this.currentTooltip = null; + this.currentAttached = null; + } + } + + getActiveTooltip() { + return this.currentTooltip; + } + + setActiveTooltip(tooltip) { + this.currentTooltip = tooltip; + } + + handleEvent(event) { + switch (event.type) { + case 'pointerdown': + this.pointerDownListener(event); + break; + } + } + + async setupSettingsPage() { + let { + shouldLog + } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { + shouldLog: false + }; + + if (isDDGDomain()) { + notifyWebApp({ + isApp + }); + + if (this.isDeviceSignedIn()) { + let userData; + + try { + userData = await this.getUserData(); + } catch (e) {} + + const hasUserData = userData && !userData.error && Object.entries(userData).length > 0; + notifyWebApp({ + deviceSignedIn: { + value: true, + shouldLog, + userData: hasUserData ? userData : undefined + } + }); + } else { + this.trySigningIn(); + } + } + } + + async setupAutofill() {} + + getAddresses() {} + /** + * @returns {Promise>} + */ + + + getUserData() { + return Promise.resolve(null); + } + + refreshAlias() {} + + async trySigningIn() { + if (isDDGDomain()) { + if (this.attempts < 10) { + this.attempts++; + const data = await sendAndWaitForAnswer(SIGN_IN_MSG, 'addUserData'); // This call doesn't send a response, so we can't know if it succeeded + + this.storeUserData(data); + await this.setupAutofill(); + await this.setupSettingsPage({ + shouldLog: true + }); + } else { + console.warn('max attempts reached, bailing'); + } + } + } + + storeUserData(_data) {} + + addDeviceListeners() {} + /** @param {() => void} _fn */ + + + addLogoutListener(_fn) {} + + isDeviceSignedIn() { + return false; + } + /** + * @returns {Promise} + */ + + + async getAlias() { + return null; + } // PM endpoints + + + storeCredentials(_opts) {} + + getAccounts() {} + /** @returns {APIResponse} */ + + + getAutofillCredentials(_id) { + throw new Error('unimplemented'); + } + /** @returns {APIResponse} */ + + + async getAutofillCreditCard(_id) { + throw new Error('unimplemented'); + } + /** @returns {Promise<{success: IdentityObject|undefined}>} */ + + + async getAutofillIdentity(_id) { + throw new Error('unimplemented'); + } + + openManagePasswords() {} + /** @param {FeatureToggleNames} _name */ + + + supportsFeature(_name) { + return false; + } + +} + +module.exports = InterfacePrototype; + +},{"../Form/formatters":15,"../Form/inputTypeConfig":17,"../Form/listenForFormSubmission":19,"../Form/matching":22,"../InputTypes/Credentials":25,"../PasswordGenerator":28,"../UI/DataAutofill":29,"../UI/EmailAutofill":30,"../autofill-utils":36,"../scanForInputs":40}],12:[function(require,module,exports){ +"use strict"; + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +const FormAnalyzer = require('./FormAnalyzer'); + +const { + addInlineStyles, + removeInlineStyles, + setValue, + isEventWithinDax, + isMobileApp, + isApp, + getDaxBoundingBox +} = require('../autofill-utils'); + +const { + getInputSubtype, + getInputMainType +} = require('./matching'); + +const { + getIconStylesAutofilled, + getIconStylesBase +} = require('./inputStyles'); + +const { + ATTR_AUTOFILL +} = require('../constants'); + +const { + getInputConfig +} = require('./inputTypeConfig.js'); + +const { + getUnifiedExpiryDate, + formatCCYear, + getCountryName +} = require('./formatters'); + +const { + Matching +} = require('./matching'); + +const { + matchingConfiguration +} = require('./matching-configuration'); + +class Form { + /** @type {import("./matching").Matching} */ + + /** @type {HTMLFormElement} */ + + /** @type {HTMLInputElement | null} */ + + /** @type {boolean | null} */ + + /** + * @param {HTMLFormElement} form + * @param {HTMLInputElement|HTMLSelectElement} input + * @param {import("../DeviceInterface/InterfacePrototype")} deviceInterface + * @param {Matching} [matching] + */ + constructor(form, input, deviceInterface, matching) { + _defineProperty(this, "matching", void 0); + + _defineProperty(this, "form", void 0); + + _defineProperty(this, "activeInput", void 0); + + _defineProperty(this, "isSignup", void 0); + + this.form = form; + this.matching = matching || new Matching(matchingConfiguration); + this.formAnalyzer = new FormAnalyzer(form, input, matching); + this.isLogin = this.formAnalyzer.isLogin; + this.isSignup = this.formAnalyzer.isSignup; + this.device = deviceInterface; + /** @type Record<'all' | SupportedMainTypes, Set> */ + + this.inputs = { + all: new Set(), + credentials: new Set(), + creditCard: new Set(), + identities: new Set(), + unknown: new Set() + }; + this.touched = new Set(); + this.listeners = new Set(); + this.activeInput = null; // We set this to true to skip event listeners while we're autofilling + + this.isAutofilling = false; + this.handlerExecuted = false; + this.shouldPromptToStoreCredentials = true; + /** + * @type {IntersectionObserver | null} + */ + + this.intObs = new IntersectionObserver(entries => { + for (const entry of entries) { + if (!entry.isIntersecting) this.removeTooltip(); + } + }); + this.categorizeInputs(); + } + + submitHandler() { + if (this.handlerExecuted) return; + const credentials = this.getValues(); // do nothing if password was absent + + if (!credentials.password) return; // checks to determine if we should offer to store credentials and/or fireproof + + const checks = [this.shouldPromptToStoreCredentials, this.device.shouldPromptToStoreCredentials({ + formElement: this.form + })]; // if *any* of the checks are truthy, proceed to offer + + if (checks.some(Boolean)) { + this.device.storeCredentials(credentials); + } // mark this form as being handled + // TODO(Shane): is this correct, what happens if a failed submission is retried? + + + this.handlerExecuted = true; + } + + getValues() { + const credentials = [...this.inputs.credentials, ...this.inputs.identities].reduce((output, input) => { + const subtype = getInputSubtype(input); + + if (['username', 'password', 'emailAddress'].includes(subtype)) { + output[subtype] = input.value || output[subtype]; + } + + return output; + }, { + username: '', + password: '' + }); // If we don't have a username, let's try and save the email if available. + + if (credentials.emailAddress && !credentials.username) { + credentials.username = credentials.emailAddress; + } + + delete credentials.emailAddress; + return credentials; + } + + hasValues() { + const { + password + } = this.getValues(); + return !!password; + } + + removeTooltip() { + var _this$intObs; + + const tooltip = this.device.getActiveTooltip(); + + if (this.isAutofilling || !tooltip) { + return; + } + + this.device.removeTooltip(); + (_this$intObs = this.intObs) === null || _this$intObs === void 0 ? void 0 : _this$intObs.disconnect(); + } + + showingTooltip(input) { + var _this$intObs2; + + (_this$intObs2 = this.intObs) === null || _this$intObs2 === void 0 ? void 0 : _this$intObs2.observe(input); + } + + removeInputHighlight(input) { + removeInlineStyles(input, getIconStylesAutofilled(input, this)); + input.classList.remove('ddg-autofilled'); + this.addAutofillStyles(input); + } + + removeAllHighlights(e, dataType) { + // This ensures we are not removing the highlight ourselves when autofilling more than once + if (e && !e.isTrusted) return; // If the user has changed the value, we prompt to update the stored creds + + this.shouldPromptToStoreCredentials = true; + this.execOnInputs(input => this.removeInputHighlight(input), dataType); + } + + removeInputDecoration(input) { + removeInlineStyles(input, getIconStylesBase(input, this)); + input.removeAttribute(ATTR_AUTOFILL); + } + + removeAllDecorations() { + this.execOnInputs(input => this.removeInputDecoration(input)); + this.listeners.forEach(_ref => { + let { + el, + type, + fn + } = _ref; + return el.removeEventListener(type, fn); + }); + } + + redecorateAllInputs() { + this.removeAllDecorations(); + this.execOnInputs(input => this.decorateInput(input)); + } + + resetAllInputs() { + this.execOnInputs(input => { + setValue(input, ''); + this.removeInputHighlight(input); + }); + if (this.activeInput) this.activeInput.focus(); + } + + dismissTooltip() { + this.removeTooltip(); + } // This removes all listeners to avoid memory leaks and weird behaviours + + + destroy() { + this.removeAllDecorations(); + this.removeTooltip(); + this.intObs = null; + } + + categorizeInputs() { + const selector = this.matching.cssSelector('FORM_INPUTS_SELECTOR'); + this.form.querySelectorAll(selector).forEach(input => this.addInput(input)); + } + + get submitButtons() { + const selector = this.matching.cssSelector('SUBMIT_BUTTON_SELECTOR'); + return [...this.form.querySelectorAll(selector)].filter(button => { + const content = button.textContent || ''; + const ariaLabel = button.getAttribute('aria-label') || ''; // @ts-ignore + + const title = button.title || ''; // trying to exclude the little buttons to show and hide passwords + + return !/password|show|toggle|reveal|hide/i.test(content + ariaLabel + title); + }); + } + + execOnInputs(fn) { + let inputType = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'all'; + const inputs = this.inputs[inputType]; + + for (const input of inputs) { + const { + shouldDecorate + } = getInputConfig(input); + if (shouldDecorate(input, this)) fn(input); + } + } + + addInput(input) { + if (this.inputs.all.has(input)) return this; + this.inputs.all.add(input); + this.matching.setInputType(input, this.form, { + isLogin: this.isLogin + }); + const mainInputType = getInputMainType(input); + this.inputs[mainInputType].add(input); + this.decorateInput(input); + return this; + } + + areAllInputsEmpty(inputType) { + let allEmpty = true; + this.execOnInputs(input => { + if (input.value) allEmpty = false; + }, inputType); + return allEmpty; + } + + addListener(el, type, fn) { + el.addEventListener(type, fn); + this.listeners.add({ + el, + type, + fn + }); + } + + addAutofillStyles(input) { + const styles = getIconStylesBase(input, this); + addInlineStyles(input, styles); + } + + decorateInput(input) { + const config = getInputConfig(input); + if (!config.shouldDecorate(input, this)) return this; + input.setAttribute(ATTR_AUTOFILL, 'true'); + const hasIcon = !!config.getIconBase(input, this); + + if (hasIcon) { + this.addAutofillStyles(input); + this.addListener(input, 'mousemove', e => { + if (isEventWithinDax(e, e.target)) { + e.target.style.setProperty('cursor', 'pointer', 'important'); + } else { + e.target.style.removeProperty('cursor'); + } + }); + } + + function getMainClickCoords(e) { + if (!e.isTrusted) return; + const isMainMouseButton = e.button === 0; + if (!isMainMouseButton) return; + return { + x: e.clientX, + y: e.clientY + }; + } // Store the click to a label so we can use the click when the field is focused + + + let storedClick = new WeakMap(); + let timeout = null; + + const handlerLabel = e => { + // Look for e.target OR it's closest parent to be a HTMLLabelElement + const control = e.target.closest('label').control; + if (!control) return; + storedClick.set(control, getMainClickCoords(e)); + clearTimeout(timeout); // Remove the stored click if the timer expires + + timeout = setTimeout(() => { + storedClick = new WeakMap(); + }, 1000); + }; + + const handler = e => { + if (this.device.getActiveTooltip() || this.isAutofilling) return; + const input = e.target; + let click = null; + + const getPosition = () => { + // In extensions, the tooltip is centered on the Dax icon + return isApp ? input.getBoundingClientRect() : getDaxBoundingBox(input); + }; // Checks for mousedown event + + + if (e.type === 'pointerdown') { + click = getMainClickCoords(e); + if (!click) return; + } else if (storedClick) { + // Reuse a previous click if one exists for this element + click = storedClick.get(input); + storedClick.delete(input); + } + + if (this.shouldOpenTooltip(e, input)) { + if (isEventWithinDax(e, input) || isMobileApp) { + e.preventDefault(); + e.stopImmediatePropagation(); + } + + this.touched.add(input); + this.device.attachTooltip(this, input, getPosition, click); + } + }; + + if (input.nodeName !== 'SELECT') { + const events = ['pointerdown']; + if (!isMobileApp) events.push('focus'); + input.labels.forEach(label => { + this.addListener(label, 'pointerdown', handlerLabel); + }); + events.forEach(ev => this.addListener(input, ev, handler)); + } + + return this; + } + + shouldOpenTooltip(e, input) { + if (isApp) return true; + const inputType = getInputMainType(input); + return !this.touched.has(input) && this.areAllInputsEmpty(inputType) || isEventWithinDax(e, input); + } + + autofillInput(input, string, dataType) { + // @ts-ignore + const activeInputSubtype = getInputSubtype(this.activeInput); + const inputSubtype = getInputSubtype(input); + const isEmailAutofill = activeInputSubtype === 'emailAddress' && inputSubtype === 'emailAddress'; // Don't override values for identities, unless it's the current input or we're autofilling email + + if (dataType === 'identities' && // only for identities + input.nodeName !== 'SELECT' && input.value !== '' && // if the input is not empty + this.activeInput !== input && // and this is not the active input + !isEmailAutofill // and we're not auto-filling email + ) return; // do not overwrite the value + + const successful = setValue(input, string); + if (!successful) return; + input.classList.add('ddg-autofilled'); + addInlineStyles(input, getIconStylesAutofilled(input, this)); // If the user changes the value, remove the decoration + + input.addEventListener('input', e => this.removeAllHighlights(e, dataType), { + once: true + }); + } + + autofillEmail(alias) { + let dataType = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'identities'; + this.isAutofilling = true; + this.execOnInputs(input => this.autofillInput(input, alias, dataType), dataType); + this.isAutofilling = false; + this.removeTooltip(); + } + + autofillData(data, dataType) { + this.shouldPromptToStoreCredentials = false; + this.isAutofilling = true; + this.execOnInputs(input => { + const inputSubtype = getInputSubtype(input); + let autofillData = data[inputSubtype]; + + if (inputSubtype === 'expiration') { + autofillData = getUnifiedExpiryDate(input, data.expirationMonth, data.expirationYear, this); + } + + if (inputSubtype === 'expirationYear' && input.nodeName === 'INPUT') { + autofillData = formatCCYear(input, autofillData, this); + } + + if (inputSubtype === 'addressCountryCode') { + autofillData = getCountryName(input, data); + } + + if (autofillData) this.autofillInput(input, autofillData, dataType); + }, dataType); + this.isAutofilling = false; + this.removeTooltip(); + } + +} + +module.exports.Form = Form; + +},{"../autofill-utils":36,"../constants":38,"./FormAnalyzer":13,"./formatters":15,"./inputStyles":16,"./inputTypeConfig.js":17,"./matching":22,"./matching-configuration":21}],13:[function(require,module,exports){ +"use strict"; + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +const { + removeExcessWhitespace, + Matching +} = require('./matching'); + +const { + TEXT_LENGTH_CUTOFF +} = require('../constants'); + +const { + matchingConfiguration +} = require('./matching-configuration'); + +class FormAnalyzer { + /** @type HTMLFormElement */ + + /** @type Matching */ + + /** + * @param {HTMLFormElement} form + * @param {HTMLInputElement|HTMLSelectElement} input + * @param {Matching} [matching] + */ + constructor(form, input, matching) { + _defineProperty(this, "form", void 0); + + _defineProperty(this, "matching", void 0); + + this.form = form; + this.matching = matching || new Matching(matchingConfiguration); + this.autofillSignal = 0; + this.signals = []; // Avoid autofill on our signup page + + if (window.location.href.match(/^https:\/\/(.+\.)?duckduckgo\.com\/email\/choose-address/i)) { + return this; + } + + this.evaluateElAttributes(input, 3, true); + form ? this.evaluateForm() : this.evaluatePage(); + return this; + } + + get isLogin() { + return this.autofillSignal < 0; + } + + get isSignup() { + return this.autofillSignal >= 0; + } + + increaseSignalBy(strength, signal) { + this.autofillSignal += strength; + this.signals.push("".concat(signal, ": +").concat(strength)); + return this; + } + + decreaseSignalBy(strength, signal) { + this.autofillSignal -= strength; + this.signals.push("".concat(signal, ": -").concat(strength)); + return this; + } + + updateSignal(_ref) { + let { + string, + // The string to check + strength, + // Strength of the signal + signalType = 'generic', + // For debugging purposes, we give a name to the signal + shouldFlip = false, + // Flips the signals, i.e. when a link points outside. See below + shouldCheckUnifiedForm = false, + // Should check for login/signup forms + shouldBeConservative = false // Should use the conservative signup regex + + } = _ref; + const negativeRegex = new RegExp(/sign(ing)?.?in(?!g)|log.?in|unsubscri/i); + const positiveRegex = new RegExp(/sign(ing)?.?up|join|\bregist(er|ration)|newsletter|\bsubscri(be|ption)|contact|create|start|settings|preferences|profile|update|checkout|guest|purchase|buy|order|schedule|estimate|request/i); + const conservativePositiveRegex = new RegExp(/sign.?up|join|register|newsletter|subscri(be|ption)|settings|preferences|profile|update/i); + const strictPositiveRegex = new RegExp(/sign.?up|join|register|settings|preferences|profile|update/i); + const matchesNegative = string === 'current-password' || string.match(negativeRegex); // Check explicitly for unified login/signup forms. They should always be negative, so we increase signal + + if (shouldCheckUnifiedForm && matchesNegative && string.match(strictPositiveRegex)) { + this.decreaseSignalBy(strength + 2, "Unified detected ".concat(signalType)); + return this; + } + + const matchesPositive = string === 'new-password' || string.match(shouldBeConservative ? conservativePositiveRegex : positiveRegex); // In some cases a login match means the login is somewhere else, i.e. when a link points outside + + if (shouldFlip) { + if (matchesNegative) this.increaseSignalBy(strength, signalType); + if (matchesPositive) this.decreaseSignalBy(strength, signalType); + } else { + if (matchesNegative) this.decreaseSignalBy(strength, signalType); + if (matchesPositive) this.increaseSignalBy(strength, signalType); + } + + return this; + } + + evaluateElAttributes(el) { + let signalStrength = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 3; + let isInput = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + Array.from(el.attributes).forEach(attr => { + if (attr.name === 'style') return; + const attributeString = "".concat(attr.name, "=").concat(attr.value); + this.updateSignal({ + string: attributeString, + strength: signalStrength, + signalType: "".concat(el.name, " attr: ").concat(attributeString), + shouldCheckUnifiedForm: isInput + }); + }); + } + + evaluatePageTitle() { + const pageTitle = document.title; + this.updateSignal({ + string: pageTitle, + strength: 2, + signalType: "page title: ".concat(pageTitle) + }); + } + + evaluatePageHeadings() { + const headings = document.querySelectorAll('h1, h2, h3, [class*="title"], [id*="title"]'); + + if (headings) { + headings.forEach(_ref2 => { + let { + textContent + } = _ref2; + textContent = removeExcessWhitespace(textContent || ''); + this.updateSignal({ + string: textContent, + strength: 0.5, + signalType: "heading: ".concat(textContent), + shouldCheckUnifiedForm: true, + shouldBeConservative: true + }); + }); + } + } + + evaluatePage() { + this.evaluatePageTitle(); + this.evaluatePageHeadings(); // Check for submit buttons + + const buttons = document.querySelectorAll("\n button[type=submit],\n button:not([type]),\n [role=button]\n "); + buttons.forEach(button => { + // if the button has a form, it's not related to our input, because our input has no form here + if (button instanceof HTMLButtonElement) { + if (!button.form && !button.closest('form')) { + this.evaluateElement(button); + this.evaluateElAttributes(button, 0.5); + } + } + }); + } + + elementIs(el, type) { + return el.nodeName.toLowerCase() === type.toLowerCase(); + } + + getText(el) { + // for buttons, we don't care about descendants, just get the whole text as is + // this is important in order to give proper attribution of the text to the button + if (this.elementIs(el, 'BUTTON')) return removeExcessWhitespace(el.textContent); + if (this.elementIs(el, 'INPUT') && ['submit', 'button'].includes(el.type)) return el.value; + return removeExcessWhitespace(Array.from(el.childNodes).reduce((text, child) => this.elementIs(child, '#text') ? text + ' ' + child.textContent : text, '')); + } + + evaluateElement(el) { + const string = this.getText(el); + + if (el.matches(this.matching.cssSelector('password'))) { + // These are explicit signals by the web author, so we weigh them heavily + this.updateSignal({ + string: el.getAttribute('autocomplete') || '', + strength: 20, + signalType: "explicit: ".concat(el.getAttribute('autocomplete')) + }); + } // check button contents + + + if (el.matches(this.matching.cssSelector('SUBMIT_BUTTON_SELECTOR'))) { + // If we're sure this is a submit button, it's a stronger signal + const strength = el.getAttribute('type') === 'submit' || /primary|submit/i.test(el.className) || el.offsetHeight * el.offsetWidth >= 10000 ? 20 : 2; + this.updateSignal({ + string, + strength, + signalType: "submit: ".concat(string) + }); + } // if a link points to relevant urls or contain contents outside the page… + + + if (this.elementIs(el, 'A') && el.href && el.href !== '#' || (el.getAttribute('role') || '').toUpperCase() === 'LINK') { + // …and matches one of the regexes, we assume the match is not pertinent to the current form + this.updateSignal({ + string, + strength: 1, + signalType: "external link: ".concat(string), + shouldFlip: true + }); + } else { + var _removeExcessWhitespa; + + // any other case + // only consider the el if it's a small text to avoid noisy disclaimers + if (((_removeExcessWhitespa = removeExcessWhitespace(el.textContent)) === null || _removeExcessWhitespa === void 0 ? void 0 : _removeExcessWhitespa.length) < TEXT_LENGTH_CUTOFF) { + this.updateSignal({ + string, + strength: 1, + signalType: "generic: ".concat(string), + shouldCheckUnifiedForm: true + }); + } + } + } + + evaluateForm() { + // Check page title + this.evaluatePageTitle(); // Check form attributes + + this.evaluateElAttributes(this.form); // Check form contents (skip select and option because they contain too much noise) + + this.form.querySelectorAll('*:not(select):not(option)').forEach(el => { + // Check if element is not hidden. Note that we can't use offsetHeight + // nor intersectionObserver, because the element could be outside the + // viewport or its parent hidden + const displayValue = window.getComputedStyle(el, null).getPropertyValue('display'); + if (displayValue !== 'none') this.evaluateElement(el); + }); // If we can't decide at this point, try reading page headings + + if (this.autofillSignal === 0) { + this.evaluatePageHeadings(); + } + + return this; + } + +} + +module.exports = FormAnalyzer; + +},{"../constants":38,"./matching":22,"./matching-configuration":21}],14:[function(require,module,exports){ +"use strict"; + +// Country names object using 2-letter country codes to reference country name +// ISO 3166 Alpha-2 Format: [2 letter Country Code]: [Country Name] +// Sorted alphabetical by country name (special characters on bottom) +// Source: https://gist.github.com/incredimike/1469814#file-variouscountrylistformats-js-L272 +module.exports = { + 'AF': 'Afghanistan', + 'AL': 'Albania', + 'DZ': 'Algeria', + 'AS': 'American Samoa', + 'AD': 'Andorra', + 'AO': 'Angola', + 'AI': 'Anguilla', + 'AQ': 'Antarctica', + 'AG': 'Antigua and Barbuda', + 'AR': 'Argentina', + 'AM': 'Armenia', + 'AW': 'Aruba', + 'AU': 'Australia', + 'AT': 'Austria', + 'AZ': 'Azerbaijan', + 'BS': 'Bahamas (the)', + 'BH': 'Bahrain', + 'BD': 'Bangladesh', + 'BB': 'Barbados', + 'BY': 'Belarus', + 'BE': 'Belgium', + 'BZ': 'Belize', + 'BJ': 'Benin', + 'BM': 'Bermuda', + 'BT': 'Bhutan', + 'BO': 'Bolivia (Plurinational State of)', + 'BQ': 'Bonaire, Sint Eustatius and Saba', + 'BA': 'Bosnia and Herzegovina', + 'BW': 'Botswana', + 'BV': 'Bouvet Island', + 'BR': 'Brazil', + 'IO': 'British Indian Ocean Territory (the)', + 'BN': 'Brunei Darussalam', + 'BG': 'Bulgaria', + 'BF': 'Burkina Faso', + 'BI': 'Burundi', + 'CV': 'Cabo Verde', + 'KH': 'Cambodia', + 'CM': 'Cameroon', + 'CA': 'Canada', + 'KY': 'Cayman Islands (the)', + 'CF': 'Central African Republic (the)', + 'TD': 'Chad', + 'CL': 'Chile', + 'CN': 'China', + 'CX': 'Christmas Island', + 'CC': 'Cocos (Keeling) Islands (the)', + 'CO': 'Colombia', + 'KM': 'Comoros (the)', + 'CD': 'Congo (the Democratic Republic of the)', + 'CG': 'Congo (the)', + 'CK': 'Cook Islands (the)', + 'CR': 'Costa Rica', + 'HR': 'Croatia', + 'CU': 'Cuba', + 'CW': 'Curaçao', + 'CY': 'Cyprus', + 'CZ': 'Czechia', + 'CI': "Côte d'Ivoire", + 'DK': 'Denmark', + 'DJ': 'Djibouti', + 'DM': 'Dominica', + 'DO': 'Dominican Republic (the)', + 'EC': 'Ecuador', + 'EG': 'Egypt', + 'SV': 'El Salvador', + 'GQ': 'Equatorial Guinea', + 'ER': 'Eritrea', + 'EE': 'Estonia', + 'SZ': 'Eswatini', + 'ET': 'Ethiopia', + 'FK': 'Falkland Islands (the) [Malvinas]', + 'FO': 'Faroe Islands (the)', + 'FJ': 'Fiji', + 'FI': 'Finland', + 'FR': 'France', + 'GF': 'French Guiana', + 'PF': 'French Polynesia', + 'TF': 'French Southern Territories (the)', + 'GA': 'Gabon', + 'GM': 'Gambia (the)', + 'GE': 'Georgia', + 'DE': 'Germany', + 'GH': 'Ghana', + 'GI': 'Gibraltar', + 'GR': 'Greece', + 'GL': 'Greenland', + 'GD': 'Grenada', + 'GP': 'Guadeloupe', + 'GU': 'Guam', + 'GT': 'Guatemala', + 'GG': 'Guernsey', + 'GN': 'Guinea', + 'GW': 'Guinea-Bissau', + 'GY': 'Guyana', + 'HT': 'Haiti', + 'HM': 'Heard Island and McDonald Islands', + 'VA': 'Holy See (the)', + 'HN': 'Honduras', + 'HK': 'Hong Kong', + 'HU': 'Hungary', + 'IS': 'Iceland', + 'IN': 'India', + 'ID': 'Indonesia', + 'IR': 'Iran (Islamic Republic of)', + 'IQ': 'Iraq', + 'IE': 'Ireland', + 'IM': 'Isle of Man', + 'IL': 'Israel', + 'IT': 'Italy', + 'JM': 'Jamaica', + 'JP': 'Japan', + 'JE': 'Jersey', + 'JO': 'Jordan', + 'KZ': 'Kazakhstan', + 'KE': 'Kenya', + 'KI': 'Kiribati', + 'KP': "Korea (the Democratic People's Republic of)", + 'KR': 'Korea (the Republic of)', + 'KW': 'Kuwait', + 'KG': 'Kyrgyzstan', + 'LA': "Lao People's Democratic Republic (the)", + 'LV': 'Latvia', + 'LB': 'Lebanon', + 'LS': 'Lesotho', + 'LR': 'Liberia', + 'LY': 'Libya', + 'LI': 'Liechtenstein', + 'LT': 'Lithuania', + 'LU': 'Luxembourg', + 'MO': 'Macao', + 'MG': 'Madagascar', + 'MW': 'Malawi', + 'MY': 'Malaysia', + 'MV': 'Maldives', + 'ML': 'Mali', + 'MT': 'Malta', + 'MH': 'Marshall Islands (the)', + 'MQ': 'Martinique', + 'MR': 'Mauritania', + 'MU': 'Mauritius', + 'YT': 'Mayotte', + 'MX': 'Mexico', + 'FM': 'Micronesia (Federated States of)', + 'MD': 'Moldova (the Republic of)', + 'MC': 'Monaco', + 'MN': 'Mongolia', + 'ME': 'Montenegro', + 'MS': 'Montserrat', + 'MA': 'Morocco', + 'MZ': 'Mozambique', + 'MM': 'Myanmar', + 'NA': 'Namibia', + 'NR': 'Nauru', + 'NP': 'Nepal', + 'NL': 'Netherlands (the)', + 'NC': 'New Caledonia', + 'NZ': 'New Zealand', + 'NI': 'Nicaragua', + 'NE': 'Niger (the)', + 'NG': 'Nigeria', + 'NU': 'Niue', + 'NF': 'Norfolk Island', + 'MP': 'Northern Mariana Islands (the)', + 'NO': 'Norway', + 'OM': 'Oman', + 'PK': 'Pakistan', + 'PW': 'Palau', + 'PS': 'Palestine, State of', + 'PA': 'Panama', + 'PG': 'Papua New Guinea', + 'PY': 'Paraguay', + 'PE': 'Peru', + 'PH': 'Philippines (the)', + 'PN': 'Pitcairn', + 'PL': 'Poland', + 'PT': 'Portugal', + 'PR': 'Puerto Rico', + 'QA': 'Qatar', + 'MK': 'Republic of North Macedonia', + 'RO': 'Romania', + 'RU': 'Russian Federation (the)', + 'RW': 'Rwanda', + 'RE': 'Réunion', + 'BL': 'Saint Barthélemy', + 'SH': 'Saint Helena, Ascension and Tristan da Cunha', + 'KN': 'Saint Kitts and Nevis', + 'LC': 'Saint Lucia', + 'MF': 'Saint Martin (French part)', + 'PM': 'Saint Pierre and Miquelon', + 'VC': 'Saint Vincent and the Grenadines', + 'WS': 'Samoa', + 'SM': 'San Marino', + 'ST': 'Sao Tome and Principe', + 'SA': 'Saudi Arabia', + 'SN': 'Senegal', + 'RS': 'Serbia', + 'SC': 'Seychelles', + 'SL': 'Sierra Leone', + 'SG': 'Singapore', + 'SX': 'Sint Maarten (Dutch part)', + 'SK': 'Slovakia', + 'SI': 'Slovenia', + 'SB': 'Solomon Islands', + 'SO': 'Somalia', + 'ZA': 'South Africa', + 'GS': 'South Georgia and the South Sandwich Islands', + 'SS': 'South Sudan', + 'ES': 'Spain', + 'LK': 'Sri Lanka', + 'SD': 'Sudan (the)', + 'SR': 'Suriname', + 'SJ': 'Svalbard and Jan Mayen', + 'SE': 'Sweden', + 'CH': 'Switzerland', + 'SY': 'Syrian Arab Republic', + 'TW': 'Taiwan', + 'TJ': 'Tajikistan', + 'TZ': 'Tanzania, United Republic of', + 'TH': 'Thailand', + 'TL': 'Timor-Leste', + 'TG': 'Togo', + 'TK': 'Tokelau', + 'TO': 'Tonga', + 'TT': 'Trinidad and Tobago', + 'TN': 'Tunisia', + 'TR': 'Turkey', + 'TM': 'Turkmenistan', + 'TC': 'Turks and Caicos Islands (the)', + 'TV': 'Tuvalu', + 'UG': 'Uganda', + 'UA': 'Ukraine', + 'AE': 'United Arab Emirates (the)', + 'GB': 'United Kingdom of Great Britain and Northern Ireland (the)', + 'UM': 'United States Minor Outlying Islands (the)', + 'US': 'United States of America (the)', + 'UY': 'Uruguay', + 'UZ': 'Uzbekistan', + 'VU': 'Vanuatu', + 'VE': 'Venezuela (Bolivarian Republic of)', + 'VN': 'Viet Nam', + 'VG': 'Virgin Islands (British)', + 'VI': 'Virgin Islands (U.S.)', + 'WF': 'Wallis and Futuna', + 'EH': 'Western Sahara', + 'YE': 'Yemen', + 'ZM': 'Zambia', + 'ZW': 'Zimbabwe', + 'AX': 'Åland Islands' +}; + +},{}],15:[function(require,module,exports){ +"use strict"; + +var _templateObject, _templateObject2; + +function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); } + +const { + matchInPlaceholderAndLabels, + checkPlaceholderAndLabels +} = require('./matching'); + +const COUNTRY_NAMES = require('./countryNames'); // Matches strings like mm/yy, mm-yyyy, mm-aa + + +const DATE_SEPARATOR_REGEX = /\w\w\s?(?[/\s.\-_—–])\s?\w\w/i; // Matches 4 non-digit repeated characters (YYYY or AAAA) or 4 digits (2022) + +const FOUR_DIGIT_YEAR_REGEX = /(\D)\1{3}|\d{4}/i; +/** + * Format the cc year to best adapt to the input requirements (YY vs YYYY) + * @param {HTMLInputElement} input + * @param {number} year + * @param {import("./Form").Form} form + * @returns {number} + */ + +const formatCCYear = (input, year, form) => { + const selector = form.matching.cssSelector('FORM_INPUTS_SELECTOR'); + if (input.maxLength === 4 || checkPlaceholderAndLabels(input, FOUR_DIGIT_YEAR_REGEX, form.form, selector)) return year; + return year - 2000; +}; +/** + * Get a unified expiry date with separator + * @param {HTMLInputElement} input + * @param {number} month + * @param {number} year + * @param {import("./Form").Form} form + * @returns {string} + */ + + +const getUnifiedExpiryDate = (input, month, year, form) => { + var _matchInPlaceholderAn, _matchInPlaceholderAn2; + + const formattedYear = formatCCYear(input, year, form); + const paddedMonth = "".concat(month).padStart(2, '0'); + const cssSelector = form.matching.cssSelector('FORM_INPUTS_SELECTOR'); + const separator = ((_matchInPlaceholderAn = matchInPlaceholderAndLabels(input, DATE_SEPARATOR_REGEX, form.form, cssSelector)) === null || _matchInPlaceholderAn === void 0 ? void 0 : (_matchInPlaceholderAn2 = _matchInPlaceholderAn.groups) === null || _matchInPlaceholderAn2 === void 0 ? void 0 : _matchInPlaceholderAn2.separator) || '/'; + return "".concat(paddedMonth).concat(separator).concat(formattedYear); +}; + +const formatFullName = _ref => { + let { + firstName = '', + middleName = '', + lastName = '' + } = _ref; + return "".concat(firstName, " ").concat(middleName ? middleName + ' ' : '').concat(lastName).trim(); +}; +/** + * Tries to look up a human-readable country name from the country code + * @param {string} locale + * @param {string} addressCountryCode + * @return {string} - Returns the country code if we can't find a name + */ + + +const getCountryDisplayName = (locale, addressCountryCode) => { + try { + const regionNames = new Intl.DisplayNames([locale], { + type: 'region' + }); + return regionNames.of(addressCountryCode); + } catch (e) { + return COUNTRY_NAMES[addressCountryCode] || addressCountryCode; + } +}; +/** + * Tries to infer the element locale or returns 'en' + * @param {HTMLInputElement | HTMLSelectElement} el + * @return {string | 'en'} + */ + + +const inferElementLocale = el => { + var _el$form; + + return el.lang || ((_el$form = el.form) === null || _el$form === void 0 ? void 0 : _el$form.lang) || document.body.lang || document.documentElement.lang || 'en'; +}; +/** + * Tries to format the country code into a localised country name + * @param {HTMLInputElement | HTMLSelectElement} el + * @param {{addressCountryCode?: string}} options + */ + + +const getCountryName = function (el) { + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const { + addressCountryCode + } = options; + if (!addressCountryCode) return ''; // Try to infer the field language or fallback to en + + const elLocale = inferElementLocale(el); + const localisedCountryName = getCountryDisplayName(elLocale, addressCountryCode); // If it's a select el we try to find a suitable match to autofill + + if (el.nodeName === 'SELECT') { + const englishCountryName = getCountryDisplayName('en', addressCountryCode); // This regex matches both the localised and English country names + + const countryNameRegex = new RegExp(String.raw(_templateObject || (_templateObject = _taggedTemplateLiteral(["", "|", ""])), localisedCountryName.replaceAll(' ', '.?'), englishCountryName.replaceAll(' ', '.?')), 'i'); + const countryCodeRegex = new RegExp(String.raw(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\b", "\b"], ["\\b", "\\b"])), addressCountryCode), 'i'); // We check the country code first because it's more accurate + + if (el instanceof HTMLSelectElement) { + for (const option of el.options) { + if (countryCodeRegex.test(option.value)) { + return option.value; + } + } + + for (const option of el.options) { + if (countryNameRegex.test(option.value) || countryNameRegex.test(option.innerText)) return option.value; + } + } + } + + return localisedCountryName; +}; + +module.exports = { + formatCCYear, + getUnifiedExpiryDate, + formatFullName, + getCountryDisplayName, + getCountryName +}; + +},{"./countryNames":14,"./matching":22}],16:[function(require,module,exports){ +"use strict"; + +const { + getInputConfig +} = require('./inputTypeConfig.js'); +/** + * Returns the css-ready base64 encoding of the icon for the given input + * @param {HTMLInputElement} input + * @param {import("./Form").Form} form + * @param {'base' | 'filled'} type + * @return {string} + */ + + +const getIcon = function (input, form) { + let type = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'base'; + const config = getInputConfig(input); + + if (type === 'base') { + return config.getIconBase(input, form); + } + + if (type === 'filled') { + return config.getIconFilled(input, form); + } + + return ''; +}; +/** + * Returns an object with styles to be applied inline + * @param {HTMLInputElement} input + * @param {String} icon + * @return {Object} + */ + + +const getBasicStyles = (input, icon) => ({ + // Height must be > 0 to account for fields initially hidden + 'background-size': "auto ".concat(input.offsetHeight <= 30 && input.offsetHeight > 0 ? '100%' : '26px'), + 'background-position': 'center right', + 'background-repeat': 'no-repeat', + 'background-origin': 'content-box', + 'background-image': "url(".concat(icon, ")"), + 'transition': 'background 0s' +}); +/** + * Get inline styles for the injected icon, base state + * @param {HTMLInputElement} input + * @param {import("./Form").Form} form + * @return {Object} + */ - this._checkDeviceSignedIn = async () => { - const { - isAppSignedIn - } = await wkSendAndWait('emailHandlerCheckAppSignedInStatus'); - this.isDeviceSignedIn = () => !!isAppSignedIn; +const getIconStylesBase = (input, form) => { + const icon = getIcon(input, form); + if (!icon) return {}; + return getBasicStyles(input, icon); +}; +/** + * Get inline styles for the injected icon, autofilled state + * @param {HTMLInputElement} input + * @param {import("./Form").Form} form + * @return {Object} + */ - return !!isAppSignedIn; - }; - this.storeUserData = ({ - addUserData: { - token, - userName, - cohort +const getIconStylesAutofilled = (input, form) => { + const icon = getIcon(input, form, 'filled'); + const iconStyle = icon ? getBasicStyles(input, icon) : {}; + return { ...iconStyle, + 'background-color': '#F8F498', + 'color': '#333333' + }; +}; + +module.exports = { + getIconStylesBase, + getIconStylesAutofilled +}; + +},{"./inputTypeConfig.js":17}],17:[function(require,module,exports){ +"use strict"; + +const { + isDDGApp, + isApp +} = require('../autofill-utils'); + +const { + daxBase64 +} = require('./logo-svg'); + +const ddgPasswordIcons = require('../UI/img/ddgPasswordIcon'); + +const { + getInputType, + getMainTypeFromType, + getInputSubtype +} = require('./matching'); + +const { + CredentialsTooltipItem +} = require('../InputTypes/Credentials'); + +const { + CreditCardTooltipItem +} = require('../InputTypes/CreditCard'); + +const { + IdentityTooltipItem +} = require('../InputTypes/Identity'); // In Firefox web_accessible_resources could leak a unique user identifier, so we avoid it here + + +const isFirefox = navigator.userAgent.includes('Firefox'); +const getDaxImg = isDDGApp || isFirefox ? daxBase64 : chrome.runtime.getURL('img/logo-small.svg'); +/** + * Get the icon for the identities (currently only Dax for emails) + * @param {HTMLInputElement} input + * @param {import("./Form").Form} form + * @return {string} + */ + +const getIdentitiesIcon = (input, _ref) => { + let { + device + } = _ref; + const subtype = getInputSubtype(input); + if (subtype === 'emailAddress' && device.isDeviceSignedIn()) return getDaxImg; + return ''; +}; +/** + * A map of config objects. These help by centralising here some complexity + * @type {InputTypeConfig} + */ + + +const inputTypeConfig = { + /** @type {CredentialsInputTypeConfig} */ + credentials: { + type: 'credentials', + getIconBase: () => ddgPasswordIcons.ddgPasswordIconBase, + getIconFilled: () => ddgPasswordIcons.ddgPasswordIconFilled, + shouldDecorate: (input, _ref2) => { + let { + isLogin, + device + } = _ref2; + + // if we are on a 'login' page, continue to use old logic, eg: just checking if there's a + // saved password + if (isLogin) { + return device.hasLocalCredentials; + } // at this point, it's not a 'login' attempt, so we could offer to provide a password? + + + if (device.supportsFeature('password.generation')) { + const subtype = getInputSubtype(input); + + if (subtype === 'password') { + return true; + } } - }) => wkSend('emailHandlerStoreToken', { - token, - username: userName, - cohort + + return false; + }, + dataType: 'Credentials', + tooltipItem: data => new CredentialsTooltipItem(data) + }, + + /** @type {CreditCardInputTypeConfig} */ + creditCard: { + type: 'creditCard', + getIconBase: () => '', + getIconFilled: () => '', + shouldDecorate: (_input, _ref3) => { + let { + device + } = _ref3; + return device.hasLocalCreditCards; + }, + dataType: 'CreditCards', + tooltipItem: data => new CreditCardTooltipItem(data) + }, + + /** @type {IdentitiesInputTypeConfig} */ + identities: { + type: 'identities', + getIconBase: getIdentitiesIcon, + getIconFilled: getIdentitiesIcon, + shouldDecorate: (input, _ref4) => { + let { + device + } = _ref4; + const subtype = getInputSubtype(input); + + if (isApp) { + var _device$getLocalIdent; + + return Boolean((_device$getLocalIdent = device.getLocalIdentities()) === null || _device$getLocalIdent === void 0 ? void 0 : _device$getLocalIdent.some(identity => !!identity[subtype])); + } + + if (subtype === 'emailAddress') { + return Boolean(device.isDeviceSignedIn()); + } + + return false; + }, + dataType: 'Identities', + tooltipItem: data => new IdentityTooltipItem(data) + }, + + /** @type {UnknownInputTypeConfig} */ + unknown: { + type: 'unknown', + getIconBase: () => '', + getIconFilled: () => '', + shouldDecorate: () => false, + dataType: '', + tooltipItem: _data => { + throw new Error('unreachable'); + } + } +}; +/** + * Retrieves configs from an input el + * @param {HTMLInputElement} input + * @returns {InputTypeConfigs} + */ + +const getInputConfig = input => { + const inputType = getInputType(input); + return getInputConfigFromType(inputType); +}; +/** + * Retrieves configs from an input type + * @param {import('./matching').SupportedTypes | string} inputType + * @returns {InputTypeConfigs} + */ + + +const getInputConfigFromType = inputType => { + const inputMainType = getMainTypeFromType(inputType); + return inputTypeConfig[inputMainType]; +}; + +module.exports = { + getInputConfig, + getInputConfigFromType +}; + +},{"../InputTypes/Credentials":25,"../InputTypes/CreditCard":26,"../InputTypes/Identity":27,"../UI/img/ddgPasswordIcon":32,"../autofill-utils":36,"./logo-svg":20,"./matching":22}],18:[function(require,module,exports){ +"use strict"; + +const EXCLUDED_TAGS = ['SCRIPT', 'NOSCRIPT', 'OPTION', 'STYLE']; +/** + * Extract all strings of an element's children to an array. + * "element.textContent" is a string which is merged of all children nodes, + * which can cause issues with things like script tags etc. + * + * @param {HTMLElement} element + * A DOM element to be extracted. + * @returns {string[]} + * All strings in an element. + */ + +const extractLabelStrings = element => { + const strings = []; + + const _extractLabelStrings = el => { + if (EXCLUDED_TAGS.includes(el.tagName)) { + return; + } // only take the string when it's an explicit text node + + + if (el.nodeType === el.TEXT_NODE || !el.childNodes.length) { + let trimmedText = el.textContent.trim(); + + if (trimmedText) { + strings.push(trimmedText); + } + + return; + } + + for (let node of el.childNodes) { + let nodeType = node.nodeType; + + if (nodeType !== node.ELEMENT_NODE && nodeType !== node.TEXT_NODE) { + continue; + } + + _extractLabelStrings(node); + } + }; + + _extractLabelStrings(element); + + return strings; +}; + +module.exports.extractLabelStrings = extractLabelStrings; + +},{}],19:[function(require,module,exports){ +"use strict"; + +const { + forms +} = require('../scanForInputs'); + +const isApp = require('../autofill-utils'); + +const listenForGlobalFormSubmission = () => { + if (!isApp) return; + + try { + window.addEventListener('submit', e => { + var _forms$get; + + return (// @ts-ignore + (_forms$get = forms.get(e.target)) === null || _forms$get === void 0 ? void 0 : _forms$get.submitHandler() + ); + }, true); + const observer = new PerformanceObserver(list => { + const entries = list.getEntries().filter(entry => // @ts-ignore why does TS not know about `entry.initiatorType`? + ['fetch', 'xmlhttprequest'].includes(entry.initiatorType) && entry.name.match(/login|sign-in|signin|session/)); + if (!entries.length) return; + const filledForm = [...forms.values()].find(form => form.hasValues()); + filledForm === null || filledForm === void 0 ? void 0 : filledForm.submitHandler(); + }); + observer.observe({ + entryTypes: ['resource'] }); + } catch (error) {// Unable to detect form submissions using AJAX calls + } +}; + +module.exports = listenForGlobalFormSubmission; + +},{"../autofill-utils":36,"../scanForInputs":40}],20:[function(require,module,exports){ +"use strict"; + +const daxBase64 = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgNDQgNDQiIHdpZHRoPSIyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+PGxpbmVhckdyYWRpZW50IGlkPSJhIj48c3RvcCBvZmZzZXQ9Ii4wMSIgc3RvcC1jb2xvcj0iIzYxNzZiOSIvPjxzdG9wIG9mZnNldD0iLjY5IiBzdG9wLWNvbG9yPSIjMzk0YTlmIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImIiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMTMuOTI5NyIgeDI9IjE3LjA3MiIgeGxpbms6aHJlZj0iI2EiIHkxPSIxNi4zOTgiIHkyPSIxNi4zOTgiLz48bGluZWFyR3JhZGllbnQgaWQ9ImMiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMjMuODExNSIgeDI9IjI2LjY3NTIiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMTQuOTY3OSIgeTI9IjE0Ljk2NzkiLz48bWFzayBpZD0iZCIgaGVpZ2h0PSI0MCIgbWFza1VuaXRzPSJ1c2VyU3BhY2VPblVzZSIgd2lkdGg9IjQwIiB4PSIyIiB5PSIyIj48cGF0aCBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Im0yMi4wMDAzIDQxLjA2NjljMTAuNTMwMiAwIDE5LjA2NjYtOC41MzY0IDE5LjA2NjYtMTkuMDY2NiAwLTEwLjUzMDMtOC41MzY0LTE5LjA2NjcxLTE5LjA2NjYtMTkuMDY2NzEtMTAuNTMwMyAwLTE5LjA2NjcxIDguNTM2NDEtMTkuMDY2NzEgMTkuMDY2NzEgMCAxMC41MzAyIDguNTM2NDEgMTkuMDY2NiAxOS4wNjY3MSAxOS4wNjY2eiIgZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIi8+PC9tYXNrPjxwYXRoIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0ibTIyIDQ0YzEyLjE1MDMgMCAyMi05Ljg0OTcgMjItMjIgMC0xMi4xNTAyNi05Ljg0OTctMjItMjItMjItMTIuMTUwMjYgMC0yMiA5Ljg0OTc0LTIyIDIyIDAgMTIuMTUwMyA5Ljg0OTc0IDIyIDIyIDIyeiIgZmlsbD0iI2RlNTgzMyIgZmlsbC1ydWxlPSJldmVub2RkIi8+PGcgbWFzaz0idXJsKCNkKSI+PHBhdGggY2xpcC1ydWxlPSJldmVub2RkIiBkPSJtMjYuMDgxMyA0MS42Mzg2Yy0uOTIwMy0xLjc4OTMtMS44MDAzLTMuNDM1Ni0yLjM0NjYtNC41MjQ2LTEuNDUyLTIuOTA3Ny0yLjkxMTQtNy4wMDctMi4yNDc3LTkuNjUwNy4xMjEtLjQ4MDMtMS4zNjc3LTE3Ljc4Njk5LTIuNDItMTguMzQ0MzItMS4xNjk3LS42MjMzMy0zLjcxMDctMS40NDQ2Ny01LjAyNy0xLjY2NDY3LS45MTY3LS4xNDY2Ni0xLjEyNTcuMTEtMS41MTA3LjE2ODY3LjM2My4wMzY2NyAyLjA5Ljg4NzMzIDIuNDIzNy45MzUtLjMzMzcuMjI3MzMtMS4zMi0uMDA3MzMtMS45NTA3LjI3MTMzLS4zMTkuMTQ2NjctLjU1NzMuNjg5MzQtLjU1Ljk0NiAxLjc5NjctLjE4MzMzIDQuNjA1NC0uMDAzNjYgNi4yNy43MzMyOS0xLjMyMzYuMTUwNC0zLjMzMy4zMTktNC4xOTgzLjc3MzctMi41MDggMS4zMi0zLjYxNTMgNC40MTEtMi45NTUzIDguMTE0My42NTYzIDMuNjk2IDMuNTY0IDE3LjE3ODQgNC40OTE2IDIxLjY4MS45MjQgNC40OTkgMTEuNTUzNyAzLjU1NjcgMTAuMDE3NC41NjF6IiBmaWxsPSIjZDVkN2Q4IiBmaWxsLXJ1bGU9ImV2ZW5vZGQiLz48cGF0aCBkPSJtMjIuMjg2NSAyNi44NDM5Yy0uNjYgMi42NDM2Ljc5MiA2LjczOTMgMi4yNDc2IDkuNjUwNi40ODkxLjk3MjcgMS4yNDM4IDIuMzkyMSAyLjA1NTggMy45NjM3LTEuODk0LjQ2OTMtNi40ODk1IDEuMTI2NC05LjcxOTEgMC0uOTI0LTQuNDkxNy0zLjgzMTctMTcuOTc3Ny00LjQ5NTMtMjEuNjgxLS42Ni0zLjcwMzMgMC02LjM0NyAyLjUxNTMtNy42NjcuODYxNy0uNDU0NyAyLjA5MzctLjc4NDcgMy40MTM3LS45MzEzLTEuNjY0Ny0uNzQwNy0zLjYzNzQtMS4wMjY3LTUuNDQxNC0uODQzMzYtLjAwNzMtLjc2MjY3IDEuMzM4NC0uNzE4NjcgMS44NDQ0LTEuMDYzMzQtLjMzMzctLjA0NzY2LTEuMTYyNC0uNzk1NjYtMS41MjktLjgzMjMzIDIuMjg4My0uMzkyNDQgNC42NDIzLS4wMjEzOCA2LjY5OSAxLjA1NiAxLjA0ODYuNTYxIDEuNzg5MyAxLjE2MjMzIDIuMjQ3NiAxLjc5MzAzIDEuMTk1NC4yMjczIDIuMjUxNC42NiAyLjk0MDcgMS4zNDkzIDIuMTE5MyAyLjExNTcgNC4wMTEzIDYuOTUyIDMuMjE5MyA5LjczMTMtLjIyMzYuNzctLjczMzMgMS4zMzEtMS4zNzEzIDEuNzk2Ny0xLjIzOTMuOTAyLTEuMDE5My0xLjA0NS00LjEwMy45NzE3LS4zOTk3LjI2MDMtLjM5OTcgMi4yMjU2LS41MjQzIDIuNzA2eiIgZmlsbD0iI2ZmZiIvPjwvZz48ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCI+PHBhdGggZD0ibTE2LjY3MjQgMjAuMzU0Yy43Njc1IDAgMS4zODk2LS42MjIxIDEuMzg5Ni0xLjM4OTZzLS42MjIxLTEuMzg5Ny0xLjM4OTYtMS4zODk3LTEuMzg5Ny42MjIyLTEuMzg5NyAxLjM4OTcuNjIyMiAxLjM4OTYgMS4zODk3IDEuMzg5NnoiIGZpbGw9IiMyZDRmOGUiLz48cGF0aCBkPSJtMTcuMjkyNCAxOC44NjE3Yy4xOTg1IDAgLjM1OTQtLjE2MDguMzU5NC0uMzU5M3MtLjE2MDktLjM1OTMtLjM1OTQtLjM1OTNjLS4xOTg0IDAtLjM1OTMuMTYwOC0uMzU5My4zNTkzcy4xNjA5LjM1OTMuMzU5My4zNTkzeiIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Im0yNS45NTY4IDE5LjMzMTFjLjY1ODEgMCAxLjE5MTctLjUzMzUgMS4xOTE3LTEuMTkxNyAwLS42NTgxLS41MzM2LTEuMTkxNi0xLjE5MTctMS4xOTE2cy0xLjE5MTcuNTMzNS0xLjE5MTcgMS4xOTE2YzAgLjY1ODIuNTMzNiAxLjE5MTcgMS4xOTE3IDEuMTkxN3oiIGZpbGw9IiMyZDRmOGUiLz48cGF0aCBkPSJtMjYuNDg4MiAxOC4wNTExYy4xNzAxIDAgLjMwOC0uMTM3OS4zMDgtLjMwOHMtLjEzNzktLjMwOC0uMzA4LS4zMDgtLjMwOC4xMzc5LS4zMDguMzA4LjEzNzkuMzA4LjMwOC4zMDh6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTE3LjA3MiAxNC45NDJzLTEuMDQ4Ni0uNDc2Ni0yLjA2NDMuMTY1Yy0xLjAxNTcuNjM4LS45NzkgMS4yOTA3LS45NzkgMS4yOTA3cy0uNTM5LTEuMjAyNy44OTgzLTEuNzkzYzEuNDQxLS41ODY3IDIuMTQ1LjMzNzMgMi4xNDUuMzM3M3oiIGZpbGw9InVybCgjYikiLz48cGF0aCBkPSJtMjYuNjc1MiAxNC44NDY3cy0uNzUxNy0uNDI5LTEuMzM4My0uNDIxN2MtMS4xOTkuMDE0Ny0xLjUyNTQuNTQyNy0xLjUyNTQuNTQyN3MuMjAxNy0xLjI2MTQgMS43MzQ0LTEuMDA4NGMuNDk5Ny4wOTE0LjkyMjMuNDIzNCAxLjEyOTMuODg3NHoiIGZpbGw9InVybCgjYykiLz48cGF0aCBkPSJtMjAuOTI1OCAyNC4zMjFjLjEzOTMtLjg0MzMgMi4zMS0yLjQzMSAzLjg1LTIuNTMgMS41NC0uMDk1MyAyLjAxNjctLjA3MzMgMy4zLS4zODEzIDEuMjg3LS4zMDQzIDQuNTk4LTEuMTI5MyA1LjUxMS0xLjU1NDcuOTE2Ny0uNDIxNiA0LjgwMzMuMjA5IDIuMDY0MyAxLjczOC0xLjE4NDMuNjYzNy00LjM3OCAxLjg4MS02LjY2MjMgMi41NjMtMi4yODA3LjY4Mi0zLjY2My0uNjUyNi00LjQyMi40Njk0LS42MDEzLjg5MS0uMTIxIDIuMTEyIDIuNjAzMyAyLjM2NSAzLjY4MTQuMzQxIDcuMjA4Ny0xLjY1NzQgNy41OTc0LS41OTQuMzg4NiAxLjA2MzMtMy4xNjA3IDIuMzgzMy01LjMyNCAyLjQyNzMtMi4xNjM0LjA0MDMtNi41MTk0LTEuNDMtNy4xNzItMS44ODQ3LS42NTY0LS40NTEtMS41MjU0LTEuNTE0My0xLjM0NTctMi42MTh6IiBmaWxsPSIjZmRkMjBhIi8+PHBhdGggZD0ibTI4Ljg4MjUgMzEuODM4NmMtLjc3NzMtLjE3MjQtNC4zMTIgMi41MDA2LTQuMzEyIDIuNTAwNmguMDAzN2wtLjE2NSAyLjA1MzRzNC4wNDA2IDEuNjUzNiA0LjczIDEuMzk3Yy42ODkzLS4yNjQuNTE3LTUuNzc1LS4yNTY3LTUuOTUxem0tMTEuNTQ2MyAxLjAzNGMuMDg0My0xLjExODQgNS4yNTQzIDEuNjQyNiA1LjI1NDMgMS42NDI2bC4wMDM3LS4wMDM2LjI1NjYgMi4xNTZzLTQuMzA4MyAyLjU4MTMtNC45MTMzIDIuMjM2NmMtLjYwMTMtLjM0NDYtLjY4OTMtNC45MDk2LS42MDEzLTYuMDMxNnoiIGZpbGw9IiM2NWJjNDYiLz48cGF0aCBkPSJtMjEuMzQgMzQuODA0OWMwIDEuODA3Ny0uMjYwNCAyLjU4NS41MTMzIDIuNzU3NC43NzczLjE3MjMgMi4yNDAzIDAgMi43NjEtLjM0NDcuNTEzMy0uMzQ0Ny4wODQzLTIuNjY5My0uMDg4LTMuMTAycy0zLjE5LS4wODgtMy4xOS42ODkzeiIgZmlsbD0iIzQzYTI0NCIvPjxwYXRoIGQ9Im0yMS42NzAxIDM0LjQwNTFjMCAxLjgwNzYtLjI2MDQgMi41ODEzLjUxMzMgMi43NTM2Ljc3MzcuMTc2IDIuMjM2NyAwIDIuNzU3My0uMzQ0Ni41MTctLjM0NDcuMDg4LTIuNjY5NC0uMDg0My0zLjEwMi0uMTcyMy0uNDMyNy0zLjE5LS4wODQ0LTMuMTkuNjg5M3oiIGZpbGw9IiM2NWJjNDYiLz48cGF0aCBkPSJtMjIuMDAwMiA0MC40NDgxYzEwLjE4ODUgMCAxOC40NDc5LTguMjU5NCAxOC40NDc5LTE4LjQ0NzlzLTguMjU5NC0xOC40NDc5NS0xOC40NDc5LTE4LjQ0Nzk1LTE4LjQ0Nzk1IDguMjU5NDUtMTguNDQ3OTUgMTguNDQ3OTUgOC4yNTk0NSAxOC40NDc5IDE4LjQ0Nzk1IDE4LjQ0Nzl6bTAgMS43MTg3YzExLjEzNzcgMCAyMC4xNjY2LTkuMDI4OSAyMC4xNjY2LTIwLjE2NjYgMC0xMS4xMzc4LTkuMDI4OS0yMC4xNjY3LTIwLjE2NjYtMjAuMTY2Ny0xMS4xMzc4IDAtMjAuMTY2NyA5LjAyODktMjAuMTY2NyAyMC4xNjY3IDAgMTEuMTM3NyA5LjAyODkgMjAuMTY2NiAyMC4xNjY3IDIwLjE2NjZ6IiBmaWxsPSIjZmZmIi8+PC9nPjwvc3ZnPg=='; +module.exports = { + daxBase64 +}; + +},{}],21:[function(require,module,exports){ +"use strict"; + +const css = require('./selectors-css'); +/** + * This is here to mimic what Remote Configuration might look like + * later on. + * + * @type {MatchingConfiguration} + */ + + +const matchingConfiguration = { + /** @type {MatcherConfiguration} */ + matchers: { + fields: { + email: { + type: 'email', + strategies: { + cssSelector: 'email', + ddgMatcher: 'email', + vendorRegex: 'email' + } + }, + password: { + type: 'password', + strategies: { + cssSelector: 'password', + ddgMatcher: 'password' + } + }, + username: { + type: 'username', + strategies: { + cssSelector: 'username', + ddgMatcher: 'username' + } + }, + firstName: { + type: 'firstName', + strategies: { + cssSelector: 'firstName', + ddgMatcher: 'firstName', + vendorRegex: 'given-name' + } + }, + middleName: { + type: 'middleName', + strategies: { + cssSelector: 'middleName', + ddgMatcher: 'middleName', + vendorRegex: 'additional-name' + } + }, + lastName: { + type: 'lastName', + strategies: { + cssSelector: 'lastName', + ddgMatcher: 'lastName', + vendorRegex: 'family-name' + } + }, + fullName: { + type: 'fullName', + strategies: { + cssSelector: 'fullName', + ddgMatcher: 'fullName', + vendorRegex: 'name' + } + }, + phone: { + type: 'phone', + strategies: { + cssSelector: 'phone', + ddgMatcher: 'phone', + vendorRegex: 'tel' + } + }, + addressStreet: { + type: 'addressStreet', + strategies: { + cssSelector: 'addressStreet', + ddgMatcher: 'addressStreet', + vendorRegex: 'address-line1' + } + }, + addressStreet2: { + type: 'addressStreet2', + strategies: { + cssSelector: 'addressStreet2', + ddgMatcher: 'addressStreet2', + vendorRegex: 'address-line2' + } + }, + addressCity: { + type: 'addressCity', + strategies: { + cssSelector: 'addressCity', + ddgMatcher: 'addressCity', + vendorRegex: 'address-level2' + } + }, + addressProvince: { + type: 'addressProvince', + strategies: { + cssSelector: 'addressProvince', + ddgMatcher: 'addressProvince', + vendorRegex: 'address-level1' + } + }, + addressPostalCode: { + type: 'addressPostalCode', + strategies: { + cssSelector: 'addressPostalCode', + ddgMatcher: 'addressPostalCode', + vendorRegex: 'postal-code' + } + }, + addressCountryCode: { + type: 'addressCountryCode', + strategies: { + cssSelector: 'addressCountryCode', + ddgMatcher: 'addressCountryCode', + vendorRegex: 'country' + } + }, + birthdayDay: { + type: 'birthdayDay', + strategies: { + cssSelector: 'birthdayDay' + } + }, + birthdayMonth: { + type: 'birthdayMonth', + strategies: { + cssSelector: 'birthdayMonth' + } + }, + birthdayYear: { + type: 'birthdayYear', + strategies: { + cssSelector: 'birthdayYear' + } + }, + cardName: { + type: 'cardName', + strategies: { + cssSelector: 'cardName', + ddgMatcher: 'cardName', + vendorRegex: 'cc-name' + } + }, + cardNumber: { + type: 'cardNumber', + strategies: { + cssSelector: 'cardNumber', + ddgMatcher: 'cardNumber', + vendorRegex: 'cc-number' + } + }, + cardSecurityCode: { + type: 'cardSecurityCode', + strategies: { + cssSelector: 'cardSecurityCode', + ddgMatcher: 'cardSecurityCode' + } + }, + expirationMonth: { + type: 'expirationMonth', + strategies: { + cssSelector: 'expirationMonth', + ddgMatcher: 'expirationMonth', + vendorRegex: 'cc-exp-month' + } + }, + expirationYear: { + type: 'expirationYear', + strategies: { + cssSelector: 'expirationYear', + ddgMatcher: 'expirationYear', + vendorRegex: 'cc-exp-year' + } + }, + expiration: { + type: 'expiration', + strategies: { + cssSelector: 'expiration', + ddgMatcher: 'expiration', + vendorRegex: 'cc-exp' + } + } + }, + lists: { + email: ['email'], + password: ['password'], + username: ['username'], + cc: ['cardName', 'cardNumber', 'cardSecurityCode', 'expirationMonth', 'expirationYear', 'expiration'], + id: ['firstName', 'middleName', 'lastName', 'fullName', 'phone', 'addressStreet', 'addressStreet2', 'addressCity', 'addressProvince', 'addressPostalCode', 'addressCountryCode', 'birthdayDay', 'birthdayMonth', 'birthdayYear'] + } + }, + strategies: { + /** @type {CssSelectorConfiguration} */ + cssSelector: { + selectors: { + // Generic + FORM_INPUTS_SELECTOR: css.__secret_do_not_use.FORM_INPUTS_SELECTOR, + SUBMIT_BUTTON_SELECTOR: css.__secret_do_not_use.SUBMIT_BUTTON_SELECTOR, + GENERIC_TEXT_FIELD: css.__secret_do_not_use.GENERIC_TEXT_FIELD, + // user + email: css.__secret_do_not_use.email, + password: css.__secret_do_not_use.password, + username: css.__secret_do_not_use.username, + // CC + cardName: css.__secret_do_not_use.cardName, + cardNumber: css.__secret_do_not_use.cardNumber, + cardSecurityCode: css.__secret_do_not_use.cardSecurityCode, + expirationMonth: css.__secret_do_not_use.expirationMonth, + expirationYear: css.__secret_do_not_use.expirationYear, + expiration: css.__secret_do_not_use.expiration, + // Identities + firstName: css.__secret_do_not_use.firstName, + middleName: css.__secret_do_not_use.middleName, + lastName: css.__secret_do_not_use.lastName, + fullName: css.__secret_do_not_use.fullName, + phone: css.__secret_do_not_use.phone, + addressStreet: css.__secret_do_not_use.addressStreet1, + addressStreet2: css.__secret_do_not_use.addressStreet2, + addressCity: css.__secret_do_not_use.addressCity, + addressProvince: css.__secret_do_not_use.addressProvince, + addressPostalCode: css.__secret_do_not_use.addressPostalCode, + addressCountryCode: css.__secret_do_not_use.addressCountryCode, + birthdayDay: css.__secret_do_not_use.birthdayDay, + birthdayMonth: css.__secret_do_not_use.birthdayMonth, + birthdayYear: css.__secret_do_not_use.birthdayYear + } + }, + + /** @type {DDGMatcherConfiguration} */ + ddgMatcher: { + matchers: { + email: { + match: '.mail', + forceUnknown: 'search' + }, + password: { + match: 'password', + forceUnknown: 'captcha' + }, + username: { + match: 'user((.)?(name|id|login))?$', + forceUnknown: 'search' + }, + // CC + cardName: { + match: '(card.*name|name.*card)|(card.*holder|holder.*card)|(card.*owner|owner.*card)' + }, + cardNumber: { + match: 'card.*number|number.*card' + }, + cardSecurityCode: { + match: 'security.?code|card.?verif|cvv|csc|cvc' + }, + expirationMonth: { + match: '(card|\\bcc\\b)?.?(exp(iry|iration)?)?.?(month|\\bmm\\b(?![.\\s/-]yy))', + forceUnknown: 'mm[/\\s.\\-_—–]' + }, + expirationYear: { + match: '(card|\\bcc\\b)?.?(exp(iry|iration)?)?.?(year|yy)', + skip: 'mm[/\\s.\\-_—–]' + }, + expiration: { + match: '(\\bmm\\b|\\b\\d\\d\\b)[/\\s.\\-_—–](\\byy|\\bjj|\\baa|\\b\\d\\d)|\\bexp|\\bvalid(idity| through| until)', + forceUnknown: 'invalid' + }, + // Identities + firstName: { + match: '(first|given|fore).?name' + }, + middleName: { + match: '(middle|additional).?name' + }, + lastName: { + match: '(last|family|sur)[^i]?name' + }, + fullName: { + match: '^(full.?|whole\\s)?name\\b', + forceUnknown: 'company|org' + }, + phone: { + match: 'phone', + forceUnknown: 'code|pass' + }, + addressStreet: { + match: 'address', + forceUnknown: 'email|\\bip\\b|duck|log.?in|sign.?in', + skip: 'address.*(2|two)' + }, + addressStreet2: { + match: 'address.*(2|two)|apartment|\\bapt\\b|\\bflat\\b|\\bline.*(2|two)', + forceUnknown: 'email|\\bip\\b|duck|log.?in|sign.?in' + }, + addressCity: { + match: 'city|town', + forceUnknown: 'vatican' + }, + addressProvince: { + match: 'state|province|region|county', + forceUnknown: 'united', + skip: 'country' + }, + addressPostalCode: { + match: '\\bzip\\b|postal|post.?code' + }, + addressCountryCode: { + match: 'country' + } + } + }, + /** - * PM endpoints + * @type {VendorRegexConfiguration} */ + vendorRegex: { + rules: { + email: null, + tel: null, + organization: null, + 'street-address': null, + 'address-line1': null, + 'address-line2': null, + 'address-line3': null, + 'address-level2': null, + 'address-level1': null, + 'postal-code': null, + country: null, + 'cc-name': null, + name: null, + 'given-name': null, + 'additional-name': null, + 'family-name': null, + 'cc-number': null, + 'cc-exp-month': null, + 'cc-exp-year': null, + 'cc-exp': null, + 'cc-type': null + }, + ruleSets: [//= ======================================================================== + // Firefox-specific rules + { + 'address-line1': 'addrline1|address_1', + 'address-line2': 'addrline2|address_2', + 'address-line3': 'addrline3|address_3', + 'address-level1': 'land', + // de-DE + 'additional-name': 'apellido.?materno|lastlastname', + 'cc-name': 'accountholdername' + '|titulaire', + // fr-FR + 'cc-number': '(cc|kk)nr', + // de-DE + 'cc-exp-month': '(cc|kk)month', + // de-DE + 'cc-exp-year': '(cc|kk)year', + // de-DE + 'cc-type': 'type' + '|kartenmarke' // de-DE + + }, //= ======================================================================== + // These are the rules used by Bitwarden [0], converted into RegExp form. + // [0] https://github.com/bitwarden/browser/blob/c2b8802201fac5e292d55d5caf3f1f78088d823c/src/services/autofill.service.ts#L436 + { + email: '(^e-?mail$)|(^email-?address$)', + tel: '(^phone$)' + '|(^mobile$)' + '|(^mobile-?phone$)' + '|(^tel$)' + '|(^telephone$)' + '|(^phone-?number$)', + organization: '(^company$)' + '|(^company-?name$)' + '|(^organization$)' + '|(^organization-?name$)', + 'street-address': '(^address$)' + '|(^street-?address$)' + '|(^addr$)' + '|(^street$)' + '|(^mailing-?addr(ess)?$)' + // Modified to not grab lines, below + '|(^billing-?addr(ess)?$)' + // Modified to not grab lines, below + '|(^mail-?addr(ess)?$)' + // Modified to not grab lines, below + '|(^bill-?addr(ess)?$)', + // Modified to not grab lines, below + 'address-line1': '(^address-?1$)' + '|(^address-?line-?1$)' + '|(^addr-?1$)' + '|(^street-?1$)', + 'address-line2': '(^address-?2$)' + '|(^address-?line-?2$)' + '|(^addr-?2$)' + '|(^street-?2$)', + 'address-line3': '(^address-?3$)' + '|(^address-?line-?3$)' + '|(^addr-?3$)' + '|(^street-?3$)', + 'address-level2': '(^city$)' + '|(^town$)' + '|(^address-?level-?2$)' + '|(^address-?city$)' + '|(^address-?town$)', + 'address-level1': '(^state$)' + '|(^province$)' + '|(^provence$)' + '|(^address-?level-?1$)' + '|(^address-?state$)' + '|(^address-?province$)', + 'postal-code': '(^postal$)' + '|(^zip$)' + '|(^zip2$)' + '|(^zip-?code$)' + '|(^postal-?code$)' + '|(^post-?code$)' + '|(^address-?zip$)' + '|(^address-?postal$)' + '|(^address-?code$)' + '|(^address-?postal-?code$)' + '|(^address-?zip-?code$)', + country: '(^country$)' + '|(^country-?code$)' + '|(^country-?name$)' + '|(^address-?country$)' + '|(^address-?country-?name$)' + '|(^address-?country-?code$)', + name: '(^name$)|full-?name|your-?name', + 'given-name': '(^f-?name$)' + '|(^first-?name$)' + '|(^given-?name$)' + '|(^first-?n$)', + 'additional-name': '(^m-?name$)' + '|(^middle-?name$)' + '|(^additional-?name$)' + '|(^middle-?initial$)' + '|(^middle-?n$)' + '|(^middle-?i$)', + 'family-name': '(^l-?name$)' + '|(^last-?name$)' + '|(^s-?name$)' + '|(^surname$)' + '|(^family-?name$)' + '|(^family-?n$)' + '|(^last-?n$)', + 'cc-name': 'cc-?name' + '|card-?name' + '|cardholder-?name' + '|cardholder' + // "|(^name$)" + // Removed to avoid overwriting "name", above. + '|(^nom$)', + 'cc-number': 'cc-?number' + '|cc-?num' + '|card-?number' + '|card-?num' + '|(^number$)' + '|(^cc$)' + '|cc-?no' + '|card-?no' + '|(^credit-?card$)' + '|numero-?carte' + '|(^carte$)' + '|(^carte-?credit$)' + '|num-?carte' + '|cb-?num', + 'cc-exp': '(^cc-?exp$)' + '|(^card-?exp$)' + '|(^cc-?expiration$)' + '|(^card-?expiration$)' + '|(^cc-?ex$)' + '|(^card-?ex$)' + '|(^card-?expire$)' + '|(^card-?expiry$)' + '|(^validite$)' + '|(^expiration$)' + '|(^expiry$)' + '|mm-?yy' + '|mm-?yyyy' + '|yy-?mm' + '|yyyy-?mm' + '|expiration-?date' + '|payment-?card-?expiration' + '|(^payment-?cc-?date$)', + 'cc-exp-month': '(^exp-?month$)' + '|(^cc-?exp-?month$)' + '|(^cc-?month$)' + '|(^card-?month$)' + '|(^cc-?mo$)' + '|(^card-?mo$)' + '|(^exp-?mo$)' + '|(^card-?exp-?mo$)' + '|(^cc-?exp-?mo$)' + '|(^card-?expiration-?month$)' + '|(^expiration-?month$)' + '|(^cc-?mm$)' + '|(^cc-?m$)' + '|(^card-?mm$)' + '|(^card-?m$)' + '|(^card-?exp-?mm$)' + '|(^cc-?exp-?mm$)' + '|(^exp-?mm$)' + '|(^exp-?m$)' + '|(^expire-?month$)' + '|(^expire-?mo$)' + '|(^expiry-?month$)' + '|(^expiry-?mo$)' + '|(^card-?expire-?month$)' + '|(^card-?expire-?mo$)' + '|(^card-?expiry-?month$)' + '|(^card-?expiry-?mo$)' + '|(^mois-?validite$)' + '|(^mois-?expiration$)' + '|(^m-?validite$)' + '|(^m-?expiration$)' + '|(^expiry-?date-?field-?month$)' + '|(^expiration-?date-?month$)' + '|(^expiration-?date-?mm$)' + '|(^exp-?mon$)' + '|(^validity-?mo$)' + '|(^exp-?date-?mo$)' + '|(^cb-?date-?mois$)' + '|(^date-?m$)', + 'cc-exp-year': '(^exp-?year$)' + '|(^cc-?exp-?year$)' + '|(^cc-?year$)' + '|(^card-?year$)' + '|(^cc-?yr$)' + '|(^card-?yr$)' + '|(^exp-?yr$)' + '|(^card-?exp-?yr$)' + '|(^cc-?exp-?yr$)' + '|(^card-?expiration-?year$)' + '|(^expiration-?year$)' + '|(^cc-?yy$)' + '|(^cc-?y$)' + '|(^card-?yy$)' + '|(^card-?y$)' + '|(^card-?exp-?yy$)' + '|(^cc-?exp-?yy$)' + '|(^exp-?yy$)' + '|(^exp-?y$)' + '|(^cc-?yyyy$)' + '|(^card-?yyyy$)' + '|(^card-?exp-?yyyy$)' + '|(^cc-?exp-?yyyy$)' + '|(^expire-?year$)' + '|(^expire-?yr$)' + '|(^expiry-?year$)' + '|(^expiry-?yr$)' + '|(^card-?expire-?year$)' + '|(^card-?expire-?yr$)' + '|(^card-?expiry-?year$)' + '|(^card-?expiry-?yr$)' + '|(^an-?validite$)' + '|(^an-?expiration$)' + '|(^annee-?validite$)' + '|(^annee-?expiration$)' + '|(^expiry-?date-?field-?year$)' + '|(^expiration-?date-?year$)' + '|(^cb-?date-?ann$)' + '|(^expiration-?date-?yy$)' + '|(^expiration-?date-?yyyy$)' + '|(^validity-?year$)' + '|(^exp-?date-?year$)' + '|(^date-?y$)', + 'cc-type': '(^cc-?type$)' + '|(^card-?type$)' + '|(^card-?brand$)' + '|(^cc-?brand$)' + '|(^cb-?type$)' + }, //= ======================================================================== + // These rules are from Chromium source codes [1]. Most of them + // converted to JS format have the same meaning with the original ones + // except the first line of "address-level1". + // [1] https://source.chromium.org/chromium/chromium/src/+/master:components/autofill/core/common/autofill_regex_constants.cc + { + // ==== Email ==== + email: 'e.?mail' + '|courriel' + // fr + '|correo.*electr(o|ó)nico' + // es-ES + '|メールアドレス' + // ja-JP + '|Электронной.?Почты' + // ru + '|邮件|邮箱' + // zh-CN + '|電郵地址' + // zh-TW + '|ഇ-മെയില്‍|ഇലക്ട്രോണിക്.?' + 'മെയിൽ' + // ml + '|ایمیل|پست.*الکترونیک' + // fa + '|ईमेल|इलॅक्ट्रॉनिक.?मेल' + // hi + '|(\\b|_)eposta(\\b|_)' + // tr + '|(?:이메일|전자.?우편|[Ee]-?mail)(.?주소)?', + // ko-KR + // ==== Telephone ==== + tel: 'phone|mobile|contact.?number' + '|telefonnummer' + // de-DE + '|telefono|teléfono' + // es + '|telfixe' + // fr-FR + '|電話' + // ja-JP + '|telefone|telemovel' + // pt-BR, pt-PT + '|телефон' + // ru + '|मोबाइल' + // hi for mobile + '|(\\b|_|\\*)telefon(\\b|_|\\*)' + // tr + '|电话' + // zh-CN + '|മൊബൈല്‍' + // ml for mobile + '|(?:전화|핸드폰|휴대폰|휴대전화)(?:.?번호)?', + // ko-KR + // ==== Address Fields ==== + organization: 'company|business|organization|organisation' + // '|(? wkSend('pmHandlerStoreCredentials', credentials); - /** - * Gets the init data from the device - * @returns {APIResponse} - */ + /** @type {Record} */ + + /** + * This acts as an internal cache for the larger vendorRegexes + * @type {{RULES: Record}} + */ + + /** @type {MatcherLists} */ + /** @type {Array} */ - this.getAutofillInitData = () => wkSendAndWait('pmHandlerGetAutofillInitData').then(response => { - this.storeLocalData(response.success); - return response; + /** + * @param {MatchingConfiguration} config + */ + constructor(config) { + _classPrivateFieldInitSpec(this, _config, { + writable: true, + value: void 0 }); - /** - * Gets credentials ready for autofill - * @param {Number} id - the credential id - * @returns {APIResponse} - */ + _classPrivateFieldInitSpec(this, _cssSelectors, { + writable: true, + value: void 0 + }); - this.getAutofillCredentials = id => wkSendAndWait('pmHandlerGetAutofillCredentials', { - id + _classPrivateFieldInitSpec(this, _ddgMatchers, { + writable: true, + value: void 0 }); - /** - * Opens the native UI for managing passwords - */ + _classPrivateFieldInitSpec(this, _vendorRegExpCache, { + writable: true, + value: void 0 + }); - this.openManagePasswords = () => wkSend('pmHandlerOpenManagePasswords'); - /** - * Opens the native UI for managing identities - */ + _classPrivateFieldInitSpec(this, _matcherLists, { + writable: true, + value: void 0 + }); + _classPrivateFieldInitSpec(this, _defaultStrategyOrder, { + writable: true, + value: ['cssSelector', 'ddgMatcher', 'vendorRegex'] + }); - this.openManageIdentities = () => wkSend('pmHandlerOpenManageIdentities'); - /** - * Opens the native UI for managing credit cards - */ + _classPrivateFieldSet(this, _config, config); + const { + rules, + ruleSets + } = _classPrivateFieldGet(this, _config).strategies.vendorRegex; - this.openManageCreditCards = () => wkSend('pmHandlerOpenManageCreditCards'); - /** - * Gets a single identity obj once the user requests it - * @param {Number} id - * @returns {APIResponse} - */ + _classPrivateFieldSet(this, _vendorRegExpCache, createCacheableVendorRegexes(rules, ruleSets)); + _classPrivateFieldSet(this, _cssSelectors, _classPrivateFieldGet(this, _config).strategies.cssSelector.selectors); - this.getAutofillIdentity = id => wkSendAndWait('pmHandlerGetIdentity', { - id + _classPrivateFieldSet(this, _ddgMatchers, _classPrivateFieldGet(this, _config).strategies.ddgMatcher.matchers); + + _classPrivateFieldSet(this, _matcherLists, { + cc: [], + id: [], + password: [], + username: [], + email: [] }); /** - * Gets a single complete credit card obj once the user requests it - * @param {Number} id - * @returns {APIResponse} + * Convert the raw config data into actual references. + * + * For example this takes `email: ["email"]` and creates + * + * `email: [{type: "email", strategies: {cssSelector: "email", ... etc}]` */ - this.getAutofillCreditCard = id => wkSendAndWait('pmHandlerGetCreditCard', { - id - }); + for (let [listName, matcherNames] of Object.entries(_classPrivateFieldGet(this, _config).matchers.lists)) { + for (let fieldName of matcherNames) { + if (!_classPrivateFieldGet(this, _matcherLists)[listName]) { + _classPrivateFieldGet(this, _matcherLists)[listName] = []; + } + + _classPrivateFieldGet(this, _matcherLists)[listName].push(_classPrivateFieldGet(this, _config).matchers.fields[fieldName]); + } + } } + /** + * Try to access a 'vendor regex' by name + * @param {string} regexName + * @returns {RegExp | undefined} + */ -} -const DeviceInterface = (() => { - if (isDDGApp) { - return isAndroid ? new AndroidInterface() : new AppleDeviceInterface(); - } + vendorRegex(regexName) { + const match = _classPrivateFieldGet(this, _vendorRegExpCache).RULES[regexName]; - return new ExtensionInterface(); -})(); + if (!match) { + console.warn('Vendor Regex not found for', regexName); + return undefined; + } -module.exports = DeviceInterface; + return match; + } + /** + * Try to access a 'css selector' by name from configuration + * @param {keyof RequiredCssSelectors | string} selectorName + * @returns {string}; + */ -},{"./Form/inputTypeConfig":6,"./UI/DataAutofill":10,"./UI/EmailAutofill":11,"./appleDeviceUtils/appleDeviceUtils":15,"./autofill-utils":17,"./scanForInputs.js":21}],2:[function(require,module,exports){ -"use strict"; -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + cssSelector(selectorName) { + const match = _classPrivateFieldGet(this, _cssSelectors)[selectorName]; -const FormAnalyzer = require('./FormAnalyzer'); + if (!match) { + console.warn('CSS selector not found for %s, using a default value', selectorName); + return ''; + } -const { - SUBMIT_BUTTON_SELECTOR, - FIELD_SELECTOR -} = require('./selectors'); + if (Array.isArray(match)) { + return match.join(','); + } -const { - addInlineStyles, - removeInlineStyles, - setValue, - isEventWithinDax, - isMobileApp -} = require('../autofill-utils'); + return match; + } + /** + * Try to access a 'ddg matcher' by name from configuration + * @param {keyof RequiredCssSelectors | string} matcherName + * @returns {DDGMatcher | undefined} + */ -const { - getInputSubtype, - setInputType, - getInputMainType, - formatCCYear, - getUnifiedExpiryDate -} = require('./input-classifiers'); -const { - getIconStylesAutofilled, - getIconStylesBase -} = require('./inputStyles'); + ddgMatcher(matcherName) { + const match = _classPrivateFieldGet(this, _ddgMatchers)[matcherName]; -const { - ATTR_AUTOFILL -} = require('../constants'); + if (!match) { + console.warn('DDG matcher not found for', matcherName); + return undefined; + } -const getInputConfig = require('./inputTypeConfig.js'); + return match; + } + /** + * Try to access a list of matchers by name - these are the ones collected in the constructor + * @param {keyof MatcherLists} listName + * @return {Matcher[]} + */ -class Form { - constructor(form, _input, DeviceInterface) { - _defineProperty(this, "autofillInput", (input, string, dataType) => { - setValue(input, string); - input.classList.add('ddg-autofilled'); - addInlineStyles(input, getIconStylesAutofilled(input)); // If the user changes the alias, remove the decoration - - input.addEventListener('input', e => this.removeAllHighlights(e, dataType), { - once: true - }); - }); - this.form = form; - this.formAnalyzer = new FormAnalyzer(form, _input); - this.isLogin = this.formAnalyzer.isLogin; - this.isSignup = this.formAnalyzer.isSignup; - this.Device = DeviceInterface; - this.attachTooltip = DeviceInterface.attachTooltip; - /** @type Object<'all' | SupportedMainTypes, Set> */ + matcherList(listName) { + const matcherList = _classPrivateFieldGet(this, _matcherLists)[listName]; - this.inputs = { - all: new Set(), - emailNew: new Set(), - credentials: new Set(), - creditCard: new Set(), - unknown: new Set() - }; - this.touched = new Set(); - this.listeners = new Set(); - this.tooltip = null; - this.activeInput = null; - this.handlerExecuted = false; - this.shouldPromptToStoreCredentials = true; + if (!matcherList) { + console.warn('MatcherList not found for ', listName); + return []; + } - this.submitHandler = () => { - if (this.handlerExecuted) return; - const credentials = this.getValues(); + return matcherList; + } + /** + * Convert a list of matchers into a single CSS selector. + * + * This will consider all matchers in the list and if it + * contains a CSS Selector it will be added to the final output + * + * @param {keyof MatcherLists} listName + * @returns {string | undefined} + */ - if (credentials.password) { - // ask to store credentials and/or fireproof - if (this.shouldPromptToStoreCredentials) { - this.Device.storeCredentials(credentials); - } - this.handlerExecuted = true; - } - }; + joinCssSelectors(listName) { + const matcherList = this.matcherList(listName); - this.getValues = () => { - const credentials = [...this.inputs.credentials, ...this.inputs.emailNew].reduce((output, input) => { - const subtype = getInputSubtype(input); - output[subtype] = input.value || output[subtype]; - return output; - }, { - username: '', - password: '' - }); // If we don't have a username, let's try and save the email if available. + if (!matcherList) { + console.warn('Matcher list not found for', listName); + return undefined; + } + /** + * @type {string[]} + */ - if (credentials.emailNew && !credentials.username) { - credentials.username = credentials.emailNew; - } - delete credentials.emailNew; - return credentials; - }; + const selectors = []; - this.hasValues = () => { - const { - username, - password - } = this.getValues(); - return !!(username && password); - }; + for (let matcher of matcherList) { + if (matcher.strategies.cssSelector) { + const css = this.cssSelector(matcher.strategies.cssSelector); - this.intObs = new IntersectionObserver(entries => { - for (const entry of entries) { - if (!entry.isIntersecting) this.removeTooltip(); + if (css) { + selectors.push(css); + } } - }); + } - this.removeTooltip = e => { - if (!this.tooltip || e && e.target === this.tooltip.host) { - return; - } + return selectors.join(', '); + } + /** + * Tries to infer the input type for an input + * + * @param {HTMLInputElement|HTMLSelectElement} input + * @param {HTMLFormElement} formEl + * @param {{isLogin?: boolean}} [opts] + * @returns {SupportedTypes} + */ - this.tooltip.remove(); - this.tooltip = null; - this.intObs.disconnect(); - window.removeEventListener('pointerdown', this.removeTooltip, { - capture: true - }); - }; - this.removeInputHighlight = input => { - removeInlineStyles(input, getIconStylesAutofilled(input)); - input.classList.remove('ddg-autofilled'); - this.addAutofillStyles(input); - }; + inferInputType(input, formEl) { + let opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + const presetType = getInputType(input); + if (presetType !== 'unknown') return presetType; // For CC forms we run aggressive matches, so we want to make sure we only + // run them on actual CC forms to avoid false positives and expensive loops - this.removeAllHighlights = (e, dataType) => { - // This ensures we are not removing the highlight ourselves when autofilling more than once - if (e && !e.isTrusted) return; // If the user has changed the value, we prompt to update the stored creds + if (this.isCCForm(formEl)) { + const ccMatchers = this.matcherList('cc'); + const subtype = this.subtypeFromMatchers(ccMatchers, input, formEl); - this.shouldPromptToStoreCredentials = true; - this.execOnInputs(this.removeInputHighlight, dataType); - }; + if (subtype && isValidCreditCardSubtype(subtype)) { + return "creditCard.".concat(subtype); + } + } - this.removeInputDecoration = input => { - removeInlineStyles(input, getIconStylesBase(input)); - input.removeAttribute(ATTR_AUTOFILL); - }; + if (input instanceof HTMLInputElement) { + if (this.isPassword(input, formEl)) { + return 'credentials.password'; + } - this.removeAllDecorations = () => { - this.execOnInputs(this.removeInputDecoration); - this.listeners.forEach(({ - el, - type, - fn - }) => el.removeEventListener(type, fn)); - }; + if (this.isEmail(input, formEl)) { + return opts.isLogin ? 'credentials.username' : 'identities.emailAddress'; + } - this.redecorateAllInputs = () => { - this.removeAllDecorations(); - this.execOnInputs(input => this.decorateInput(input)); - }; + if (this.isUserName(input, formEl)) { + return 'credentials.username'; + } + } - this.resetAllInputs = () => { - this.execOnInputs(input => { - setValue(input, ''); - this.removeInputHighlight(input); - }); - if (this.activeInput) this.activeInput.focus(); - }; + const idMatchers = this.matcherList('id'); + const idSubtype = this.subtypeFromMatchers(idMatchers, input, formEl); - this.dismissTooltip = () => { - this.removeTooltip(); - }; + if (idSubtype && isValidIdentitiesSubtype(idSubtype)) { + return "identities.".concat(idSubtype); + } - this.categorizeInputs(); - return this; + return 'unknown'; } + /** + * Sets the input type as a data attribute to the element and returns it + * @param {HTMLInputElement} input + * @param {HTMLFormElement} formEl + * @param {{isLogin?: boolean}} [opts] + * @returns {SupportedSubTypes | string} + */ - categorizeInputs() { - this.form.querySelectorAll(FIELD_SELECTOR).forEach(input => this.addInput(input)); + + setInputType(input, formEl) { + let opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + const type = this.inferInputType(input, formEl, opts); + input.setAttribute(ATTR_INPUT_TYPE, type); + return type; } + /** + * Tries to infer input subtype, with checks in decreasing order of reliability + * @param {Matcher[]} matchers + * @param {HTMLInputElement|HTMLSelectElement} el + * @param {HTMLFormElement} form + * @return {MatcherTypeNames|undefined} + */ - get submitButtons() { - return [...this.form.querySelectorAll(SUBMIT_BUTTON_SELECTOR)].filter(button => { - const content = button.textContent; - const ariaLabel = button.getAttribute('aria-label'); - const title = button.title; // trying to exclude the little buttons to show and hide passwords - return !/password|show|toggle|reveal|hide/i.test(content + ariaLabel + title); - }); - } + subtypeFromMatchers(matchers, el, form) { + for (let strategyName of _classPrivateFieldGet(this, _defaultStrategyOrder)) { + for (let matcher of matchers) { + const lookup = matcher.strategies[strategyName]; - execOnInputs(fn, inputType = 'all') { - const inputs = this.inputs[inputType]; + if (!lookup) { + continue; + } - for (const input of inputs) { - const { - shouldDecorate - } = getInputConfig(input); - if (shouldDecorate(this.isLogin, this.Device)) fn(input); + const result = this.executeMatchingStrategy(strategyName, lookup, el, form); + + if (result.matched) { + return matcher.type; + } + + if (!result.matched && result.proceed === false) { + // If we get here, do not allow subsequent strategies to continue + return undefined; + } + } } - } - addInput(input) { - if (this.inputs.all.has(input)) return this; - this.inputs.all.add(input); - setInputType(input, this); - const mainInputType = getInputMainType(input); - this.inputs[mainInputType].add(input); - this.decorateInput(input); - return this; + return undefined; } + /** + * Takes a given strategy name, like 'cssSelector' along with a lookup key + * and tries to execute that strategy safely on the input provided + * + * @param {StrategyNames} strategy + * @param {string} lookup + * @param {HTMLInputElement|HTMLSelectElement} el + * @param {HTMLFormElement} form + * @returns {MatchingResult} + */ - areAllInputsEmpty(inputType) { - let allEmpty = true; - this.execOnInputs(input => { - if (input.value) allEmpty = false; - }, inputType); - return allEmpty; - } - addListener(el, type, fn) { - el.addEventListener(type, fn); - this.listeners.add({ - el, - type, - fn - }); - } + executeMatchingStrategy(strategy, lookup, el, form) { + switch (strategy) { + case 'cssSelector': + { + const selector = this.cssSelector(lookup); + return this.execCssSelector(selector, el); + } - addAutofillStyles(input) { - const styles = getIconStylesBase(input); - addInlineStyles(input, styles); - } + case 'ddgMatcher': + { + const ddgMatcher = this.ddgMatcher(lookup); - decorateInput(input) { - const config = getInputConfig(input); - if (!config.shouldDecorate(this.isLogin, this.Device)) return this; - input.setAttribute(ATTR_AUTOFILL, 'true'); - const hasIcon = !!config.getIconBase(); + if (!ddgMatcher || !ddgMatcher.match) { + return { + matched: false + }; + } - if (hasIcon) { - this.addAutofillStyles(input, config); - this.addListener(input, 'mousemove', e => { - if (isEventWithinDax(e, e.target)) { - e.target.style.setProperty('cursor', 'pointer', 'important'); - } else { - e.target.style.removeProperty('cursor'); + return this.execDDGMatcher(ddgMatcher, el, form); } - }); - } - const handler = e => { - if (this.tooltip) return; // Checks for mousedown event + case 'vendorRegex': + { + const rule = this.vendorRegex(lookup); - if (e.type === 'pointerdown') { - if (!e.isTrusted) return; - const isMainMouseButton = e.button === 0; - if (!isMainMouseButton) return; - } + if (!rule) { + return { + matched: false + }; + } - if (this.shouldOpenTooltip(e, e.target)) { - if (isEventWithinDax(e, e.target) || isMobileApp) { - e.preventDefault(); - e.stopImmediatePropagation(); + return this.execVendorRegex(rule, el, form); } - this.touched.add(e.target); - this.attachTooltip(this, e.target); - } - }; - - const events = ['pointerdown']; - if (!isMobileApp) events.push('focus'); - events.forEach(ev => this.addListener(input, ev, handler, true)); - return this; + default: + return { + matched: false + }; + } } + /** + * CSS selector matching just levearages the `.matches` method on elements + * + * @param {string} cssSelector + * @param {HTMLInputElement|HTMLSelectElement} el + * @returns {MatchingResult} + */ - shouldOpenTooltip(e, input) { - const inputType = getInputMainType(input); - if (inputType !== 'emailNew') return true; - return !this.touched.has(input) && this.areAllInputsEmpty(inputType) || isEventWithinDax(e, input); + + execCssSelector(cssSelector, el) { + return { + matched: el.matches(cssSelector) + }; } + /** + * A DDG Matcher can have a `match` regex along with a `not` regex. This is done + * to allow it to be driven by configuration as it avoids needing to invoke custom functions. + * + * todo: maxDigits was added as an edge-case when converting this over to be declarative, but I'm + * unsure if it's actually needed. It's not urgent, but we should consider removing it if that's the case + * + * @param {DDGMatcher} ddgMatcher + * @param {HTMLInputElement|HTMLSelectElement} el + * @param {HTMLFormElement} form + * @returns {MatchingResult} + */ - autofillEmail(alias, dataType = 'emailNew') { - this.execOnInputs(input => this.autofillInput(input, alias, dataType), dataType); - if (this.tooltip) { - this.removeTooltip(); + execDDGMatcher(ddgMatcher, el, form) { + let matchRexExp = safeRegex(ddgMatcher.match || ''); + + if (!matchRexExp) { + return { + matched: false + }; } - } - autofillData(data, dataType) { - this.shouldPromptToStoreCredentials = false; - this.execOnInputs(input => { - const inputSubtype = getInputSubtype(input); - let autofillData = data[inputSubtype]; + let requiredScore = ['match', 'forceUnknown', 'maxDigits'].filter(ddgMatcherProp => ddgMatcherProp in ddgMatcher).length; + /** @type {MatchableStrings[]} */ - if (inputSubtype === 'expiration') { - autofillData = getUnifiedExpiryDate(input, data.expirationMonth, data.expirationYear, this.form); - } + const matchableStrings = ddgMatcher.matchableStrings || ['labelText', 'placeholderAttr', 'relatedText']; - if (inputSubtype === 'expirationYear' && input.nodeName === 'INPUT') { - autofillData = formatCCYear(input, autofillData, this.form); - } + for (let elementString of this.getElementStrings(el, form, { + matchableStrings + })) { + if (!elementString) continue; + elementString = elementString.toLowerCase(); + + if (ddgMatcher.skip) { + let skipRegex = safeRegex(ddgMatcher.skip); + + if (!skipRegex) { + return { + matched: false + }; + } + + if (skipRegex.test(elementString)) { + continue; + } + } // Scoring to ensure all DDG tests are valid + + + let score = 0; // if the `match` regex fails, moves onto the next string + + if (!matchRexExp.test(elementString)) { + continue; + } // Otherwise, increment the score - if (autofillData) this.autofillInput(input, autofillData, dataType); - }, dataType); - if (this.tooltip) { - this.removeTooltip(); - } - } + score++; // If a negated regex was provided, ensure it does not match + // If it DOES match - then we need to prevent any future strategies from continuing -} + if (ddgMatcher.forceUnknown) { + let notRegex = safeRegex(ddgMatcher.forceUnknown); -module.exports = Form; + if (!notRegex) { + return { + matched: false + }; + } -},{"../autofill-utils":17,"../constants":19,"./FormAnalyzer":3,"./input-classifiers":4,"./inputStyles":5,"./inputTypeConfig.js":6,"./selectors":9}],3:[function(require,module,exports){ -"use strict"; + if (notRegex.test(elementString)) { + return { + matched: false, + proceed: false + }; + } else { + // All good here, increment the score + score++; + } + } // If a 'maxDigits' rule was provided, validate it -const { - PASSWORD_SELECTOR, - SUBMIT_BUTTON_SELECTOR -} = require('./selectors'); -class FormAnalyzer { - constructor(form, input) { - this.form = form; - this.autofillSignal = 0; - this.signals = []; // Avoid autofill on our signup page + if (ddgMatcher.maxDigits) { + const digitLength = elementString.replace(/[^0-9]/g, '').length; - if (window.location.href.match(/^https:\/\/(.+\.)?duckduckgo\.com\/email\/choose-address/i)) { - return this; + if (digitLength > ddgMatcher.maxDigits) { + return { + matched: false + }; + } else { + score++; + } + } + + if (score === requiredScore) { + return { + matched: true + }; + } } - this.evaluateElAttributes(input, 3, true); - form ? this.evaluateForm() : this.evaluatePage(); - return this; + return { + matched: false + }; } + /** + * If we get here, a firefox/vendor regex was given and we can execute it on the element + * strings + * @param {RegExp} regex + * @param {HTMLInputElement|HTMLSelectElement} el + * @param {HTMLFormElement} form + * @return {MatchingResult} + */ - get isLogin() { - return this.autofillSignal < 0; - } - get isSignup() { - return this.autofillSignal >= 0; - } + execVendorRegex(regex, el, form) { + for (let elementString of this.getElementStrings(el, form)) { + if (!elementString) continue; + elementString = elementString.toLowerCase(); - increaseSignalBy(strength, signal) { - this.autofillSignal += strength; - this.signals.push("".concat(signal, ": +").concat(strength)); - return this; - } + if (regex.test(elementString)) { + return { + matched: true + }; + } + } - decreaseSignalBy(strength, signal) { - this.autofillSignal -= strength; - this.signals.push("".concat(signal, ": -").concat(strength)); - return this; + return { + matched: false + }; } + /** + * Yield strings in the order in which they should be checked against. + * + * Note: some strategies may not want to accept all strings, which is + * where `matchableStrings` helps. It defaults to when you see below but can + * be overridden. + * + * For example, `nameAttr` is first, since this has the highest chance of matching + * and then the rest are in decreasing order of value vs cost + * + * A generator function is used here to prevent any potentially expensive + * lookups occurring if they are rare. For example if 90% of all matching never needs + * to look at the output from `relatedText`, then the cost of computing it will be avoided. + * + * @param {HTMLInputElement|HTMLSelectElement} el + * @param {HTMLFormElement} form + * @param {{matchableStrings?: MatchableStrings[]}} [opts] + * @returns {Generator} + */ - updateSignal({ - string, - // The string to check - strength, - // Strength of the signal - signalType = 'generic', - // For debugging purposes, we give a name to the signal - shouldFlip = false, - // Flips the signals, i.e. when a link points outside. See below - shouldCheckUnifiedForm = false, - // Should check for login/signup forms - shouldBeConservative = false // Should use the conservative signup regex - - }) { - const negativeRegex = new RegExp(/sign(ing)?.?in(?!g)|log.?in/i); - const positiveRegex = new RegExp(/sign(ing)?.?up|join|regist(er|ration)|newsletter|subscri(be|ption)|contact|create|start|settings|preferences|profile|update|checkout|guest|purchase|buy|order|schedule|estimate|request/i); - const conservativePositiveRegex = new RegExp(/sign.?up|join|register|newsletter|subscri(be|ption)|settings|preferences|profile|update/i); - const strictPositiveRegex = new RegExp(/sign.?up|join|register|settings|preferences|profile|update/i); - const matchesNegative = string === 'current-password' || string.match(negativeRegex); // Check explicitly for unified login/signup forms. They should always be negative, so we increase signal - if (shouldCheckUnifiedForm && matchesNegative && string.match(strictPositiveRegex)) { - this.decreaseSignalBy(strength + 2, "Unified detected ".concat(signalType)); - return this; - } + *getElementStrings(el, form) { + let opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + let { + matchableStrings = ['nameAttr', 'labelText', 'placeholderAttr', 'id', 'relatedText'] + } = opts; - const matchesPositive = string === 'new-password' || string.match(shouldBeConservative ? conservativePositiveRegex : positiveRegex); // In some cases a login match means the login is somewhere else, i.e. when a link points outside + for (let matchableString of matchableStrings) { + switch (matchableString) { + case 'nameAttr': + { + yield el.name; + break; + } - if (shouldFlip) { - if (matchesNegative) this.increaseSignalBy(strength, signalType); - if (matchesPositive) this.decreaseSignalBy(strength, signalType); - } else { - if (matchesNegative) this.decreaseSignalBy(strength, signalType); - if (matchesPositive) this.increaseSignalBy(strength, signalType); - } + case 'labelText': + { + yield getExplicitLabelsText(el); + break; + } - return this; - } + case 'placeholderAttr': + { + if (el instanceof HTMLInputElement) { + yield el.placeholder || ''; + } - evaluateElAttributes(el, signalStrength = 3, isInput = false) { - Array.from(el.attributes).forEach(attr => { - if (attr.name === 'style') return; - const attributeString = "".concat(attr.name, "=").concat(attr.value); - this.updateSignal({ - string: attributeString, - strength: signalStrength, - signalType: "".concat(el.name, " attr: ").concat(attributeString), - shouldCheckUnifiedForm: isInput - }); - }); - } + break; + } - evaluatePageTitle() { - const pageTitle = document.title; - this.updateSignal({ - string: pageTitle, - strength: 2, - signalType: "page title: ".concat(pageTitle) - }); - } + case 'id': + { + yield el.id; + break; + } - evaluatePageHeadings() { - const headings = document.querySelectorAll('h1, h2, h3, [class*="title"], [id*="title"]'); + case 'relatedText': + { + yield getRelatedText(el, form, this.cssSelector('FORM_INPUTS_SELECTOR')); + break; + } - if (headings) { - headings.forEach(({ - innerText - }) => { - this.updateSignal({ - string: innerText, - strength: 0.5, - signalType: "heading: ".concat(innerText), - shouldCheckUnifiedForm: true, - shouldBeConservative: true - }); - }); + default: + {// a matchable string that wasn't handled + } + } } } + /** + * Tries to infer if input is for password + * @param {HTMLInputElement} el + * @param {HTMLFormElement} form + */ - evaluatePage() { - this.evaluatePageTitle(); - this.evaluatePageHeadings(); // Check for submit buttons - const buttons = document.querySelectorAll("\n button[type=submit],\n button:not([type]),\n [role=button]\n "); - buttons.forEach(button => { - // if the button has a form, it's not related to our input, because our input has no form here - if (!button.form && !button.closest('form')) { - this.evaluateElement(button); - this.evaluateElAttributes(button, 0.5); - } - }); + isPassword(el, form) { + const pwMatchers = this.matcherList('password'); + return !!this.subtypeFromMatchers(pwMatchers, el, form); } + /** + * Tries to infer if input is for email + * @param {HTMLInputElement} el + * @param {HTMLFormElement} form + * @return {boolean} + */ - elementIs(el, type) { - return el.nodeName.toLowerCase() === type.toLowerCase(); + + isEmail(el, form) { + const emailMatchers = this.matcherList('email'); + return !!this.subtypeFromMatchers(emailMatchers, el, form); } + /** + * Tries to infer if input is for username + * @param {HTMLInputElement} el + * @param {HTMLFormElement} form + * @return {boolean} + */ - getText(el) { - // for buttons, we don't care about descendants, just get the whole text as is - // this is important in order to give proper attribution of the text to the button - if (this.elementIs(el, 'BUTTON')) return el.innerText; - if (this.elementIs(el, 'INPUT') && ['submit', 'button'].includes(el.type)) return el.value; - return Array.from(el.childNodes).reduce((text, child) => this.elementIs(child, '#text') ? text + ' ' + child.textContent : text, ''); + + isUserName(el, form) { + const usernameMatchers = this.matcherList('username'); + return !!this.subtypeFromMatchers(usernameMatchers, el, form); } + /** + * Tries to infer if it's a credit card form + * @param {HTMLFormElement} formEl + * @returns {boolean} + */ - evaluateElement(el) { - const string = this.getText(el); - if (el.matches(PASSWORD_SELECTOR)) { - // These are explicit signals by the web author, so we weigh them heavily - this.updateSignal({ - string: el.getAttribute('autocomplete') || '', - strength: 20, - signalType: "explicit: ".concat(el.getAttribute('autocomplete')) - }); - } // check button contents + isCCForm(formEl) { + var _formEl$textContent; + const ccFieldSelector = this.joinCssSelectors('cc'); - if (el.matches(SUBMIT_BUTTON_SELECTOR)) { - // If we're sure this is a submit button, it's a stronger signal - const strength = el.getAttribute('type') === 'submit' ? 20 : 2; - this.updateSignal({ - string, - strength, - signalType: "submit: ".concat(string) - }); - } // if a link points to relevant urls or contain contents outside the page… + if (!ccFieldSelector) { + return false; + } + const hasCCSelectorChild = formEl.querySelector(ccFieldSelector); // If the form contains one of the specific selectors, we have high confidence - if (this.elementIs(el, 'A') && el.href && el.href !== '#' || (el.getAttribute('role') || '').toUpperCase() === 'LINK') { - // …and matches one of the regexes, we assume the match is not pertinent to the current form - this.updateSignal({ - string, - strength: 1, - signalType: "external link: ".concat(string), - shouldFlip: true - }); - } else { - var _el$innerText; + if (hasCCSelectorChild) return true; // Read form attributes to find a signal - // any other case - // only consider the el if it's a small text to avoid noisy disclaimers - if (((_el$innerText = el.innerText) === null || _el$innerText === void 0 ? void 0 : _el$innerText.length) < 50) { - this.updateSignal({ - string, - strength: 1, - signalType: "generic: ".concat(string), - shouldCheckUnifiedForm: true - }); - } - } + const hasCCAttribute = [...formEl.attributes].some(_ref => { + let { + name, + value + } = _ref; + return /(credit|payment).?card/i.test("".concat(name, "=").concat(value)); + }); + if (hasCCAttribute) return true; // Match form textContent against common cc fields (includes hidden labels) + + const textMatches = (_formEl$textContent = formEl.textContent) === null || _formEl$textContent === void 0 ? void 0 : _formEl$textContent.match(/(credit)?card(.?number)?|ccv|security.?code|cvv|cvc|csc/ig); // We check for more than one to minimise false positives + + return Boolean(textMatches && textMatches.length > 1); } + /** + * @type {MatchingConfiguration} + */ - evaluateForm() { - // Check page title - this.evaluatePageTitle(); // Check form attributes - this.evaluateElAttributes(this.form); // Check form contents (skip select and option because they contain too much noise) +} +/** + * @returns {SupportedTypes} + */ - this.form.querySelectorAll('*:not(select):not(option)').forEach(el => { - // Check if element is not hidden. Note that we can't use offsetHeight - // nor intersectionObserver, because the element could be outside the - // viewport or its parent hidden - const displayValue = window.getComputedStyle(el, null).getPropertyValue('display'); - if (displayValue !== 'none') this.evaluateElement(el); - }); // If we can't decide at this point, try reading page headings - if (this.autofillSignal === 0) { - this.evaluatePageHeadings(); +_defineProperty(Matching, "emptyConfig", { + matchers: { + lists: {}, + fields: {} + }, + strategies: { + 'vendorRegex': { + rules: {}, + ruleSets: [] + }, + 'ddgMatcher': { + matchers: {} + }, + 'cssSelector': { + selectors: {} } + } +}); - return this; +function getInputType(input) { + const attr = input.getAttribute(ATTR_INPUT_TYPE); + + if (isValidSupportedType(attr)) { + return attr; } + return 'unknown'; } +/** + * Retrieves the main type + * @param {SupportedTypes | string} type + * @returns {SupportedMainTypes} + */ -module.exports = FormAnalyzer; -},{"./selectors":9}],4:[function(require,module,exports){ -"use strict"; +function getMainTypeFromType(type) { + const mainType = type.split('.')[0]; -const { - CC_FIELD_SELECTOR, - DATE_SEPARATOR_REGEX, - CC_MATCHERS_LIST, - PASSWORD_MATCHER, - EMAIL_MATCHER, - USERNAME_MATCHER, - FOUR_DIGIT_YEAR_REGEX -} = require('./selectors'); + switch (mainType) { + case 'credentials': + case 'creditCard': + case 'identities': + return mainType; + } -const { - ATTR_INPUT_TYPE -} = require('../constants'); + return 'unknown'; +} /** - * Tests that a string matches a regex while not matching another - * @param {String} string - * @param {RegExp} regex - * @param {RegExp} negativeRegex - * @return {boolean} + * Retrieves the input main type + * @param {HTMLInputElement} input + * @returns {SupportedMainTypes} */ -const testAgainstRegexes = (string = '', regex, negativeRegex) => regex.test(string) && !(negativeRegex !== null && negativeRegex !== void 0 && negativeRegex.test(string)); +const getInputMainType = input => getMainTypeFromType(getInputType(input)); +/** @typedef {supportedIdentitiesSubtypes[number]} SupportedIdentitiesSubTypes */ + + +const supportedIdentitiesSubtypes = +/** @type {const} */ +['emailAddress', 'firstName', 'middleName', 'lastName', 'fullName', 'phone', 'addressStreet', 'addressStreet2', 'addressCity', 'addressProvince', 'addressPostalCode', 'addressCountryCode', 'birthdayDay', 'birthdayMonth', 'birthdayYear']; /** - * Get text from all explicit labels - * @param {HTMLInputElement} el - * @return {String} + * @param {SupportedTypes | any} supportedType + * @returns {supportedType is SupportedIdentitiesSubTypes} */ +function isValidIdentitiesSubtype(supportedType) { + return supportedIdentitiesSubtypes.includes(supportedType); +} +/** @typedef {supportedCreditCardSubtypes[number]} SupportedCreditCardSubTypes */ -const getExplicitLabelsText = el => { - var _document$getElementB; - const text = [...(el.labels || [])].reduce((text, label) => "".concat(text, " ").concat(label.textContent), ''); - const ariaLabel = el.getAttribute('aria-label') || ''; - const labelledByText = ((_document$getElementB = document.getElementById(el.getAttribute('aria-labelled'))) === null || _document$getElementB === void 0 ? void 0 : _document$getElementB.textContent) || ''; - return "".concat(text, " ").concat(ariaLabel, " ").concat(labelledByText); -}; +const supportedCreditCardSubtypes = +/** @type {const} */ +['cardName', 'cardNumber', 'cardSecurityCode', 'expirationMonth', 'expirationYear', 'expiration']; /** - * Get all text close to the input (useful when no labels are defined) - * @param {HTMLInputElement} el - * @param {HTMLFormElement} form - * @return {string} + * @param {SupportedTypes | any} supportedType + * @returns {supportedType is SupportedCreditCardSubTypes} */ +function isValidCreditCardSubtype(supportedType) { + return supportedCreditCardSubtypes.includes(supportedType); +} +/** @typedef {supportedCredentialsSubtypes[number]} SupportedCredentialsSubTypes */ + -const getRelatedText = (el, form) => { - const container = getLargestMeaningfulContainer(el, form); - return container.textContent; -}; +const supportedCredentialsSubtypes = +/** @type {const} */ +['password', 'username']; /** - * Find a container for the input field that won't contain other inputs (useful to get elements related to the field) - * @param {HTMLElement} el - * @param {HTMLFormElement} form - * @return {HTMLElement} + * @param {SupportedTypes | any} supportedType + * @returns {supportedType is SupportedCredentialsSubTypes} */ +function isValidCredentialsSubtype(supportedType) { + return supportedCredentialsSubtypes.includes(supportedType); +} +/** @typedef {SupportedIdentitiesSubTypes | SupportedCreditCardSubTypes | SupportedCredentialsSubTypes} SupportedSubTypes */ -const getLargestMeaningfulContainer = (el, form) => { - const parentElement = el.parentElement; - if (!parentElement || el === form) return el; - const inputsInScope = parentElement.querySelectorAll('input, select, textarea'); // To avoid noise, ensure that our input is the only in scope +/** @typedef {`identities.${SupportedIdentitiesSubTypes}` | `creditCard.${SupportedCreditCardSubTypes}` | `credentials.${SupportedCredentialsSubTypes}` | 'unknown'} SupportedTypes */ - if (inputsInScope.length === 1) { - return getLargestMeaningfulContainer(parentElement, form); - } - return el; -}; +const supportedTypes = [...supportedIdentitiesSubtypes.map(type => "identities.".concat(type)), ...supportedCreditCardSubtypes.map(type => "creditCard.".concat(type)), ...supportedCredentialsSubtypes.map(type => "credentials.".concat(type))]; /** - * Tries to infer input type, with checks in decreasing order of reliability - * @type (el: HTMLInputElement, form: HTMLFormElement, Matcher) => Boolean + * Retrieves the subtype + * @param {SupportedTypes | string} type + * @returns {SupportedSubTypes | 'unknown'} */ - -const checkMatch = (el, form, { - selector, - regex, - negativeRegex -}) => { - if (selector && el.matches(selector)) return true; - if (!regex) return false; - return testAgainstRegexes(getExplicitLabelsText(el), regex, negativeRegex) || testAgainstRegexes(el.id, regex, negativeRegex) || testAgainstRegexes(el.placeholder, regex, negativeRegex) || testAgainstRegexes(getRelatedText(el, form), regex, negativeRegex); -}; +function getSubtypeFromType(type) { + const subType = type === null || type === void 0 ? void 0 : type.split('.')[1]; + const validType = isValidSubtype(subType); + return validType ? subType : 'unknown'; +} /** - * Tries to infer if input is for password - * @type (el: HTMLInputElement, form: HTMLFormElement) => Boolean + * @param {SupportedSubTypes | any} supportedSubType + * @returns {supportedSubType is SupportedSubTypes} */ -const isPassword = (el, form) => checkMatch(el, form, PASSWORD_MATCHER); +function isValidSubtype(supportedSubType) { + return isValidIdentitiesSubtype(supportedSubType) || isValidCreditCardSubtype(supportedSubType) || isValidCredentialsSubtype(supportedSubType); +} /** - * Tries to infer if input is for email - * @type (el: HTMLInputElement, form: HTMLFormElement) => Boolean + * @param {SupportedTypes | any} supportedType + * @returns {supportedType is SupportedTypes} */ -const isEmail = (el, form) => checkMatch(el, form, EMAIL_MATCHER); +function isValidSupportedType(supportedType) { + return supportedTypes.includes(supportedType); +} /** - * Tries to infer if input is for username - * @type (el: HTMLInputElement, form: HTMLFormElement) => Boolean + * Retrieves the input subtype + * @param {HTMLInputElement|Element} input + * @returns {SupportedSubTypes | 'unknown'} */ -const isUserName = (el, form) => checkMatch(el, form, USERNAME_MATCHER); +function getInputSubtype(input) { + const type = getInputType(input); + return getSubtypeFromType(type); +} /** - * Tries to infer if it's a credit card form - * @param {HTMLFormElement} form - * @returns {boolean} + * Remove whitespace of more than 2 in a row and trim the string + * @param string + * @return {string} */ -const isCCForm = form => { - const hasCCSelectorChild = form.querySelector(CC_FIELD_SELECTOR); // If the form contains one of the specific selectors, we have high confidence - - if (hasCCSelectorChild) return true; // Read form attributes to find a signal - - const hasCCAttribute = [...form.attributes].some(({ - name, - value - }) => /(credit|payment).?card/i.test("".concat(name, "=").concat(value))); - if (hasCCAttribute) return true; // Match form textContent against common cc fields (includes hidden labels) - - const textMatches = form.textContent.match(/(credit)?card(.?number)?|ccv|security.?code|cvv|cvc|csc/ig); // We check for more than one to minimise false positives - - return (textMatches === null || textMatches === void 0 ? void 0 : textMatches.length) > 1; +const removeExcessWhitespace = function () { + let string = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; + return string.replace(/\n/g, ' ').replace(/\s{2,}/, ' ').trim(); }; /** - * Get a CC subtype based on selectors and regexes - * @param {HTMLInputElement} el - * @param {HTMLFormElement} form + * Get text from all explicit labels + * @param {HTMLInputElement|HTMLSelectElement} el * @return {string} */ -const getCCFieldSubtype = (el, form) => { - var _CC_MATCHERS_LIST$fin; +const getExplicitLabelsText = el => { + const labelTextCandidates = []; + + for (let label of el.labels || []) { + labelTextCandidates.push(...extractLabelStrings(label)); + } + + if (el.hasAttribute('aria-label')) { + labelTextCandidates.push(el.getAttribute('aria-label')); + } // Try to access another element if it was marked as the label for this input/select - return (_CC_MATCHERS_LIST$fin = CC_MATCHERS_LIST.find(sel => checkMatch(el, form, sel))) === null || _CC_MATCHERS_LIST$fin === void 0 ? void 0 : _CC_MATCHERS_LIST$fin.type; -}; -/** - * Tries to infer the input type - * @param {HTMLInputElement} input - * @param {Form} form - * @returns {SupportedSubTypes} - */ + const ariaLabelAttr = el.getAttribute('aria-labelled') || el.getAttribute('aria-labelledby') || ''; + const labelledByElement = document.getElementById(ariaLabelAttr); -const inferInputType = (input, form) => { - const presetType = input.getAttribute(ATTR_INPUT_TYPE); - if (presetType) return presetType; - const formEl = form.form; // For CC forms we run aggressive matches, so we want to make sure we only - // run them on actual CC forms to avoid false positives and expensive loops + if (labelledByElement) { + labelTextCandidates.push(...extractLabelStrings(labelledByElement)); + } - if (isCCForm(formEl)) { - const subtype = getCCFieldSubtype(input, formEl); - if (subtype) return "creditCard.".concat(subtype); + if (labelTextCandidates.length > 0) { + return removeExcessWhitespace(labelTextCandidates.join(' ')); } - if (isPassword(input, formEl)) return 'credentials.password'; - if (isEmail(input, formEl)) return form.isLogin ? 'credentials.username' : 'emailNew'; - if (isUserName(input, formEl)) return 'credentials.username'; - return 'unknown'; + return ''; }; /** - * Sets the input type as a data attribute to the element and returns it - * @param {HTMLInputElement} input - * @param {Form} form - * @returns {SupportedSubTypes} + * Get all text close to the input (useful when no labels are defined) + * @param {HTMLInputElement|HTMLSelectElement} el + * @param {HTMLFormElement} form + * @param {string} cssSelector + * @return {string} */ -const setInputType = (input, form) => { - const type = inferInputType(input, form); - input.setAttribute(ATTR_INPUT_TYPE, type); - return type; -}; -/** - * Retrieves the input main type - * @param {HTMLInputElement} input - * @returns {SupportedSubTypes} - */ +const getRelatedText = (el, form, cssSelector) => { + var _container$querySelec, _container$textConten; + const container = getLargestMeaningfulContainer(el, form, cssSelector); // If there is no meaningful container return empty string -const getInputMainType = input => { - var _input$getAttribute; + if (container === el || container.nodeName === 'SELECT') return ''; // If the container has a select element, remove its contents to avoid noise - return ((_input$getAttribute = input.getAttribute(ATTR_INPUT_TYPE)) === null || _input$getAttribute === void 0 ? void 0 : _input$getAttribute.split('.')[0]) || 'unknown'; + const noisyText = ((_container$querySelec = container.querySelector('select')) === null || _container$querySelec === void 0 ? void 0 : _container$querySelec.textContent) || ''; + const sanitizedText = removeExcessWhitespace((_container$textConten = container.textContent) === null || _container$textConten === void 0 ? void 0 : _container$textConten.replace(noisyText, '')); // If the text is longer than n chars it's too noisy and likely to yield false positives, so return '' + + if (sanitizedText.length < TEXT_LENGTH_CUTOFF) return sanitizedText; + return ''; }; /** - * Retrieves the input subtype - * @param {HTMLInputElement} input - * @returns {SupportedSubTypes} + * Find a container for the input field that won't contain other inputs (useful to get elements related to the field) + * @param {HTMLElement} el + * @param {HTMLFormElement} form + * @param {string} cssSelector + * @return {HTMLElement} */ -const getInputSubtype = input => { - var _input$getAttribute2, _input$getAttribute3; +const getLargestMeaningfulContainer = (el, form, cssSelector) => { + /* TODO: there could be more than one select el for the same label, in that case we should + change how we compute the container */ + const parentElement = el.parentElement; + if (!parentElement || el === form) return el; + const inputsInParentsScope = parentElement.querySelectorAll(cssSelector); // To avoid noise, ensure that our input is the only in scope + + if (inputsInParentsScope.length === 1) { + return getLargestMeaningfulContainer(parentElement, form, cssSelector); + } - return ((_input$getAttribute2 = input.getAttribute(ATTR_INPUT_TYPE)) === null || _input$getAttribute2 === void 0 ? void 0 : _input$getAttribute2.split('.')[1]) || ((_input$getAttribute3 = input.getAttribute(ATTR_INPUT_TYPE)) === null || _input$getAttribute3 === void 0 ? void 0 : _input$getAttribute3.split('.')[0]) || 'unknown'; + return el; }; /** * Find a regex match for a given input * @param {HTMLInputElement} input * @param {RegExp} regex * @param {HTMLFormElement} form + * @param {string} cssSelector * @returns {RegExpMatchArray|null} */ -const matchInPlaceholderAndLabels = (input, regex, form) => { +const matchInPlaceholderAndLabels = (input, regex, form, cssSelector) => { var _input$placeholder; - return ((_input$placeholder = input.placeholder) === null || _input$placeholder === void 0 ? void 0 : _input$placeholder.match(regex)) || getExplicitLabelsText(input).match(regex) || getRelatedText(input, form).match(regex); + return ((_input$placeholder = input.placeholder) === null || _input$placeholder === void 0 ? void 0 : _input$placeholder.match(regex)) || getExplicitLabelsText(input).match(regex) || getRelatedText(input, form, cssSelector).match(regex); }; /** * Check if a given input matches a regex * @param {HTMLInputElement} input * @param {RegExp} regex * @param {HTMLFormElement} form + * @param {string} cssSelector * @returns {boolean} */ -const checkPlaceholderAndLabels = (input, regex, form) => !!matchInPlaceholderAndLabels(input, regex, form); -/** - * Format the cc year to best adapt to the input requirements (YY vs YYYY) - * @param {HTMLInputElement} input - * @param {number} year - * @param {HTMLFormElement} form - * @returns {number} - */ - - -const formatCCYear = (input, year, form) => { - if (input.maxLength === 4 || checkPlaceholderAndLabels(input, FOUR_DIGIT_YEAR_REGEX, form)) return year; - return year - 2000; +const checkPlaceholderAndLabels = (input, regex, form, cssSelector) => { + return !!matchInPlaceholderAndLabels(input, regex, form, cssSelector); }; /** - * Get a unified expiry date with separator - * @param {HTMLInputElement} input - * @param {number} month - * @param {number} year - * @param {HTMLFormElement} form - * @returns {string} + * Creating Regex instances can throw, so we add this to be + * @param {string} string + * @returns {RegExp | undefined} string */ -const getUnifiedExpiryDate = (input, month, year, form) => { - var _matchInPlaceholderAn, _matchInPlaceholderAn2; - - const formattedYear = formatCCYear(input, year, form); - const paddedMonth = "".concat(month).padStart(2, '0'); - const separator = ((_matchInPlaceholderAn = matchInPlaceholderAndLabels(input, DATE_SEPARATOR_REGEX, form)) === null || _matchInPlaceholderAn === void 0 ? void 0 : (_matchInPlaceholderAn2 = _matchInPlaceholderAn.groups) === null || _matchInPlaceholderAn2 === void 0 ? void 0 : _matchInPlaceholderAn2.separator) || '/'; - return "".concat(paddedMonth).concat(separator).concat(formattedYear); +const safeRegex = string => { + try { + // This is lower-cased here because giving a `i` on a regex flag is a performance problem in some cases + const input = String(string).toLowerCase().normalize('NFKC'); + return new RegExp(input, 'u'); + } catch (e) { + console.warn('Could not generate regex from string input', string); + return undefined; + } }; module.exports = { - isPassword, - isEmail, - isUserName, - getCCFieldSubtype, - inferInputType, - setInputType, - getInputMainType, + getInputType, getInputSubtype, - formatCCYear, - getUnifiedExpiryDate + getSubtypeFromType, + removeExcessWhitespace, + getInputMainType, + getMainTypeFromType, + getExplicitLabelsText, + getRelatedText, + matchInPlaceholderAndLabels, + checkPlaceholderAndLabels, + safeRegex, + Matching +}; + +},{"../constants":38,"./label-util":18,"./vendor-regex":24}],23:[function(require,module,exports){ +"use strict"; + +const FORM_INPUTS_SELECTOR = "\ninput:not([type=submit]):not([type=button]):not([type=checkbox]):not([type=radio]):not([type=hidden]):not([type=file]),\nselect"; +const SUBMIT_BUTTON_SELECTOR = "\ninput[type=submit],\ninput[type=button],\nbutton:not([role=switch]):not([role=link]),\n[role=button]"; +const email = "\ninput:not([type])[name*=mail i],\ninput[type=\"\"][name*=mail i],\ninput[type=text][name*=mail i],\ninput:not([type])[placeholder*=mail i]:not([placeholder*=search i]),\ninput[type=text][placeholder*=mail i]:not([placeholder*=search i]),\ninput[type=\"\"][placeholder*=mail i]:not([placeholder*=search i]),\ninput:not([type])[placeholder*=mail i]:not([placeholder*=search i]),\ninput[type=email],\ninput[type=text][aria-label*=mail i]:not([aria-label*=search i]),\ninput:not([type])[aria-label*=mail i]:not([aria-label*=search i]),\ninput[type=text][placeholder*=mail i]:not([placeholder*=search i]),\ninput[autocomplete=email]"; // We've seen non-standard types like 'user'. This selector should get them, too + +const GENERIC_TEXT_FIELD = "\ninput:not([type=button]):not([type=checkbox]):not([type=color]):not([type=date]):not([type=datetime-local]):not([type=datetime]):not([type=file]):not([type=hidden]):not([type=month]):not([type=number]):not([type=radio]):not([type=range]):not([type=reset]):not([type=search]):not([type=submit]):not([type=time]):not([type=url]):not([type=week])"; +const password = "input[type=password]:not([autocomplete*=cc]):not([autocomplete=one-time-code])"; +const cardName = "\ninput[autocomplete=\"cc-name\"],\ninput[autocomplete=\"ccname\"],\ninput[name=\"ccname\"],\ninput[name=\"cc-name\"],\ninput[name=\"ppw-accountHolderName\"],\ninput[id*=cardname i],\ninput[id*=card-name i],\ninput[id*=card_name i]"; +const cardNumber = "\ninput[autocomplete=\"cc-number\"],\ninput[autocomplete=\"ccnumber\"],\ninput[autocomplete=\"cardnumber\"],\ninput[autocomplete=\"card-number\"],\ninput[name=\"ccnumber\"],\ninput[name=\"cc-number\"],\ninput[name=\"cardnumber\"],\ninput[name=\"card-number\"],\ninput[name*=creditCardNumber i],\ninput[id*=cardnumber i],\ninput[id*=card-number i],\ninput[id*=card_number i]"; +const cardSecurityCode = "\ninput[autocomplete=\"cc-csc\"],\ninput[autocomplete=\"csc\"],\ninput[autocomplete=\"cc-cvc\"],\ninput[autocomplete=\"cvc\"],\ninput[name=\"cvc\"],\ninput[name=\"cc-cvc\"],\ninput[name=\"cc-csc\"],\ninput[name=\"csc\"],\ninput[name=\"securityCode\"]"; +const expirationMonth = "\n[autocomplete=\"cc-exp-month\"],\n[name=\"ccmonth\"],\n[name=\"ppw-expirationDate_month\"],\n[name=cardExpiryMonth],\n[name=\"expiration-month\"],\n[name*=ExpDate_Month i],\n[id*=expiration-month i]"; +const expirationYear = "\n[autocomplete=\"cc-exp-year\"],\n[name=\"ccyear\"],\n[name=\"ppw-expirationDate_year\"],\n[name=cardExpiryYear],\n[name=\"expiration-year\"],\n[name*=ExpDate_Year i],\n[id*=expiration-year i]"; +const expiration = "\n[autocomplete=\"cc-exp\"],\n[name=\"cc-exp\"],\n[name=\"exp-date\"],\n[name=\"expirationDate\"],\ninput[id*=expiration i]"; +const firstName = "\n[name*=fname i], [autocomplete*=given-name i],\n[name*=firstname i], [autocomplete*=firstname i],\n[name*=first-name i], [autocomplete*=first-name i],\n[name*=first_name i], [autocomplete*=first_name i],\n[name*=givenname i], [autocomplete*=givenname i],\n[name*=given-name i],\n[name*=given_name i], [autocomplete*=given_name i],\n[name*=forename i], [autocomplete*=forename i]"; +const middleName = "\n[name*=mname i], [autocomplete*=additional-name i],\n[name*=middlename i], [autocomplete*=middlename i],\n[name*=middle-name i], [autocomplete*=middle-name i],\n[name*=middle_name i], [autocomplete*=middle_name i],\n[name*=additionalname i], [autocomplete*=additionalname i],\n[name*=additional-name i],\n[name*=additional_name i], [autocomplete*=additional_name i]"; +const lastName = "\n[name=lname], [autocomplete*=family-name i],\n[name*=lastname i], [autocomplete*=lastname i],\n[name*=last-name i], [autocomplete*=last-name i],\n[name*=last_name i], [autocomplete*=last_name i],\n[name*=familyname i], [autocomplete*=familyname i],\n[name*=family-name i],\n[name*=family_name i], [autocomplete*=family_name i],\n[name*=surname i], [autocomplete*=surname i]"; +const fullName = "\n[name=name], [autocomplete=name],\n[name*=fullname i], [autocomplete*=fullname i],\n[name*=full-name i], [autocomplete*=full-name i],\n[name*=full_name i], [autocomplete*=full_name i],\n[name*=your-name i], [autocomplete*=your-name i]"; +const phone = "\n[name*=phone i], [name*=mobile i], [autocomplete=tel]"; +const addressStreet1 = "\n[name=address], [autocomplete=street-address], [autocomplete=address-line1],\n[name=street],\n[name=ppw-line1]"; +const addressStreet2 = "\n[name=address], [autocomplete=address-line2],\n[name=ppw-line2]"; +const addressCity = "\n[name=city], [autocomplete=address-level2],\n[name=ppw-city]"; +const addressProvince = "\n[name=province], [name=state], [autocomplete=address-level1]"; +const addressPostalCode = "\n[name=zip], [name=zip2], [name=postal], [autocomplete=postal-code], [autocomplete=zip-code],\n[name*=postalCode i], [name*=zipcode i]"; +const addressCountryCode = "\n[name=country], [autocomplete=country],\n[name*=countryCode i], [name*=country-code i],\n[name*=countryName i], [name*=country-name i]"; +const birthdayDay = "\n[name=bday-day],\n[name=birthday_day], [name=birthday-day],\n[name=date_of_birth_day], [name=date-of-birth-day],\n[name^=birthdate_d], [name^=birthdate-d]"; +const birthdayMonth = "\n[name=bday-month],\n[name=birthday_month], [name=birthday-month],\n[name=date_of_birth_month], [name=date-of-birth-month],\n[name^=birthdate_m], [name^=birthdate-m]"; +const birthdayYear = "\n[name=bday-year],\n[name=birthday_year], [name=birthday-year],\n[name=date_of_birth_year], [name=date-of-birth-year],\n[name^=birthdate_y], [name^=birthdate-y]"; +const username = ["".concat(GENERIC_TEXT_FIELD, "[autocomplete^=user]"), // fix for `aa.com` +"input[name=\"loginId\"]"]; // todo: these are still used directly right now, mostly in scanForInputs +// todo: ensure these can be set via configuration + +module.exports.FORM_INPUTS_SELECTOR = FORM_INPUTS_SELECTOR; +module.exports.SUBMIT_BUTTON_SELECTOR = SUBMIT_BUTTON_SELECTOR; // Exported here for now, to be moved to configuration later + +module.exports.__secret_do_not_use = { + GENERIC_TEXT_FIELD, + SUBMIT_BUTTON_SELECTOR, + FORM_INPUTS_SELECTOR, + email: email, + password, + username, + cardName, + cardNumber, + cardSecurityCode, + expirationMonth, + expirationYear, + expiration, + firstName, + middleName, + lastName, + fullName, + phone, + addressStreet1, + addressStreet2, + addressCity, + addressProvince, + addressPostalCode, + addressCountryCode, + birthdayDay, + birthdayMonth, + birthdayYear }; -},{"../constants":19,"./selectors":9}],5:[function(require,module,exports){ +},{}],24:[function(require,module,exports){ "use strict"; -const getInputConfig = require('./inputTypeConfig.js'); /** - * Get inline styles for the injected icon, base state - * @param {HTMLInputElement} input - * @return {Object} + * Given some ruleSets, create an efficient + * lookup system for accessing cached regexes by name. + * + * @param {VendorRegexConfiguration["rules"]} rules + * @param {VendorRegexConfiguration["ruleSets"]} ruleSets + * @return {{RULES: Record}} */ +function createCacheableVendorRegexes(rules, ruleSets) { + const vendorRegExp = { + RULES: rules, + RULE_SETS: ruleSets, + + _getRule(name) { + let rules = []; + this.RULE_SETS.forEach(set => { + if (set[name]) { + var _set$name; + + // Add the rule. + // We make the regex lower case so that we can match it against the + // lower-cased field name and get a rough equivalent of a case-insensitive + // match. This avoids a performance cliff with the "iu" flag on regular + // expressions. + rules.push("(".concat((_set$name = set[name]) === null || _set$name === void 0 ? void 0 : _set$name.toLowerCase(), ")").normalize('NFKC')); + } + }); + const value = new RegExp(rules.join('|'), 'u'); + Object.defineProperty(this.RULES, name, { + get: undefined + }); + Object.defineProperty(this.RULES, name, { + value + }); + return value; + }, + init() { + Object.keys(this.RULES).forEach(field => Object.defineProperty(this.RULES, field, { + get() { + return vendorRegExp._getRule(field); + } + + })); + } -const getIconStylesBase = input => { - const config = getInputConfig(input); - const icon = config.getIconBase(); - if (!icon) return {}; - return { - // Height must be > 0 to account for fields initially hidden - 'background-size': "auto ".concat(input.offsetHeight <= 30 && input.offsetHeight > 0 ? '100%' : '26px'), - 'background-position': 'center right', - 'background-repeat': 'no-repeat', - 'background-origin': 'content-box', - 'background-image': "url(".concat(icon, ")"), - 'transition': 'background 0s' }; -}; + vendorRegExp.init(); // @ts-ignore + + return vendorRegExp; +} + +module.exports.createCacheableVendorRegexes = createCacheableVendorRegexes; + +},{}],25:[function(require,module,exports){ +"use strict"; + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); } + +function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } } + +function _classPrivateFieldGet(receiver, privateMap) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "get"); return _classApplyDescriptorGet(receiver, descriptor); } + +function _classApplyDescriptorGet(receiver, descriptor) { if (descriptor.get) { return descriptor.get.call(receiver); } return descriptor.value; } + +function _classPrivateFieldSet(receiver, privateMap, value) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "set"); _classApplyDescriptorSet(receiver, descriptor, value); return value; } + +function _classExtractFieldDescriptor(receiver, privateMap, action) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to " + action + " private field on non-instance"); } return privateMap.get(receiver); } + +function _classApplyDescriptorSet(receiver, descriptor, value) { if (descriptor.set) { descriptor.set.call(receiver, value); } else { if (!descriptor.writable) { throw new TypeError("attempted to set read only private field"); } descriptor.value = value; } } + +const GENERATED_ID = '__generated__'; /** - * Get inline styles for the injected icon, autofilled state - * @param {HTMLInputElement} input + * @implements {TooltipItemRenderer} */ +var _data = /*#__PURE__*/new WeakMap(); -const getIconStylesAutofilled = input => { - const config = getInputConfig(input); - const icon = config.getIconBase(); - const iconStyle = icon ? { - 'background-image': "url(".concat(icon) - } : {}; - return { ...iconStyle, - 'background-color': '#F8F498', - 'color': '#333333' +class CredentialsTooltipItem { + /** @type {CredentialsObject} */ + + /** @param {CredentialsObject} data */ + constructor(data) { + _classPrivateFieldInitSpec(this, _data, { + writable: true, + value: void 0 + }); + + _defineProperty(this, "id", () => String(_classPrivateFieldGet(this, _data).id)); + + _classPrivateFieldSet(this, _data, data); + } + + labelMedium(_subtype) { + if (_classPrivateFieldGet(this, _data).id === GENERATED_ID) { + return 'Generated password'; + } + + return _classPrivateFieldGet(this, _data).username; + } + + labelSmall(_subtype) { + if (_classPrivateFieldGet(this, _data).id === GENERATED_ID && _classPrivateFieldGet(this, _data).password) { + return _classPrivateFieldGet(this, _data).password; + } + + return '•••••••••••••••'; + } + +} +/** + * Generate a stand-in 'CredentialsObject' from a + * given (generated) password. + * + * @param {string} password + * @returns {CredentialsObject} + */ + + +function fromPassword(password) { + return { + id: GENERATED_ID, + password: password, + username: '' }; -}; +} -module.exports = { - getIconStylesBase, - getIconStylesAutofilled -}; +module.exports.CredentialsTooltipItem = CredentialsTooltipItem; +module.exports.fromPassword = fromPassword; +module.exports.GENERATED_ID = GENERATED_ID; -},{"./inputTypeConfig.js":6}],6:[function(require,module,exports){ +},{}],26:[function(require,module,exports){ "use strict"; -const { - isDDGApp, - isMobileApp -} = require('../autofill-utils'); +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } -const { - daxBase64 -} = require('./logo-svg'); +function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); } -const ddgPasswordIcons = require('../UI/img/ddgPasswordIcon'); +function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } } -const { - getInputMainType -} = require('./input-classifiers'); // In Firefox web_accessible_resources could leak a unique user identifier, so we avoid it here +function _classPrivateFieldGet(receiver, privateMap) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "get"); return _classApplyDescriptorGet(receiver, descriptor); } +function _classApplyDescriptorGet(receiver, descriptor) { if (descriptor.get) { return descriptor.get.call(receiver); } return descriptor.value; } + +function _classPrivateFieldSet(receiver, privateMap, value) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "set"); _classApplyDescriptorSet(receiver, descriptor, value); return value; } + +function _classExtractFieldDescriptor(receiver, privateMap, action) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to " + action + " private field on non-instance"); } return privateMap.get(receiver); } + +function _classApplyDescriptorSet(receiver, descriptor, value) { if (descriptor.set) { descriptor.set.call(receiver, value); } else { if (!descriptor.writable) { throw new TypeError("attempted to set read only private field"); } descriptor.value = value; } } + +var _data = /*#__PURE__*/new WeakMap(); -const isFirefox = navigator.userAgent.includes('Firefox'); -const getDaxImg = isDDGApp || isFirefox ? daxBase64 : chrome.runtime.getURL('img/logo-small.svg'); /** - * A map of config objects. These help by centralising here some of the complexity - * @type {Object} + * @implements {TooltipItemRenderer} */ +class CreditCardTooltipItem { + /** @type {CreditCardObject} */ -const inputTypeConfig = { - emailNew: { - type: 'emailNew', - getIconBase: () => getDaxImg, - getIconFilled: () => getDaxImg, - shouldDecorate: (isLogin, device) => { - if (isMobileApp) return device.isDeviceSignedIn(); - return device.hasLocalAddresses; - }, - dataType: 'Addresses', - displayTitlePropName: '', - displaySubtitlePropName: '', - autofillMethod: '' - }, - credentials: { - type: 'credentials', - getIconBase: () => ddgPasswordIcons.ddgPasswordIconBase, - getIconFilled: () => ddgPasswordIcons.ddgPasswordIconFilled, - shouldDecorate: (isLogin, device) => isLogin && device.hasLocalCredentials, - dataType: 'Credentials', - displayTitlePropName: 'username', - displaySubtitlePropName: '•••••••••••••••', - autofillMethod: 'getAutofillCredentials' - }, - creditCard: { - type: 'creditCard', - getIconBase: () => '', - getIconFilled: () => '', - shouldDecorate: (isLogin, device) => device.hasLocalCreditCards, - dataType: 'CreditCards', - displayTitlePropName: 'title', - displaySubtitlePropName: 'displayNumber', - autofillMethod: 'getAutofillCreditCard' - }, - unknown: { - type: 'unknown', - getIconBase: () => '', - getIconFilled: () => '', - shouldDecorate: () => false, - dataType: '', - displayTitlePropName: '', - displaySubtitlePropName: '', - autofillMethod: '' + /** @param {CreditCardObject} data */ + constructor(data) { + _classPrivateFieldInitSpec(this, _data, { + writable: true, + value: void 0 + }); + + _defineProperty(this, "id", () => String(_classPrivateFieldGet(this, _data).id)); + + _defineProperty(this, "labelMedium", _ => _classPrivateFieldGet(this, _data).title); + + _defineProperty(this, "labelSmall", _ => _classPrivateFieldGet(this, _data).displayNumber); + + _classPrivateFieldSet(this, _data, data); } -}; -/** - * Retrieves configs from an input el - * @param {HTMLInputElement} input - * @returns {InputTypeConfig} - */ -const getInputConfig = input => { - const inputType = getInputMainType(input); - return inputTypeConfig[inputType || 'unknown']; -}; +} -module.exports = getInputConfig; +module.exports.CreditCardTooltipItem = CreditCardTooltipItem; -},{"../UI/img/ddgPasswordIcon":13,"../autofill-utils":17,"./input-classifiers":4,"./logo-svg":8}],7:[function(require,module,exports){ +},{}],27:[function(require,module,exports){ "use strict"; +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); } + +function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } } + +function _classPrivateFieldGet(receiver, privateMap) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "get"); return _classApplyDescriptorGet(receiver, descriptor); } + +function _classApplyDescriptorGet(receiver, descriptor) { if (descriptor.get) { return descriptor.get.call(receiver); } return descriptor.value; } + +function _classPrivateFieldSet(receiver, privateMap, value) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "set"); _classApplyDescriptorSet(receiver, descriptor, value); return value; } + +function _classExtractFieldDescriptor(receiver, privateMap, action) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to " + action + " private field on non-instance"); } return privateMap.get(receiver); } + +function _classApplyDescriptorSet(receiver, descriptor, value) { if (descriptor.set) { descriptor.set.call(receiver, value); } else { if (!descriptor.writable) { throw new TypeError("attempted to set read only private field"); } descriptor.value = value; } } + const { - forms -} = require('../scanForInputs'); + getCountryDisplayName +} = require('../Form/formatters'); +/** + * @implements {TooltipItemRenderer} + */ -const isApp = require('../autofill-utils'); -const listenForGlobalFormSubmission = () => { - if (!isApp) return; +var _data = /*#__PURE__*/new WeakMap(); - try { - const observer = new PerformanceObserver(list => { - const entries = list.getEntries().filter(entry => ['fetch', 'xmlhttprequest'].includes(entry.initiatorType) && entry.name.match(/login|sign-in|signin|session/)); - if (!entries.length) return; - const filledForm = [...forms.values()].find(form => form.hasValues()); - filledForm === null || filledForm === void 0 ? void 0 : filledForm.submitHandler(); +class IdentityTooltipItem { + /** @type {IdentityObject} */ + + /** @param {IdentityObject} data */ + constructor(data) { + _classPrivateFieldInitSpec(this, _data, { + writable: true, + value: void 0 }); - observer.observe({ - entryTypes: ['resource'] + + _defineProperty(this, "id", () => String(_classPrivateFieldGet(this, _data).id)); + + _defineProperty(this, "labelMedium", subtype => { + if (subtype === 'addressCountryCode') { + return getCountryDisplayName('en', _classPrivateFieldGet(this, _data).addressCountryCode || ''); + } + + if (_classPrivateFieldGet(this, _data).id === 'privateAddress') { + return 'Generated Private Address'; + } + + return _classPrivateFieldGet(this, _data)[subtype]; + }); + + _defineProperty(this, "labelSmall", _ => { + return _classPrivateFieldGet(this, _data).title; + }); + + _classPrivateFieldSet(this, _data, data); + } + + label(subtype) { + if (_classPrivateFieldGet(this, _data).id === 'privateAddress') { + return _classPrivateFieldGet(this, _data)[subtype]; + } + + return null; + } + +} + +module.exports.IdentityTooltipItem = IdentityTooltipItem; + +},{"../Form/formatters":15}],28:[function(require,module,exports){ +"use strict"; + +function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); } + +function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } } + +function _classPrivateFieldSet(receiver, privateMap, value) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "set"); _classApplyDescriptorSet(receiver, descriptor, value); return value; } + +function _classApplyDescriptorSet(receiver, descriptor, value) { if (descriptor.set) { descriptor.set.call(receiver, value); } else { if (!descriptor.writable) { throw new TypeError("attempted to set read only private field"); } descriptor.value = value; } } + +function _classPrivateFieldGet(receiver, privateMap) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "get"); return _classApplyDescriptorGet(receiver, descriptor); } + +function _classExtractFieldDescriptor(receiver, privateMap, action) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to " + action + " private field on non-instance"); } return privateMap.get(receiver); } + +function _classApplyDescriptorGet(receiver, descriptor) { if (descriptor.get) { return descriptor.get.call(receiver); } return descriptor.value; } + +const { + generate +} = require('../packages/password'); + +const rules = require('../packages/password/rules.json'); +/** + * Create a password once and reuse it. + */ + + +var _previous = /*#__PURE__*/new WeakMap(); + +class PasswordGenerator { + constructor() { + _classPrivateFieldInitSpec(this, _previous, { + writable: true, + value: null }); - } catch (error) {// Unable to detect form submissions using AJAX calls } -}; -module.exports = listenForGlobalFormSubmission; + /** @returns {boolean} */ + get generated() { + return _classPrivateFieldGet(this, _previous) !== null; + } + /** @param {import('../packages/password').GenerateOptions} [params] */ -},{"../autofill-utils":17,"../scanForInputs":21}],8:[function(require,module,exports){ -"use strict"; -const daxBase64 = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgNDQgNDQiIHdpZHRoPSIyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+PGxpbmVhckdyYWRpZW50IGlkPSJhIj48c3RvcCBvZmZzZXQ9Ii4wMSIgc3RvcC1jb2xvcj0iIzYxNzZiOSIvPjxzdG9wIG9mZnNldD0iLjY5IiBzdG9wLWNvbG9yPSIjMzk0YTlmIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImIiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMTMuOTI5NyIgeDI9IjE3LjA3MiIgeGxpbms6aHJlZj0iI2EiIHkxPSIxNi4zOTgiIHkyPSIxNi4zOTgiLz48bGluZWFyR3JhZGllbnQgaWQ9ImMiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMjMuODExNSIgeDI9IjI2LjY3NTIiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMTQuOTY3OSIgeTI9IjE0Ljk2NzkiLz48bWFzayBpZD0iZCIgaGVpZ2h0PSI0MCIgbWFza1VuaXRzPSJ1c2VyU3BhY2VPblVzZSIgd2lkdGg9IjQwIiB4PSIyIiB5PSIyIj48cGF0aCBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Im0yMi4wMDAzIDQxLjA2NjljMTAuNTMwMiAwIDE5LjA2NjYtOC41MzY0IDE5LjA2NjYtMTkuMDY2NiAwLTEwLjUzMDMtOC41MzY0LTE5LjA2NjcxLTE5LjA2NjYtMTkuMDY2NzEtMTAuNTMwMyAwLTE5LjA2NjcxIDguNTM2NDEtMTkuMDY2NzEgMTkuMDY2NzEgMCAxMC41MzAyIDguNTM2NDEgMTkuMDY2NiAxOS4wNjY3MSAxOS4wNjY2eiIgZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIi8+PC9tYXNrPjxwYXRoIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0ibTIyIDQ0YzEyLjE1MDMgMCAyMi05Ljg0OTcgMjItMjIgMC0xMi4xNTAyNi05Ljg0OTctMjItMjItMjItMTIuMTUwMjYgMC0yMiA5Ljg0OTc0LTIyIDIyIDAgMTIuMTUwMyA5Ljg0OTc0IDIyIDIyIDIyeiIgZmlsbD0iI2RlNTgzMyIgZmlsbC1ydWxlPSJldmVub2RkIi8+PGcgbWFzaz0idXJsKCNkKSI+PHBhdGggY2xpcC1ydWxlPSJldmVub2RkIiBkPSJtMjYuMDgxMyA0MS42Mzg2Yy0uOTIwMy0xLjc4OTMtMS44MDAzLTMuNDM1Ni0yLjM0NjYtNC41MjQ2LTEuNDUyLTIuOTA3Ny0yLjkxMTQtNy4wMDctMi4yNDc3LTkuNjUwNy4xMjEtLjQ4MDMtMS4zNjc3LTE3Ljc4Njk5LTIuNDItMTguMzQ0MzItMS4xNjk3LS42MjMzMy0zLjcxMDctMS40NDQ2Ny01LjAyNy0xLjY2NDY3LS45MTY3LS4xNDY2Ni0xLjEyNTcuMTEtMS41MTA3LjE2ODY3LjM2My4wMzY2NyAyLjA5Ljg4NzMzIDIuNDIzNy45MzUtLjMzMzcuMjI3MzMtMS4zMi0uMDA3MzMtMS45NTA3LjI3MTMzLS4zMTkuMTQ2NjctLjU1NzMuNjg5MzQtLjU1Ljk0NiAxLjc5NjctLjE4MzMzIDQuNjA1NC0uMDAzNjYgNi4yNy43MzMyOS0xLjMyMzYuMTUwNC0zLjMzMy4zMTktNC4xOTgzLjc3MzctMi41MDggMS4zMi0zLjYxNTMgNC40MTEtMi45NTUzIDguMTE0My42NTYzIDMuNjk2IDMuNTY0IDE3LjE3ODQgNC40OTE2IDIxLjY4MS45MjQgNC40OTkgMTEuNTUzNyAzLjU1NjcgMTAuMDE3NC41NjF6IiBmaWxsPSIjZDVkN2Q4IiBmaWxsLXJ1bGU9ImV2ZW5vZGQiLz48cGF0aCBkPSJtMjIuMjg2NSAyNi44NDM5Yy0uNjYgMi42NDM2Ljc5MiA2LjczOTMgMi4yNDc2IDkuNjUwNi40ODkxLjk3MjcgMS4yNDM4IDIuMzkyMSAyLjA1NTggMy45NjM3LTEuODk0LjQ2OTMtNi40ODk1IDEuMTI2NC05LjcxOTEgMC0uOTI0LTQuNDkxNy0zLjgzMTctMTcuOTc3Ny00LjQ5NTMtMjEuNjgxLS42Ni0zLjcwMzMgMC02LjM0NyAyLjUxNTMtNy42NjcuODYxNy0uNDU0NyAyLjA5MzctLjc4NDcgMy40MTM3LS45MzEzLTEuNjY0Ny0uNzQwNy0zLjYzNzQtMS4wMjY3LTUuNDQxNC0uODQzMzYtLjAwNzMtLjc2MjY3IDEuMzM4NC0uNzE4NjcgMS44NDQ0LTEuMDYzMzQtLjMzMzctLjA0NzY2LTEuMTYyNC0uNzk1NjYtMS41MjktLjgzMjMzIDIuMjg4My0uMzkyNDQgNC42NDIzLS4wMjEzOCA2LjY5OSAxLjA1NiAxLjA0ODYuNTYxIDEuNzg5MyAxLjE2MjMzIDIuMjQ3NiAxLjc5MzAzIDEuMTk1NC4yMjczIDIuMjUxNC42NiAyLjk0MDcgMS4zNDkzIDIuMTE5MyAyLjExNTcgNC4wMTEzIDYuOTUyIDMuMjE5MyA5LjczMTMtLjIyMzYuNzctLjczMzMgMS4zMzEtMS4zNzEzIDEuNzk2Ny0xLjIzOTMuOTAyLTEuMDE5My0xLjA0NS00LjEwMy45NzE3LS4zOTk3LjI2MDMtLjM5OTcgMi4yMjU2LS41MjQzIDIuNzA2eiIgZmlsbD0iI2ZmZiIvPjwvZz48ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCI+PHBhdGggZD0ibTE2LjY3MjQgMjAuMzU0Yy43Njc1IDAgMS4zODk2LS42MjIxIDEuMzg5Ni0xLjM4OTZzLS42MjIxLTEuMzg5Ny0xLjM4OTYtMS4zODk3LTEuMzg5Ny42MjIyLTEuMzg5NyAxLjM4OTcuNjIyMiAxLjM4OTYgMS4zODk3IDEuMzg5NnoiIGZpbGw9IiMyZDRmOGUiLz48cGF0aCBkPSJtMTcuMjkyNCAxOC44NjE3Yy4xOTg1IDAgLjM1OTQtLjE2MDguMzU5NC0uMzU5M3MtLjE2MDktLjM1OTMtLjM1OTQtLjM1OTNjLS4xOTg0IDAtLjM1OTMuMTYwOC0uMzU5My4zNTkzcy4xNjA5LjM1OTMuMzU5My4zNTkzeiIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Im0yNS45NTY4IDE5LjMzMTFjLjY1ODEgMCAxLjE5MTctLjUzMzUgMS4xOTE3LTEuMTkxNyAwLS42NTgxLS41MzM2LTEuMTkxNi0xLjE5MTctMS4xOTE2cy0xLjE5MTcuNTMzNS0xLjE5MTcgMS4xOTE2YzAgLjY1ODIuNTMzNiAxLjE5MTcgMS4xOTE3IDEuMTkxN3oiIGZpbGw9IiMyZDRmOGUiLz48cGF0aCBkPSJtMjYuNDg4MiAxOC4wNTExYy4xNzAxIDAgLjMwOC0uMTM3OS4zMDgtLjMwOHMtLjEzNzktLjMwOC0uMzA4LS4zMDgtLjMwOC4xMzc5LS4zMDguMzA4LjEzNzkuMzA4LjMwOC4zMDh6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTE3LjA3MiAxNC45NDJzLTEuMDQ4Ni0uNDc2Ni0yLjA2NDMuMTY1Yy0xLjAxNTcuNjM4LS45NzkgMS4yOTA3LS45NzkgMS4yOTA3cy0uNTM5LTEuMjAyNy44OTgzLTEuNzkzYzEuNDQxLS41ODY3IDIuMTQ1LjMzNzMgMi4xNDUuMzM3M3oiIGZpbGw9InVybCgjYikiLz48cGF0aCBkPSJtMjYuNjc1MiAxNC44NDY3cy0uNzUxNy0uNDI5LTEuMzM4My0uNDIxN2MtMS4xOTkuMDE0Ny0xLjUyNTQuNTQyNy0xLjUyNTQuNTQyN3MuMjAxNy0xLjI2MTQgMS43MzQ0LTEuMDA4NGMuNDk5Ny4wOTE0LjkyMjMuNDIzNCAxLjEyOTMuODg3NHoiIGZpbGw9InVybCgjYykiLz48cGF0aCBkPSJtMjAuOTI1OCAyNC4zMjFjLjEzOTMtLjg0MzMgMi4zMS0yLjQzMSAzLjg1LTIuNTMgMS41NC0uMDk1MyAyLjAxNjctLjA3MzMgMy4zLS4zODEzIDEuMjg3LS4zMDQzIDQuNTk4LTEuMTI5MyA1LjUxMS0xLjU1NDcuOTE2Ny0uNDIxNiA0LjgwMzMuMjA5IDIuMDY0MyAxLjczOC0xLjE4NDMuNjYzNy00LjM3OCAxLjg4MS02LjY2MjMgMi41NjMtMi4yODA3LjY4Mi0zLjY2My0uNjUyNi00LjQyMi40Njk0LS42MDEzLjg5MS0uMTIxIDIuMTEyIDIuNjAzMyAyLjM2NSAzLjY4MTQuMzQxIDcuMjA4Ny0xLjY1NzQgNy41OTc0LS41OTQuMzg4NiAxLjA2MzMtMy4xNjA3IDIuMzgzMy01LjMyNCAyLjQyNzMtMi4xNjM0LjA0MDMtNi41MTk0LTEuNDMtNy4xNzItMS44ODQ3LS42NTY0LS40NTEtMS41MjU0LTEuNTE0My0xLjM0NTctMi42MTh6IiBmaWxsPSIjZmRkMjBhIi8+PHBhdGggZD0ibTI4Ljg4MjUgMzEuODM4NmMtLjc3NzMtLjE3MjQtNC4zMTIgMi41MDA2LTQuMzEyIDIuNTAwNmguMDAzN2wtLjE2NSAyLjA1MzRzNC4wNDA2IDEuNjUzNiA0LjczIDEuMzk3Yy42ODkzLS4yNjQuNTE3LTUuNzc1LS4yNTY3LTUuOTUxem0tMTEuNTQ2MyAxLjAzNGMuMDg0My0xLjExODQgNS4yNTQzIDEuNjQyNiA1LjI1NDMgMS42NDI2bC4wMDM3LS4wMDM2LjI1NjYgMi4xNTZzLTQuMzA4MyAyLjU4MTMtNC45MTMzIDIuMjM2NmMtLjYwMTMtLjM0NDYtLjY4OTMtNC45MDk2LS42MDEzLTYuMDMxNnoiIGZpbGw9IiM2NWJjNDYiLz48cGF0aCBkPSJtMjEuMzQgMzQuODA0OWMwIDEuODA3Ny0uMjYwNCAyLjU4NS41MTMzIDIuNzU3NC43NzczLjE3MjMgMi4yNDAzIDAgMi43NjEtLjM0NDcuNTEzMy0uMzQ0Ny4wODQzLTIuNjY5My0uMDg4LTMuMTAycy0zLjE5LS4wODgtMy4xOS42ODkzeiIgZmlsbD0iIzQzYTI0NCIvPjxwYXRoIGQ9Im0yMS42NzAxIDM0LjQwNTFjMCAxLjgwNzYtLjI2MDQgMi41ODEzLjUxMzMgMi43NTM2Ljc3MzcuMTc2IDIuMjM2NyAwIDIuNzU3My0uMzQ0Ni41MTctLjM0NDcuMDg4LTIuNjY5NC0uMDg0My0zLjEwMi0uMTcyMy0uNDMyNy0zLjE5LS4wODQ0LTMuMTkuNjg5M3oiIGZpbGw9IiM2NWJjNDYiLz48cGF0aCBkPSJtMjIuMDAwMiA0MC40NDgxYzEwLjE4ODUgMCAxOC40NDc5LTguMjU5NCAxOC40NDc5LTE4LjQ0NzlzLTguMjU5NC0xOC40NDc5NS0xOC40NDc5LTE4LjQ0Nzk1LTE4LjQ0Nzk1IDguMjU5NDUtMTguNDQ3OTUgMTguNDQ3OTUgOC4yNTk0NSAxOC40NDc5IDE4LjQ0Nzk1IDE4LjQ0Nzl6bTAgMS43MTg3YzExLjEzNzcgMCAyMC4xNjY2LTkuMDI4OSAyMC4xNjY2LTIwLjE2NjYgMC0xMS4xMzc4LTkuMDI4OS0yMC4xNjY3LTIwLjE2NjYtMjAuMTY2Ny0xMS4xMzc4IDAtMjAuMTY2NyA5LjAyODktMjAuMTY2NyAyMC4xNjY3IDAgMTEuMTM3NyA5LjAyODkgMjAuMTY2NiAyMC4xNjY3IDIwLjE2NjZ6IiBmaWxsPSIjZmZmIi8+PC9nPjwvc3ZnPg=='; -module.exports = { - daxBase64 -}; + generate() { + let params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; -},{}],9:[function(require,module,exports){ -"use strict"; + if (_classPrivateFieldGet(this, _previous)) { + return _classPrivateFieldGet(this, _previous); + } -const EMAIL_SELECTOR = "\ninput:not([type])[name*=mail i]:not([readonly]):not([disabled]):not([hidden]):not([aria-hidden=true]),\ninput[type=\"\"][name*=mail i]:not([readonly]):not([disabled]):not([hidden]):not([aria-hidden=true]),\ninput[type=text][name*=mail i]:not([readonly]):not([disabled]):not([hidden]):not([aria-hidden=true]),\ninput:not([type])[id*=mail i]:not([readonly]):not([disabled]):not([hidden]):not([aria-hidden=true]),\ninput[type=\"\"][id*=mail i]:not([readonly]):not([disabled]):not([hidden]):not([aria-hidden=true]),\ninput:not([type])[placeholder*=mail i]:not([placeholder*=search i]):not([readonly]):not([disabled]):not([hidden]):not([aria-hidden=true]),\ninput[type=text][placeholder*=mail i]:not([placeholder*=search i]):not([readonly]):not([disabled]):not([hidden]):not([aria-hidden=true]),\ninput[type=\"\"][placeholder*=mail i]:not([placeholder*=search i]):not([readonly]):not([disabled]):not([hidden]):not([aria-hidden=true]),\ninput:not([type])[placeholder*=mail i]:not([placeholder*=search i]):not([readonly]):not([disabled]):not([hidden]):not([aria-hidden=true]),\ninput[type=email]:not([readonly]):not([disabled]):not([hidden]):not([aria-hidden=true]),\ninput[type=text][aria-label*=mail i]:not([aria-label*=search i]),\ninput:not([type])[aria-label*=mail i]:not([aria-label*=search i]),\ninput[type=text][placeholder*=mail i]:not([placeholder*=search i]):not([readonly]),\ninput[autocomplete=email]:not([readonly]):not([hidden]):not([disabled])"; -/** @type Matcher */ - -const EMAIL_MATCHER = { - type: 'email', - selector: EMAIL_SELECTOR, - regex: /.mail/i, - negativeRegex: /search/i -}; // We've seen non-standard types like 'user'. This selector should get them, too - -const GENERIC_TEXT_FIELD = "\ninput:not([type=button]):not([type=checkbox]):not([type=color]):not([type=date]):not([type=datetime-local]):not([type=datetime]):not([type=file]):not([type=hidden]):not([type=month]):not([type=number]):not([type=radio]):not([type=range]):not([type=reset]):not([type=search]):not([type=submit]):not([type=tel]):not([type=time]):not([type=url]):not([type=week]):not([readonly]):not([disabled])"; -const PASSWORD_SELECTOR = "input[type=password]:not([autocomplete*=cc]):not([autocomplete=one-time-code])"; -/** @type Matcher */ - -const PASSWORD_MATCHER = { - type: 'password', - selector: PASSWORD_SELECTOR, - regex: /password/i, - negativeRegex: /captcha/i -}; // This is more generic, used only when we have identified a form - -const USERNAME_SELECTOR = "".concat(GENERIC_TEXT_FIELD, "[autocomplete^=user]"); -/** @type Matcher */ - -const USERNAME_MATCHER = { - type: 'username', - selector: USERNAME_SELECTOR, - regex: /user((.)?name)?$/i, - negativeRegex: /search/i -}; -const CC_NAME_SELECTOR = "\ninput[autocomplete=\"cc-name\"],\ninput[autocomplete=\"ccname\"],\ninput[name=\"ccname\"],\ninput[name=\"cc-name\"],\ninput[name=\"ppw-accountHolderName\"],\ninput[id*=cardname i],\ninput[id*=card-name i],\ninput[id*=card_name i]"; -const CC_NUMBER_SELECTOR = "\ninput[autocomplete=\"cc-number\"],\ninput[autocomplete=\"ccnumber\"],\ninput[autocomplete=\"cardnumber\"],\ninput[autocomplete=\"card-number\"],\ninput[name=\"ccnumber\"],\ninput[name=\"cc-number\"],\ninput[name=\"cardnumber\"],\ninput[name=\"card-number\"],\ninput[name=\"creditCardNumber\"],\ninput[name=\"addCreditCardNumber\"],\ninput[id*=cardnumber i],\ninput[id*=card-number i],\ninput[id*=card_number i]"; -const CC_CVC_SELECTOR = "\ninput[autocomplete=\"cc-csc\"],\ninput[autocomplete=\"csc\"],\ninput[autocomplete=\"cc-cvc\"],\ninput[autocomplete=\"cvc\"],\ninput[name=\"cvc\"],\ninput[name=\"cc-cvc\"],\ninput[name=\"cc-csc\"],\ninput[name=\"csc\"],\ninput[name=\"securityCode\"]"; -const CC_MONTH_SELECTOR = "\n[autocomplete=\"cc-exp-month\"],\n[name=\"ccmonth\"],\n[name=\"ppw-expirationDate_month\"]"; -const CC_YEAR_SELECTOR = "\n[autocomplete=\"cc-exp-year\"],\n[name=\"ccyear\"],\n[name=\"ppw-expirationDate_year\"]"; -const CC_EXP_SELECTOR = "\n[autocomplete=\"cc-exp\"],\n[name=\"exp-date\"],\n[name=\"expirationDate\"],\ninput[id*=expiration i],\nselect[id*=expiration i]"; // Matches strings like mm/yy, mm-yyyy, mm-aa + _classPrivateFieldSet(this, _previous, generate({ ...params, + rules + })); -const DATE_SEPARATOR_REGEX = /\w\w\s?(?[/\s.\-_—–])\s?\w\w/i; // Matches 4 non-digit repeated characters (YYYY or AAAA) or 4 digits (2022) + return _classPrivateFieldGet(this, _previous); + } -const FOUR_DIGIT_YEAR_REGEX = /(\D)\1{3}|\d{4}/i; -/** - * This is used to map a selector with the data type we store for credit cards - * @type {[Matcher]} - */ - -const CC_MATCHERS_LIST = [{ - type: 'cardName', - selector: CC_NAME_SELECTOR, - regex: /(card.*name|name.*card)|(card.*holder|holder.*card)|(card.*owner|owner.*card)/i -}, { - type: 'cardNumber', - selector: CC_NUMBER_SELECTOR, - regex: /card.*number|number.*card/i -}, { - type: 'cardSecurityCode', - selector: CC_CVC_SELECTOR, - regex: /security.?code|cvv|csc|cvc/i -}, { - type: 'expirationMonth', - selector: CC_MONTH_SELECTOR, - regex: /(card|cc)?.?(exp(iry|iration)?)?.?(month|mm(?![.\s/-]yy))/i, - negativeRegex: /mm[/\s.\-_—–]/i -}, { - type: 'expirationYear', - selector: CC_YEAR_SELECTOR, - regex: /(card|cc)?.?(exp(iry|iration)?)?.?(ye(ar)?|yy)/i, - negativeRegex: /mm[/\s.\-_—–]/i -}, { - type: 'expiration', - selector: CC_EXP_SELECTOR, - regex: /(mm|\d\d)[/\s.\-_—–](yy|jj|aa|\d\d)|exp|valid/i, - negativeRegex: /invalid/i -}]; -const CC_FIELD_SELECTOR = CC_MATCHERS_LIST.map(({ - selector -}) => selector).join(', '); -const FIELD_SELECTOR = [PASSWORD_SELECTOR, GENERIC_TEXT_FIELD, EMAIL_SELECTOR, CC_FIELD_SELECTOR].join(', '); -const SUBMIT_BUTTON_SELECTOR = "\ninput[type=submit],\ninput[type=button],\nbutton:not([role=switch]):not([role=link]),\n[role=button]"; -module.exports = { - PASSWORD_SELECTOR, - EMAIL_MATCHER, - PASSWORD_MATCHER, - USERNAME_MATCHER, - FOUR_DIGIT_YEAR_REGEX, - CC_MATCHERS_LIST, - DATE_SEPARATOR_REGEX, - CC_FIELD_SELECTOR, - FIELD_SELECTOR, - SUBMIT_BUTTON_SELECTOR -}; +} + +module.exports.PasswordGenerator = PasswordGenerator; -},{}],10:[function(require,module,exports){ +},{"../packages/password":2,"../packages/password/rules.json":6}],29:[function(require,module,exports){ "use strict"; const { isApp, + isTopFrame, escapeXML } = require('../autofill-utils'); const Tooltip = require('./Tooltip'); -const getInputConfig = require('../Form/inputTypeConfig'); - class DataAutofill extends Tooltip { - constructor(input, associatedForm, Interface) { - super(input, associatedForm, Interface); - const config = getInputConfig(input); - this.data = this.interface["getLocal".concat(config.dataType)](); + /** + * @param {InputTypeConfigs} config + * @param {TooltipItemRenderer[]} items + * @param {{onSelect(id:string): void}} callbacks + */ + render(config, items, callbacks) { const includeStyles = isApp ? "") : ""); - this.shadow.innerHTML = "\n".concat(includeStyles, "\n
\n \n
"); + let hasAddedSeparator = false; // Only show an hr above the first duck address button, but it can be either personal or private + + const shouldShowSeparator = dataId => { + const shouldShow = ['personalAddress', 'privateAddress'].includes(dataId) && !hasAddedSeparator; + if (shouldShow) hasAddedSeparator = true; + return shouldShow; + }; + + const topClass = isTopFrame ? 'top-autofill' : ''; + this.shadow.innerHTML = "\n".concat(includeStyles, "\n
\n \n
"); this.wrapper = this.shadow.querySelector('.wrapper'); this.tooltip = this.shadow.querySelector('.tooltip'); this.autofillButtons = this.shadow.querySelectorAll('.js-autofill-button'); this.autofillButtons.forEach(btn => { this.registerClickableButton(btn, () => { - this.interface["".concat(config.autofillMethod)](btn.id).then(({ - success, - error - }) => { - if (success) this.associatedForm.autofillData(success, config.type); - }); + callbacks.onSelect(btn.id); }); }); this.init(); + return this; } } module.exports = DataAutofill; -},{"../Form/inputTypeConfig":6,"../autofill-utils":17,"./Tooltip":12,"./styles/autofill-tooltip-styles.js":14}],11:[function(require,module,exports){ +},{"../autofill-utils":36,"./Tooltip":31,"./styles/autofill-tooltip-styles.js":33}],30:[function(require,module,exports){ "use strict"; const { isApp, - formatAddress, + formatDuckAddress, escapeXML } = require('../autofill-utils'); const Tooltip = require('./Tooltip'); class EmailAutofill extends Tooltip { - constructor(input, associatedForm, Interface) { - super(input, associatedForm, Interface); + constructor(config, inputType, position, deviceInterface) { + super(config, inputType, position, deviceInterface); this.addresses = this.interface.getLocalAddresses(); const includeStyles = isApp ? "") : ""); - this.shadow.innerHTML = "\n".concat(includeStyles, "\n
\n \n
"); + this.shadow.innerHTML = "\n".concat(includeStyles, "\n
\n \n
"); this.wrapper = this.shadow.querySelector('.wrapper'); this.tooltip = this.shadow.querySelector('.tooltip'); this.usePersonalButton = this.shadow.querySelector('.js-use-personal'); @@ -1636,29 +7090,41 @@ class EmailAutofill extends Tooltip { this.addressEl = this.shadow.querySelector('.js-address'); this.updateAddresses = addresses => { - if (addresses) { + if (addresses && this.addressEl) { this.addresses = addresses; - this.addressEl.textContent = formatAddress(addresses.personalAddress); + this.addressEl.textContent = formatDuckAddress(addresses.personalAddress); } }; this.registerClickableButton(this.usePersonalButton, () => { - this.associatedForm.autofillEmail(formatAddress(this.addresses.personalAddress)); + this.fillForm('personalAddress'); }); this.registerClickableButton(this.usePrivateButton, () => { - this.associatedForm.autofillEmail(formatAddress(this.addresses.privateAddress)); - this.interface.refreshAlias(); + this.fillForm('privateAddress'); }); // Get the alias from the extension this.interface.getAddresses().then(this.updateAddresses); this.init(); } + /** + * @param {'personalAddress' | 'privateAddress'} id + */ + + + async fillForm(id) { + const address = this.addresses[id]; + const formattedAddress = formatDuckAddress(address); + this.interface.selectedDetail({ + email: formattedAddress, + id + }, 'email'); + } } module.exports = EmailAutofill; -},{"../autofill-utils":17,"./Tooltip":12,"./styles/autofill-tooltip-styles.js":14}],12:[function(require,module,exports){ +},{"../autofill-utils":36,"./Tooltip":31,"./styles/autofill-tooltip-styles.js":33}],31:[function(require,module,exports){ "use strict"; function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } @@ -1666,91 +7132,16 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope const { safeExecute, addInlineStyles, - getDaxBoundingBox + isTopFrame } = require('../autofill-utils'); const { - getInputMainType -} = require('../Form/input-classifiers'); - -const updatePosition = function ({ - left, - top -}) { - const shadow = this.shadow; // If the stylesheet is not loaded wait for load (Chrome bug) - - if (!shadow.styleSheets.length) { - this.stylesheet.addEventListener('load', this.checkPosition); - return; - } - - this.left = left; - this.top = top; - - if (this.transformRuleIndex && shadow.styleSheets[0].rules[this.transformRuleIndex]) { - // If we have already set the rule, remove it… - shadow.styleSheets[0].deleteRule(this.transformRuleIndex); - } else { - // …otherwise, set the index as the very last rule - this.transformRuleIndex = shadow.styleSheets[0].rules.length; - } - - const newRule = ".wrapper {transform: translate(".concat(left, "px, ").concat(top, "px);}"); - shadow.styleSheets[0].insertRule(newRule, this.transformRuleIndex); -}; - -const checkPosition = function () { - if (this.animationFrame) { - window.cancelAnimationFrame(this.animationFrame); - } - - this.animationFrame = window.requestAnimationFrame(() => { - const isEmailInput = getInputMainType(this.input) === 'emailNew'; // Placement for the email autofill tooltip is relative to the position of the Dax icon - - const position = isEmailInput ? getDaxBoundingBox(this.input) : this.input.getBoundingClientRect(); - const { - left, - bottom - } = position; - - if (left !== this.left || bottom !== this.top) { - this.updatePosition({ - left, - top: bottom - }); - } - - this.animationFrame = null; - }); -}; - -const ensureIsLastInDOM = function () { - this.count = this.count || 0; // If DDG el is not the last in the doc, move it there - - if (document.body.lastElementChild !== this.host) { - // Try up to 15 times to avoid infinite loop in case someone is doing the same - if (this.count < 15) { - this.lift(); - this.append(); - this.checkPosition(); - this.count++; - } else { - // Remove the tooltip from the form to cleanup listeners and observers - this.associatedForm.removeTooltip(); - console.info("DDG autofill bailing out"); - } - } -}; + getSubtypeFromType +} = require('../Form/matching'); class Tooltip { - constructor(input, associatedForm, Interface) { - _defineProperty(this, "checkPosition", checkPosition.bind(this)); - - _defineProperty(this, "updatePosition", updatePosition.bind(this)); - - _defineProperty(this, "ensureIsLastInDOM", ensureIsLastInDOM.bind(this)); - - _defineProperty(this, "resObs", new ResizeObserver(entries => entries.forEach(this.checkPosition))); + constructor(config, inputType, getPosition, deviceInterface) { + _defineProperty(this, "resObs", new ResizeObserver(entries => entries.forEach(() => this.checkPosition()))); _defineProperty(this, "mutObs", new MutationObserver(mutationList => { for (const mutationRecord of mutationList) { @@ -1769,19 +7160,22 @@ class Tooltip { _defineProperty(this, "clickableButtons", new Map()); this.shadow = document.createElement('ddg-autofill').attachShadow({ - mode: 'closed' + mode: deviceInterface.mode === 'test' ? 'open' : 'closed' }); this.host = this.shadow.host; + this.config = config; + this.subtype = getSubtypeFromType(inputType); this.tooltip = null; + this.getPosition = getPosition; const forcedVisibilityStyles = { 'display': 'block', 'visibility': 'visible', 'opacity': '1' - }; + }; // @ts-ignore how to narrow this.host to HTMLElement? + addInlineStyles(this.host, forcedVisibilityStyles); - this.input = input; - this.associatedForm = associatedForm; - this.interface = Interface; + this.interface = deviceInterface; + this.count = 0; } append() { @@ -1789,8 +7183,7 @@ class Tooltip { } remove() { - window.removeEventListener('scroll', this.checkPosition, { - passive: true, + window.removeEventListener('scroll', this, { capture: true }); this.resObs.disconnect(); @@ -1804,6 +7197,100 @@ class Tooltip { document.body.removeChild(this.host); } + handleEvent(event) { + switch (event.type) { + case 'scroll': + this.checkPosition(); + break; + } + } + + focus(x, y) { + var _this$shadow$elementF, _this$shadow$elementF2; + + const focusableElements = 'button'; + const currentFocusClassName = 'currentFocus'; + const currentFocused = this.shadow.querySelectorAll(".".concat(currentFocusClassName)); + [...currentFocused].forEach(el => { + el.classList.remove(currentFocusClassName); + }); + (_this$shadow$elementF = this.shadow.elementFromPoint(x, y)) === null || _this$shadow$elementF === void 0 ? void 0 : (_this$shadow$elementF2 = _this$shadow$elementF.closest(focusableElements)) === null || _this$shadow$elementF2 === void 0 ? void 0 : _this$shadow$elementF2.classList.add(currentFocusClassName); + } + + checkPosition() { + if (this.animationFrame) { + window.cancelAnimationFrame(this.animationFrame); + } + + this.animationFrame = window.requestAnimationFrame(() => { + const { + left, + bottom + } = this.getPosition(); + + if (left !== this.left || bottom !== this.top) { + this.updatePosition({ + left, + top: bottom + }); + } + + this.animationFrame = null; + }); + } + + updatePosition(_ref) { + let { + left, + top + } = _ref; + const shadow = this.shadow; // If the stylesheet is not loaded wait for load (Chrome bug) + + if (!shadow.styleSheets.length) { + var _this$stylesheet; + + (_this$stylesheet = this.stylesheet) === null || _this$stylesheet === void 0 ? void 0 : _this$stylesheet.addEventListener('load', () => this.checkPosition()); + return; + } + + this.left = left; + this.top = top; + + if (this.transformRuleIndex && shadow.styleSheets[0].rules[this.transformRuleIndex]) { + // If we have already set the rule, remove it… + shadow.styleSheets[0].deleteRule(this.transformRuleIndex); + } else { + // …otherwise, set the index as the very last rule + this.transformRuleIndex = shadow.styleSheets[0].rules.length; + } + + let newRule = ".wrapper {transform: translate(".concat(left, "px, ").concat(top, "px);}"); + + if (isTopFrame) { + newRule = '.wrapper {transform: none; }'; + } + + shadow.styleSheets[0].insertRule(newRule, this.transformRuleIndex); + } + + ensureIsLastInDOM() { + this.count = this.count || 0; // If DDG el is not the last in the doc, move it there + + if (document.body.lastElementChild !== this.host) { + // Try up to 15 times to avoid infinite loop in case someone is doing the same + if (this.count < 15) { + this.lift(); + this.append(); + this.checkPosition(); + this.count++; + } else { + // Remove the tooltip from the form to cleanup listeners and observers + this.interface.removeTooltip(); + console.info("DDG autofill bailing out"); + } + } + } + setActiveButton(e) { this.activeButton = e.target; } @@ -1816,7 +7303,7 @@ class Tooltip { this.clickableButtons.set(btn, handler); // Needed because clicks within the shadow dom don't provide this info to the outside btn.addEventListener('mouseenter', e => this.setActiveButton(e)); - btn.addEventListener('mouseleave', e => this.unsetActiveButton(e)); + btn.addEventListener('mouseleave', () => this.unsetActiveButton()); } dispatchClick() { @@ -1827,14 +7314,38 @@ class Tooltip { } } + setupSizeListener() { + if (!isTopFrame) return; // Listen to layout and paint changes to register the size + + const observer = new PerformanceObserver(() => { + this.setSize(); + }); + observer.observe({ + entryTypes: ['layout-shift', 'paint'] + }); + } + + setSize() { + if (!isTopFrame) return; + const innerNode = this.shadow.querySelector('.wrapper--data'); // Shouldn't be possible + + if (!innerNode) return; + this.interface.setSize({ + height: innerNode.clientHeight, + width: innerNode.clientWidth + }); + } + init() { + var _this$stylesheet2; + this.animationFrame = null; this.top = 0; this.left = 0; this.transformRuleIndex = null; this.stylesheet = this.shadow.querySelector('link, style'); // Un-hide once the style is loaded, to avoid flashing unstyled content - this.stylesheet.addEventListener('load', () => this.tooltip.removeAttribute('hidden')); + (_this$stylesheet2 = this.stylesheet) === null || _this$stylesheet2 === void 0 ? void 0 : _this$stylesheet2.addEventListener('load', () => this.tooltip.removeAttribute('hidden')); this.append(); this.resObs.observe(document.body); this.mutObs.observe(document.body, { @@ -1842,17 +7353,18 @@ class Tooltip { subtree: true, attributes: true }); - window.addEventListener('scroll', this.checkPosition, { - passive: true, + window.addEventListener('scroll', this, { capture: true }); + this.setSize(); + this.setupSizeListener(); } } module.exports = Tooltip; -},{"../Form/input-classifiers":4,"../autofill-utils":17}],13:[function(require,module,exports){ +},{"../Form/matching":22,"../autofill-utils":36}],32:[function(require,module,exports){ "use strict"; const ddgPasswordIconBase = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMjRweCIgaGVpZ2h0PSIyNHB4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8dGl0bGU+ZGRnLXBhc3N3b3JkLWljb24tYmFzZTwvdGl0bGU+CiAgICA8ZyBpZD0iZGRnLXBhc3N3b3JkLWljb24tYmFzZSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9IlVuaW9uIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0LjAwMDAwMCwgNC4wMDAwMDApIiBmaWxsPSIjMDAwMDAwIj4KICAgICAgICAgICAgPHBhdGggZD0iTTExLjMzMzMsMi42NjY2NyBDMTAuMjI4OCwyLjY2NjY3IDkuMzMzMzMsMy41NjIxIDkuMzMzMzMsNC42NjY2NyBDOS4zMzMzMyw1Ljc3MTI0IDEwLjIyODgsNi42NjY2NyAxMS4zMzMzLDYuNjY2NjcgQzEyLjQzNzksNi42NjY2NyAxMy4zMzMzLDUuNzcxMjQgMTMuMzMzMyw0LjY2NjY3IEMxMy4zMzMzLDMuNTYyMSAxMi40Mzc5LDIuNjY2NjcgMTEuMzMzMywyLjY2NjY3IFogTTEwLjY2NjcsNC42NjY2NyBDMTAuNjY2Nyw0LjI5ODQ4IDEwLjk2NTEsNCAxMS4zMzMzLDQgQzExLjcwMTUsNCAxMiw0LjI5ODQ4IDEyLDQuNjY2NjcgQzEyLDUuMDM0ODYgMTEuNzAxNSw1LjMzMzMzIDExLjMzMzMsNS4zMzMzMyBDMTAuOTY1MSw1LjMzMzMzIDEwLjY2NjcsNS4wMzQ4NiAxMC42NjY3LDQuNjY2NjcgWiIgaWQ9IlNoYXBlIj48L3BhdGg+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0xMC42NjY3LDAgQzcuNzIxMTUsMCA1LjMzMzMzLDIuMzg3ODEgNS4zMzMzMyw1LjMzMzMzIEM1LjMzMzMzLDUuNzYxMTkgNS4zODM4NSw2LjE3Nzk4IDUuNDc5NDUsNi41Nzc3NSBMMC4xOTUyNjIsMTEuODYxOSBDMC4wNzAyMzc5LDExLjk4NyAwLDEyLjE1NjUgMCwxMi4zMzMzIEwwLDE1LjMzMzMgQzAsMTUuNzAxNSAwLjI5ODQ3NywxNiAwLjY2NjY2NywxNiBMMy4zMzMzMywxNiBDNC4wNjk3MSwxNiA0LjY2NjY3LDE1LjQwMyA0LjY2NjY3LDE0LjY2NjcgTDQuNjY2NjcsMTQgTDUuMzMzMzMsMTQgQzYuMDY5NzEsMTQgNi42NjY2NywxMy40MDMgNi42NjY2NywxMi42NjY3IEw2LjY2NjY3LDExLjMzMzMgTDgsMTEuMzMzMyBDOC4xNzY4MSwxMS4zMzMzIDguMzQ2MzgsMTEuMjYzMSA4LjQ3MTQxLDExLjEzODEgTDkuMTU5MDYsMTAuNDUwNCBDOS42Mzc3MiwxMC41OTEyIDEwLjE0MzksMTAuNjY2NyAxMC42NjY3LDEwLjY2NjcgQzEzLjYxMjIsMTAuNjY2NyAxNiw4LjI3ODg1IDE2LDUuMzMzMzMgQzE2LDIuMzg3ODEgMTMuNjEyMiwwIDEwLjY2NjcsMCBaIE02LjY2NjY3LDUuMzMzMzMgQzYuNjY2NjcsMy4xMjQxOSA4LjQ1NzUzLDEuMzMzMzMgMTAuNjY2NywxLjMzMzMzIEMxMi44NzU4LDEuMzMzMzMgMTQuNjY2NywzLjEyNDE5IDE0LjY2NjcsNS4zMzMzMyBDMTQuNjY2Nyw3LjU0MjQ3IDEyLjg3NTgsOS4zMzMzMyAxMC42NjY3LDkuMzMzMzMgQzEwLjE1NTgsOS4zMzMzMyA5LjY2ODg2LDkuMjM3OSA5LjIyMTUyLDkuMDY0NSBDOC45NzUyOCw4Ljk2OTA1IDguNjk1OTEsOS4wMjc5NSA4LjUwOTE2LDkuMjE0NjkgTDcuNzIzODYsMTAgTDYsMTAgQzUuNjMxODEsMTAgNS4zMzMzMywxMC4yOTg1IDUuMzMzMzMsMTAuNjY2NyBMNS4zMzMzMywxMi42NjY3IEw0LDEyLjY2NjcgQzMuNjMxODEsMTIuNjY2NyAzLjMzMzMzLDEyLjk2NTEgMy4zMzMzMywxMy4zMzMzIEwzLjMzMzMzLDE0LjY2NjcgTDEuMzMzMzMsMTQuNjY2NyBMMS4zMzMzMywxMi42MDk1IEw2LjY5Nzg3LDcuMjQ0OTQgQzYuODc1MDIsNy4wNjc3OSA2LjkzNzksNi44MDYyOSA2Ljg2MDY1LDYuNTY3OTggQzYuNzM0ODksNi4xNzk5NyA2LjY2NjY3LDUuNzY1MjcgNi42NjY2Nyw1LjMzMzMzIFoiIGlkPSJTaGFwZSI+PC9wYXRoPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+'; @@ -1861,21 +7373,23 @@ const ddgPasswordIconFilled = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4 const ddgPasswordIconFocused = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMjRweCIgaGVpZ2h0PSIyNHB4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8dGl0bGU+ZGRnLXBhc3N3b3JkLWljb24tZm9jdXNlZDwvdGl0bGU+CiAgICA8ZyBpZD0iZGRnLXBhc3N3b3JkLWljb24tZm9jdXNlZCIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9Ikljb24tQ29udGFpbmVyIiBmaWxsPSIjMDAwMDAwIj4KICAgICAgICAgICAgPHJlY3QgaWQ9IlJlY3RhbmdsZSIgZmlsbC1vcGFjaXR5PSIwLjEiIGZpbGwtcnVsZT0ibm9uemVybyIgeD0iMCIgeT0iMCIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiByeD0iMTIiPjwvcmVjdD4KICAgICAgICAgICAgPGcgaWQ9Ikdyb3VwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0LjAwMDAwMCwgNC4wMDAwMDApIiBmaWxsLW9wYWNpdHk9IjAuOSI+CiAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTEuMjUsMi43NSBDMTAuMTQ1NCwyLjc1IDkuMjUsMy42NDU0MyA5LjI1LDQuNzUgQzkuMjUsNS44NTQ1NyAxMC4xNDU0LDYuNzUgMTEuMjUsNi43NSBDMTIuMzU0Niw2Ljc1IDEzLjI1LDUuODU0NTcgMTMuMjUsNC43NSBDMTMuMjUsMy42NDU0MyAxMi4zNTQ2LDIuNzUgMTEuMjUsMi43NSBaIE0xMC43NSw0Ljc1IEMxMC43NSw0LjQ3Mzg2IDEwLjk3MzksNC4yNSAxMS4yNSw0LjI1IEMxMS41MjYxLDQuMjUgMTEuNzUsNC40NzM4NiAxMS43NSw0Ljc1IEMxMS43NSw1LjAyNjE0IDExLjUyNjEsNS4yNSAxMS4yNSw1LjI1IEMxMC45NzM5LDUuMjUgMTAuNzUsNS4wMjYxNCAxMC43NSw0Ljc1IFoiIGlkPSJTaGFwZSI+PC9wYXRoPgogICAgICAgICAgICAgICAgPHBhdGggZD0iTTEwLjYyNSwwIEM3LjY1NjUsMCA1LjI1LDIuNDA2NDcgNS4yNSw1LjM3NSBDNS4yNSw1Ljc4MDk4IDUuMjk1MTQsNi4xNzcxIDUuMzgwODgsNi41NTg1IEwwLjIxOTY3LDExLjcxOTcgQzAuMDc5MDIsMTEuODYwMyAwLDEyLjA1MTEgMCwxMi4yNSBMMCwxNS4yNSBDMCwxNS42NjQyIDAuMzM1NzksMTYgMC43NSwxNiBMMy43NDY2MSwxNiBDNC4zMDA3NiwxNiA0Ljc1LDE1LjU1MDggNC43NSwxNC45OTY2IEw0Ljc1LDE0IEw1Ljc0NjYxLDE0IEM2LjMwMDgsMTQgNi43NSwxMy41NTA4IDYuNzUsMTIuOTk2NiBMNi43NSwxMS41IEw4LDExLjUgQzguMTk4OSwxMS41IDguMzg5NywxMS40MjEgOC41MzAzLDExLjI4MDMgTDkuMjQwOCwxMC41Njk5IEM5LjY4MywxMC42ODc1IDEwLjE0NzIsMTAuNzUgMTAuNjI1LDEwLjc1IEMxMy41OTM1LDEwLjc1IDE2LDguMzQzNSAxNiw1LjM3NSBDMTYsMi40MDY0NyAxMy41OTM1LDAgMTAuNjI1LDAgWiBNNi43NSw1LjM3NSBDNi43NSwzLjIzNDkgOC40ODQ5LDEuNSAxMC42MjUsMS41IEMxMi43NjUxLDEuNSAxNC41LDMuMjM0OSAxNC41LDUuMzc1IEMxNC41LDcuNTE1MSAxMi43NjUxLDkuMjUgMTAuNjI1LDkuMjUgQzEwLjE1NDUsOS4yNSA5LjcwNTMsOS4xNjY1IDkuMjkwMSw5LjAxNDIgQzkuMDE1OCw4LjkxMzUgOC43MDgsOC45ODEzIDguNTAxNCw5LjE4NzkgTDcuNjg5MywxMCBMNiwxMCBDNS41ODU3OSwxMCA1LjI1LDEwLjMzNTggNS4yNSwxMC43NSBMNS4yNSwxMi41IEw0LDEyLjUgQzMuNTg1NzksMTIuNSAzLjI1LDEyLjgzNTggMy4yNSwxMy4yNSBMMy4yNSwxNC41IEwxLjUsMTQuNSBMMS41LDEyLjU2MDcgTDYuNzQ4Myw3LjMxMjQgQzYuOTQ2Nyw3LjExNCA3LjAxNzcsNi44MjE0IDYuOTMyNSw2LjU1NDEgQzYuODE0MSw2LjE4MzMgNi43NSw1Ljc4NzM1IDYuNzUsNS4zNzUgWiIgaWQ9IlNoYXBlIj48L3BhdGg+CiAgICAgICAgICAgIDwvZz4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg=='; const ddgCcIconBase = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+CiAgICA8cGF0aCBkPSJNNSA5Yy0uNTUyIDAtMSAuNDQ4LTEgMXYyYzAgLjU1Mi40NDggMSAxIDFoM2MuNTUyIDAgMS0uNDQ4IDEtMXYtMmMwLS41NTItLjQ0OC0xLTEtMUg1eiIgZmlsbD0iIzAwMCIvPgogICAgPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xIDZjMC0yLjIxIDEuNzktNCA0LTRoMTRjMi4yMSAwIDQgMS43OSA0IDR2MTJjMCAyLjIxLTEuNzkgNC00IDRINWMtMi4yMSAwLTQtMS43OS00LTRWNnptNC0yYy0xLjEwNSAwLTIgLjg5NS0yIDJ2OWgxOFY2YzAtMS4xMDUtLjg5NS0yLTItMkg1em0wIDE2Yy0xLjEwNSAwLTItLjg5NS0yLTJoMThjMCAxLjEwNS0uODk1IDItMiAySDV6IiBmaWxsPSIjMDAwIi8+Cjwvc3ZnPgo='; const ddgCcIconFilled = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+CiAgICA8cGF0aCBkPSJNNSA5Yy0uNTUyIDAtMSAuNDQ4LTEgMXYyYzAgLjU1Mi40NDggMSAxIDFoM2MuNTUyIDAgMS0uNDQ4IDEtMXYtMmMwLS41NTItLjQ0OC0xLTEtMUg1eiIgZmlsbD0iIzc2NDMxMCIvPgogICAgPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xIDZjMC0yLjIxIDEuNzktNCA0LTRoMTRjMi4yMSAwIDQgMS43OSA0IDR2MTJjMCAyLjIxLTEuNzkgNC00IDRINWMtMi4yMSAwLTQtMS43OS00LTRWNnptNC0yYy0xLjEwNSAwLTIgLjg5NS0yIDJ2OWgxOFY2YzAtMS4xMDUtLjg5NS0yLTItMkg1em0wIDE2Yy0xLjEwNSAwLTItLjg5NS0yLTJoMThjMCAxLjEwNS0uODk1IDItMiAySDV6IiBmaWxsPSIjNzY0MzEwIi8+Cjwvc3ZnPgo='; +const ddgIdentityIconBase = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+CiAgICA8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTEyIDIxYzIuMTQzIDAgNC4xMTEtLjc1IDUuNjU3LTItLjYyNi0uNTA2LTEuMzE4LS45MjctMi4wNi0xLjI1LTEuMS0uNDgtMi4yODUtLjczNS0zLjQ4Ni0uNzUtMS4yLS4wMTQtMi4zOTIuMjExLTMuNTA0LjY2NC0uODE3LjMzMy0xLjU4Ljc4My0yLjI2NCAxLjMzNiAxLjU0NiAxLjI1IDMuNTE0IDIgNS42NTcgMnptNC4zOTctNS4wODNjLjk2Ny40MjIgMS44NjYuOTggMi42NzIgMS42NTVDMjAuMjc5IDE2LjAzOSAyMSAxNC4xMDQgMjEgMTJjMC00Ljk3LTQuMDMtOS05LTlzLTkgNC4wMy05IDljMCAyLjEwNC43MjIgNC4wNCAxLjkzMiA1LjU3Mi44NzQtLjczNCAxLjg2LTEuMzI4IDIuOTIxLTEuNzYgMS4zNi0uNTU0IDIuODE2LS44MyA0LjI4My0uODExIDEuNDY3LjAxOCAyLjkxNi4zMyA0LjI2LjkxNnpNMTIgMjNjNi4wNzUgMCAxMS00LjkyNSAxMS0xMVMxOC4wNzUgMSAxMiAxIDEgNS45MjUgMSAxMnM0LjkyNSAxMSAxMSAxMXptMy0xM2MwIDEuNjU3LTEuMzQzIDMtMyAzcy0zLTEuMzQzLTMtMyAxLjM0My0zIDMtMyAzIDEuMzQzIDMgM3ptMiAwYzAgMi43NjEtMi4yMzkgNS01IDVzLTUtMi4yMzktNS01IDIuMjM5LTUgNS01IDUgMi4yMzkgNSA1eiIgZmlsbD0iIzAwMCIvPgo8L3N2Zz4KPHBhdGggeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTEyIDIxYzIuMTQzIDAgNC4xMTEtLjc1IDUuNjU3LTItLjYyNi0uNTA2LTEuMzE4LS45MjctMi4wNi0xLjI1LTEuMS0uNDgtMi4yODUtLjczNS0zLjQ4Ni0uNzUtMS4yLS4wMTQtMi4zOTIuMjExLTMuNTA0LjY2NC0uODE3LjMzMy0xLjU4Ljc4My0yLjI2NCAxLjMzNiAxLjU0NiAxLjI1IDMuNTE0IDIgNS42NTcgMnptNC4zOTctNS4wODNjLjk2Ny40MjIgMS44NjYuOTggMi42NzIgMS42NTVDMjAuMjc5IDE2LjAzOSAyMSAxNC4xMDQgMjEgMTJjMC00Ljk3LTQuMDMtOS05LTlzLTkgNC4wMy05IDljMCAyLjEwNC43MjIgNC4wNCAxLjkzMiA1LjU3Mi44NzQtLjczNCAxLjg2LTEuMzI4IDIuOTIxLTEuNzYgMS4zNi0uNTU0IDIuODE2LS44MyA0LjI4My0uODExIDEuNDY3LjAxOCAyLjkxNi4zMyA0LjI2LjkxNnpNMTIgMjNjNi4wNzUgMCAxMS00LjkyNSAxMS0xMVMxOC4wNzUgMSAxMiAxIDEgNS45MjUgMSAxMnM0LjkyNSAxMSAxMSAxMXptMy0xM2MwIDEuNjU3LTEuMzQzIDMtMyAzcy0zLTEuMzQzLTMtMyAxLjM0My0zIDMtMyAzIDEuMzQzIDMgM3ptMiAwYzAgMi43NjEtMi4yMzkgNS01IDVzLTUtMi4yMzktNS01IDIuMjM5LTUgNS01IDUgMi4yMzkgNSA1eiIgZmlsbD0iIzAwMCIvPgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiBmaWxsPSJub25lIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xMiAyMWMyLjE0MyAwIDQuMTExLS43NSA1LjY1Ny0yLS42MjYtLjUwNi0xLjMxOC0uOTI3LTIuMDYtMS4yNS0xLjEtLjQ4LTIuMjg1LS43MzUtMy40ODYtLjc1LTEuMi0uMDE0LTIuMzkyLjIxMS0zLjUwNC42NjQtLjgxNy4zMzMtMS41OC43ODMtMi4yNjQgMS4zMzYgMS41NDYgMS4yNSAzLjUxNCAyIDUuNjU3IDJ6bTQuMzk3LTUuMDgzYy45NjcuNDIyIDEuODY2Ljk4IDIuNjcyIDEuNjU1QzIwLjI3OSAxNi4wMzkgMjEgMTQuMTA0IDIxIDEyYzAtNC45Ny00LjAzLTktOS05cy05IDQuMDMtOSA5YzAgMi4xMDQuNzIyIDQuMDQgMS45MzIgNS41NzIuODc0LS43MzQgMS44Ni0xLjMyOCAyLjkyMS0xLjc2IDEuMzYtLjU1NCAyLjgxNi0uODMgNC4yODMtLjgxMSAxLjQ2Ny4wMTggMi45MTYuMzMgNC4yNi45MTZ6TTEyIDIzYzYuMDc1IDAgMTEtNC45MjUgMTEtMTFTMTguMDc1IDEgMTIgMSAxIDUuOTI1IDEgMTJzNC45MjUgMTEgMTEgMTF6bTMtMTNjMCAxLjY1Ny0xLjM0MyAzLTMgM3MtMy0xLjM0My0zLTMgMS4zNDMtMyAzLTMgMyAxLjM0MyAzIDN6bTIgMGMwIDIuNzYxLTIuMjM5IDUtNSA1cy01LTIuMjM5LTUtNSAyLjIzOS01IDUtNSA1IDIuMjM5IDUgNXoiIGZpbGw9IiMwMDAiLz4KPC9zdmc+Cg=="; module.exports = { ddgPasswordIconBase, ddgPasswordIconBaseWhite, ddgPasswordIconFilled, ddgPasswordIconFocused, ddgCcIconBase, - ddgCcIconFilled + ddgCcIconFilled, + ddgIdentityIconBase }; -},{}],14:[function(require,module,exports){ +},{}],33:[function(require,module,exports){ "use strict"; -module.exports = "\n.wrapper *, .wrapper *::before, .wrapper *::after {\n box-sizing: border-box;\n}\n.wrapper {\n position: fixed;\n top: 0;\n left: 0;\n padding: 0;\n font-family: 'DDG_ProximaNova', 'Proxima Nova', -apple-system,\n BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu',\n 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;\n -webkit-font-smoothing: antialiased;\n /* move it offscreen to avoid flashing */\n transform: translate(-1000px);\n z-index: 2147483647;\n}\n.wrapper--data {\n font-family: 'SF Pro Text', -apple-system,\n BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu',\n 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;\n}\n.tooltip {\n position: absolute;\n width: 300px;\n max-width: calc(100vw - 25px);\n z-index: 2147483647;\n}\n.tooltip--data {\n top: 100%;\n left: 100%;\n padding: 4px;\n border: 0.5px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n background-color: rgba(242, 240, 240, 0.9);\n -webkit-backdrop-filter: blur(40px);\n backdrop-filter: blur(40px);\n font-size: 13px;\n line-height: 15px;\n color: #222222;\n box-shadow: 0 10px 20px rgba(0, 0, 0, 0.32);\n}\n.tooltip--email {\n top: calc(100% + 6px);\n right: calc(100% - 46px);\n padding: 8px;\n border: 1px solid #D0D0D0;\n border-radius: 10px;\n background-color: #FFFFFF;\n font-size: 14px;\n line-height: 1.3;\n color: #333333;\n box-shadow: 0 10px 20px rgba(0, 0, 0, 0.15);\n}\n.tooltip--email::before,\n.tooltip--email::after {\n content: \"\";\n width: 0;\n height: 0;\n border-left: 10px solid transparent;\n border-right: 10px solid transparent;\n display: block;\n border-bottom: 8px solid #D0D0D0;\n position: absolute;\n right: 20px;\n}\n.tooltip--email::before {\n border-bottom-color: #D0D0D0;\n top: -9px;\n}\n.tooltip--email::after {\n border-bottom-color: #FFFFFF;\n top: -8px;\n}\n\n/* Buttons */\n.tooltip__button {\n display: flex;\n width: 100%;\n padding: 4px 8px 7px;\n font-family: inherit;\n background: transparent;\n border: none;\n border-radius: 6px;\n}\n.tooltip__button:hover {\n background-color: rgba(0, 121, 242, 0.8);\n color: #FFFFFF;\n}\n\n/* Data autofill tooltip specific */\n.tooltip__button--data {\n min-height: 48px;\n flex-direction: row;\n justify-content: flex-start;\n align-items: center;\n font-size: inherit;\n font-weight: 500;\n text-align: left;\n letter-spacing: -0.25px;\n}\n.tooltip__button--data > * {\n opacity: 0.9;\n}\n.tooltip__button--data:first-child {\n margin-top: 0;\n}\n.tooltip__button--data:last-child {\n margin-bottom: 0;\n}\n.tooltip__button--data::before {\n content: '';\n display: block;\n width: 26px;\n height: 26px;\n margin: auto 8px auto 0;\n background-size: cover;\n}\n.tooltip__button__secondary-text {\n font-size: 11px;\n color: rgba(0,0,0,0.6);\n}\n.tooltip__button:hover .tooltip__button__secondary-text {\n color: #FFFFFF;\n}\n\n/* Icons */\n.tooltip__button--data--credentials::before {\n /* TODO: use dynamically from src/UI/img/ddgPasswordIcon.js */\n background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMjRweCIgaGVpZ2h0PSIyNHB4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8dGl0bGU+ZGRnLXBhc3N3b3JkLWljb24tYmFzZTwvdGl0bGU+CiAgICA8ZyBpZD0iZGRnLXBhc3N3b3JkLWljb24tYmFzZSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9IlVuaW9uIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0LjAwMDAwMCwgNC4wMDAwMDApIiBmaWxsPSIjMDAwMDAwIj4KICAgICAgICAgICAgPHBhdGggZD0iTTExLjMzMzMsMi42NjY2NyBDMTAuMjI4OCwyLjY2NjY3IDkuMzMzMzMsMy41NjIxIDkuMzMzMzMsNC42NjY2NyBDOS4zMzMzMyw1Ljc3MTI0IDEwLjIyODgsNi42NjY2NyAxMS4zMzMzLDYuNjY2NjcgQzEyLjQzNzksNi42NjY2NyAxMy4zMzMzLDUuNzcxMjQgMTMuMzMzMyw0LjY2NjY3IEMxMy4zMzMzLDMuNTYyMSAxMi40Mzc5LDIuNjY2NjcgMTEuMzMzMywyLjY2NjY3IFogTTEwLjY2NjcsNC42NjY2NyBDMTAuNjY2Nyw0LjI5ODQ4IDEwLjk2NTEsNCAxMS4zMzMzLDQgQzExLjcwMTUsNCAxMiw0LjI5ODQ4IDEyLDQuNjY2NjcgQzEyLDUuMDM0ODYgMTEuNzAxNSw1LjMzMzMzIDExLjMzMzMsNS4zMzMzMyBDMTAuOTY1MSw1LjMzMzMzIDEwLjY2NjcsNS4wMzQ4NiAxMC42NjY3LDQuNjY2NjcgWiIgaWQ9IlNoYXBlIj48L3BhdGg+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0xMC42NjY3LDAgQzcuNzIxMTUsMCA1LjMzMzMzLDIuMzg3ODEgNS4zMzMzMyw1LjMzMzMzIEM1LjMzMzMzLDUuNzYxMTkgNS4zODM4NSw2LjE3Nzk4IDUuNDc5NDUsNi41Nzc3NSBMMC4xOTUyNjIsMTEuODYxOSBDMC4wNzAyMzc5LDExLjk4NyAwLDEyLjE1NjUgMCwxMi4zMzMzIEwwLDE1LjMzMzMgQzAsMTUuNzAxNSAwLjI5ODQ3NywxNiAwLjY2NjY2NywxNiBMMy4zMzMzMywxNiBDNC4wNjk3MSwxNiA0LjY2NjY3LDE1LjQwMyA0LjY2NjY3LDE0LjY2NjcgTDQuNjY2NjcsMTQgTDUuMzMzMzMsMTQgQzYuMDY5NzEsMTQgNi42NjY2NywxMy40MDMgNi42NjY2NywxMi42NjY3IEw2LjY2NjY3LDExLjMzMzMgTDgsMTEuMzMzMyBDOC4xNzY4MSwxMS4zMzMzIDguMzQ2MzgsMTEuMjYzMSA4LjQ3MTQxLDExLjEzODEgTDkuMTU5MDYsMTAuNDUwNCBDOS42Mzc3MiwxMC41OTEyIDEwLjE0MzksMTAuNjY2NyAxMC42NjY3LDEwLjY2NjcgQzEzLjYxMjIsMTAuNjY2NyAxNiw4LjI3ODg1IDE2LDUuMzMzMzMgQzE2LDIuMzg3ODEgMTMuNjEyMiwwIDEwLjY2NjcsMCBaIE02LjY2NjY3LDUuMzMzMzMgQzYuNjY2NjcsMy4xMjQxOSA4LjQ1NzUzLDEuMzMzMzMgMTAuNjY2NywxLjMzMzMzIEMxMi44NzU4LDEuMzMzMzMgMTQuNjY2NywzLjEyNDE5IDE0LjY2NjcsNS4zMzMzMyBDMTQuNjY2Nyw3LjU0MjQ3IDEyLjg3NTgsOS4zMzMzMyAxMC42NjY3LDkuMzMzMzMgQzEwLjE1NTgsOS4zMzMzMyA5LjY2ODg2LDkuMjM3OSA5LjIyMTUyLDkuMDY0NSBDOC45NzUyOCw4Ljk2OTA1IDguNjk1OTEsOS4wMjc5NSA4LjUwOTE2LDkuMjE0NjkgTDcuNzIzODYsMTAgTDYsMTAgQzUuNjMxODEsMTAgNS4zMzMzMywxMC4yOTg1IDUuMzMzMzMsMTAuNjY2NyBMNS4zMzMzMywxMi42NjY3IEw0LDEyLjY2NjcgQzMuNjMxODEsMTIuNjY2NyAzLjMzMzMzLDEyLjk2NTEgMy4zMzMzMywxMy4zMzMzIEwzLjMzMzMzLDE0LjY2NjcgTDEuMzMzMzMsMTQuNjY2NyBMMS4zMzMzMywxMi42MDk1IEw2LjY5Nzg3LDcuMjQ0OTQgQzYuODc1MDIsNy4wNjc3OSA2LjkzNzksNi44MDYyOSA2Ljg2MDY1LDYuNTY3OTggQzYuNzM0ODksNi4xNzk5NyA2LjY2NjY3LDUuNzY1MjcgNi42NjY2Nyw1LjMzMzMzIFoiIGlkPSJTaGFwZSI+PC9wYXRoPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+');\n}\n.tooltip__button--data--credentials:hover::before {\n background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMjRweCIgaGVpZ2h0PSIyNHB4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8dGl0bGU+ZGRnLXBhc3N3b3JkLWljb24tYmFzZS13aGl0ZTwvdGl0bGU+CiAgICA8ZyBpZD0iZGRnLXBhc3N3b3JkLWljb24tYmFzZS13aGl0ZSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9IlVuaW9uIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0LjAwMDAwMCwgNC4wMDAwMDApIiBmaWxsPSIjRkZGRkZGIj4KICAgICAgICAgICAgPHBhdGggZD0iTTExLjMzMzMsMi42NjY2NyBDMTAuMjI4OCwyLjY2NjY3IDkuMzMzMzMsMy41NjIxIDkuMzMzMzMsNC42NjY2NyBDOS4zMzMzMyw1Ljc3MTI0IDEwLjIyODgsNi42NjY2NyAxMS4zMzMzLDYuNjY2NjcgQzEyLjQzNzksNi42NjY2NyAxMy4zMzMzLDUuNzcxMjQgMTMuMzMzMyw0LjY2NjY3IEMxMy4zMzMzLDMuNTYyMSAxMi40Mzc5LDIuNjY2NjcgMTEuMzMzMywyLjY2NjY3IFogTTEwLjY2NjcsNC42NjY2NyBDMTAuNjY2Nyw0LjI5ODQ4IDEwLjk2NTEsNCAxMS4zMzMzLDQgQzExLjcwMTUsNCAxMiw0LjI5ODQ4IDEyLDQuNjY2NjcgQzEyLDUuMDM0ODYgMTEuNzAxNSw1LjMzMzMzIDExLjMzMzMsNS4zMzMzMyBDMTAuOTY1MSw1LjMzMzMzIDEwLjY2NjcsNS4wMzQ4NiAxMC42NjY3LDQuNjY2NjcgWiIgaWQ9IlNoYXBlIj48L3BhdGg+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0xMC42NjY3LDAgQzcuNzIxMTUsMCA1LjMzMzMzLDIuMzg3ODEgNS4zMzMzMyw1LjMzMzMzIEM1LjMzMzMzLDUuNzYxMTkgNS4zODM4NSw2LjE3Nzk4IDUuNDc5NDUsNi41Nzc3NSBMMC4xOTUyNjIsMTEuODYxOSBDMC4wNzAyMzc5LDExLjk4NyAwLDEyLjE1NjUgMCwxMi4zMzMzIEwwLDE1LjMzMzMgQzAsMTUuNzAxNSAwLjI5ODQ3NywxNiAwLjY2NjY2NywxNiBMMy4zMzMzMywxNiBDNC4wNjk3MSwxNiA0LjY2NjY3LDE1LjQwMyA0LjY2NjY3LDE0LjY2NjcgTDQuNjY2NjcsMTQgTDUuMzMzMzMsMTQgQzYuMDY5NzEsMTQgNi42NjY2NywxMy40MDMgNi42NjY2NywxMi42NjY3IEw2LjY2NjY3LDExLjMzMzMgTDgsMTEuMzMzMyBDOC4xNzY4MSwxMS4zMzMzIDguMzQ2MzgsMTEuMjYzMSA4LjQ3MTQxLDExLjEzODEgTDkuMTU5MDYsMTAuNDUwNCBDOS42Mzc3MiwxMC41OTEyIDEwLjE0MzksMTAuNjY2NyAxMC42NjY3LDEwLjY2NjcgQzEzLjYxMjIsMTAuNjY2NyAxNiw4LjI3ODg1IDE2LDUuMzMzMzMgQzE2LDIuMzg3ODEgMTMuNjEyMiwwIDEwLjY2NjcsMCBaIE02LjY2NjY3LDUuMzMzMzMgQzYuNjY2NjcsMy4xMjQxOSA4LjQ1NzUzLDEuMzMzMzMgMTAuNjY2NywxLjMzMzMzIEMxMi44NzU4LDEuMzMzMzMgMTQuNjY2NywzLjEyNDE5IDE0LjY2NjcsNS4zMzMzMyBDMTQuNjY2Nyw3LjU0MjQ3IDEyLjg3NTgsOS4zMzMzMyAxMC42NjY3LDkuMzMzMzMgQzEwLjE1NTgsOS4zMzMzMyA5LjY2ODg2LDkuMjM3OSA5LjIyMTUyLDkuMDY0NSBDOC45NzUyOCw4Ljk2OTA1IDguNjk1OTEsOS4wMjc5NSA4LjUwOTE2LDkuMjE0NjkgTDcuNzIzODYsMTAgTDYsMTAgQzUuNjMxODEsMTAgNS4zMzMzMywxMC4yOTg1IDUuMzMzMzMsMTAuNjY2NyBMNS4zMzMzMywxMi42NjY3IEw0LDEyLjY2NjcgQzMuNjMxODEsMTIuNjY2NyAzLjMzMzMzLDEyLjk2NTEgMy4zMzMzMywxMy4zMzMzIEwzLjMzMzMzLDE0LjY2NjcgTDEuMzMzMzMsMTQuNjY2NyBMMS4zMzMzMywxMi42MDk1IEw2LjY5Nzg3LDcuMjQ0OTQgQzYuODc1MDIsNy4wNjc3OSA2LjkzNzksNi44MDYyOSA2Ljg2MDY1LDYuNTY3OTggQzYuNzM0ODksNi4xNzk5NyA2LjY2NjY3LDUuNzY1MjcgNi42NjY2Nyw1LjMzMzMzIFoiIGlkPSJTaGFwZSI+PC9wYXRoPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+');\n}\n.tooltip__button--data--creditCard::before {\n background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+CiAgICA8cGF0aCBkPSJNNSA5Yy0uNTUyIDAtMSAuNDQ4LTEgMXYyYzAgLjU1Mi40NDggMSAxIDFoM2MuNTUyIDAgMS0uNDQ4IDEtMXYtMmMwLS41NTItLjQ0OC0xLTEtMUg1eiIgZmlsbD0iIzAwMCIvPgogICAgPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xIDZjMC0yLjIxIDEuNzktNCA0LTRoMTRjMi4yMSAwIDQgMS43OSA0IDR2MTJjMCAyLjIxLTEuNzkgNC00IDRINWMtMi4yMSAwLTQtMS43OS00LTRWNnptNC0yYy0xLjEwNSAwLTIgLjg5NS0yIDJ2OWgxOFY2YzAtMS4xMDUtLjg5NS0yLTItMkg1em0wIDE2Yy0xLjEwNSAwLTItLjg5NS0yLTJoMThjMCAxLjEwNS0uODk1IDItMiAySDV6IiBmaWxsPSIjMDAwIi8+Cjwvc3ZnPgo=');\n}\n.tooltip__button--data--creditCard:hover::before {\n background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+CiAgICA8cGF0aCBkPSJNNSA5Yy0uNTUyIDAtMSAuNDQ4LTEgMXYyYzAgLjU1Mi40NDggMSAxIDFoM2MuNTUyIDAgMS0uNDQ4IDEtMXYtMmMwLS41NTItLjQ0OC0xLTEtMUg1eiIgZmlsbD0iI2ZmZiIvPgogICAgPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xIDZjMC0yLjIxIDEuNzktNCA0LTRoMTRjMi4yMSAwIDQgMS43OSA0IDR2MTJjMCAyLjIxLTEuNzkgNC00IDRINWMtMi4yMSAwLTQtMS43OS00LTRWNnptNC0yYy0xLjEwNSAwLTIgLjg5NS0yIDJ2OWgxOFY2YzAtMS4xMDUtLjg5NS0yLTItMkg1em0wIDE2Yy0xLjEwNSAwLTItLjg5NS0yLTJoMThjMCAxLjEwNS0uODk1IDItMiAySDV6IiBmaWxsPSIjZmZmIi8+Cjwvc3ZnPgo=');\n}\n\n/* Email tooltip specific */\n.tooltip__button--email {\n flex-direction: column;\n justify-content: center;\n align-items: flex-start;\n font-size: 14px;\n}\n.tooltip__button--email__primary-text {\n font-weight: bold;\n}\n.tooltip__button--email__secondary-text {\n font-size: 12px;\n}\n"; +module.exports = "\n.wrapper *, .wrapper *::before, .wrapper *::after {\n box-sizing: border-box;\n}\n.wrapper {\n position: fixed;\n top: 0;\n left: 0;\n padding: 0;\n font-family: 'DDG_ProximaNova', 'Proxima Nova', -apple-system,\n BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu',\n 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;\n -webkit-font-smoothing: antialiased;\n /* move it offscreen to avoid flashing */\n transform: translate(-1000px);\n z-index: 2147483647;\n}\n:not(.top-autofill).wrapper--data {\n font-family: 'SF Pro Text', -apple-system,\n BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu',\n 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;\n}\n:not(.top-autofill) .tooltip {\n position: absolute;\n width: 300px;\n max-width: calc(100vw - 25px);\n z-index: 2147483647;\n}\n.tooltip--data, #topAutofill {\n background-color: rgba(242, 240, 240, 0.9);\n -webkit-backdrop-filter: blur(40px);\n backdrop-filter: blur(40px);\n}\n.tooltip--data {\n padding: 6px;\n font-size: 13px;\n line-height: 14px;\n width: 315px;\n}\n:not(.top-autofill) .tooltip--data {\n top: 100%;\n left: 100%;\n border: 0.5px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n box-shadow: 0 10px 20px rgba(0, 0, 0, 0.32);\n}\n:not(.top-autofill) .tooltip--email {\n top: calc(100% + 6px);\n right: calc(100% - 46px);\n padding: 8px;\n border: 1px solid #D0D0D0;\n border-radius: 10px;\n background-color: #FFFFFF;\n font-size: 14px;\n line-height: 1.3;\n color: #333333;\n box-shadow: 0 10px 20px rgba(0, 0, 0, 0.15);\n}\n.tooltip--email::before,\n.tooltip--email::after {\n content: \"\";\n width: 0;\n height: 0;\n border-left: 10px solid transparent;\n border-right: 10px solid transparent;\n display: block;\n border-bottom: 8px solid #D0D0D0;\n position: absolute;\n right: 20px;\n}\n.tooltip--email::before {\n border-bottom-color: #D0D0D0;\n top: -9px;\n}\n.tooltip--email::after {\n border-bottom-color: #FFFFFF;\n top: -8px;\n}\n\n/* Buttons */\n.tooltip__button {\n display: flex;\n width: 100%;\n padding: 8px 0px;\n font-family: inherit;\n color: inherit;\n background: transparent;\n border: none;\n border-radius: 6px;\n}\n.tooltip__button.currentFocus,\n.tooltip__button:hover {\n background-color: rgba(0, 121, 242, 0.8);\n color: #FFFFFF;\n}\n\n/* Data autofill tooltip specific */\n.tooltip__button--data {\n min-height: 48px;\n flex-direction: row;\n justify-content: flex-start;\n font-size: inherit;\n font-weight: 500;\n line-height: 16px;\n text-align: left;\n}\n.tooltip__button--data > * {\n opacity: 0.9;\n}\n.tooltip__button--data:first-child {\n margin-top: 0;\n}\n.tooltip__button--data:last-child {\n margin-bottom: 0;\n}\n.tooltip__button--data::before {\n content: '';\n flex-shrink: 0;\n display: block;\n width: 32px;\n height: 32px;\n margin: 0 8px;\n background-size: 24px 24px;\n background-repeat: no-repeat;\n background-position: center 1px;\n}\n.tooltip__button--data.currentFocus::before,\n.tooltip__button--data:hover::before {\n filter: invert(100%);\n}\n.tooltip__button__text-container {\n margin: auto 0;\n}\n.label {\n display: block;\n font-weight: 400;\n letter-spacing: -0.25px;\n color: rgba(0,0,0,.8);\n line-height: 13px;\n}\n.label + .label {\n margin-top: 5px; \n}\n.label.label--medium {\n letter-spacing: -0.08px;\n color: rgba(0,0,0,.9)\n}\n.label.label--small {\n font-size: 11px;\n font-weight: 400;\n letter-spacing: 0.06px;\n color: rgba(0,0,0,0.6);\n}\n.tooltip__button.currentFocus .label,\n.tooltip__button:hover .label,\n.tooltip__button.currentFocus .label,\n.tooltip__button:hover .label {\n color: #FFFFFF;\n}\n\n/* Icons */\n.tooltip__button--data--credentials::before {\n /* TODO: use dynamically from src/UI/img/ddgPasswordIcon.js */\n background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik05LjYzNiA4LjY4MkM5LjYzNiA1LjU0NCAxMi4xOCAzIDE1LjMxOCAzIDE4LjQ1NiAzIDIxIDUuNTQ0IDIxIDguNjgyYzAgMy4xMzgtMi41NDQgNS42ODItNS42ODIgNS42ODItLjY5MiAwLTEuMzUzLS4xMjQtMS45NjQtLjM0OS0uMzcyLS4xMzctLjc5LS4wNDEtMS4wNjYuMjQ1bC0uNzEzLjc0SDEwYy0uNTUyIDAtMSAuNDQ4LTEgMXYySDdjLS41NTIgMC0xIC40NDgtMSAxdjJIM3YtMi44ODFsNi42NjgtNi42NjhjLjI2NS0uMjY2LjM2LS42NTguMjQ0LTEuMDE1LS4xNzktLjU1MS0uMjc2LTEuMTQtLjI3Ni0xLjc1NHpNMTUuMzE4IDFjLTQuMjQyIDAtNy42ODIgMy40NC03LjY4MiA3LjY4MiAwIC42MDcuMDcxIDEuMi4yMDUgMS43NjdsLTYuNTQ4IDYuNTQ4Yy0uMTg4LjE4OC0uMjkzLjQ0Mi0uMjkzLjcwOFYyMmMwIC4yNjUuMTA1LjUyLjI5My43MDcuMTg3LjE4OC40NDIuMjkzLjcwNy4yOTNoNGMxLjEwNSAwIDItLjg5NSAyLTJ2LTFoMWMxLjEwNSAwIDItLjg5NSAyLTJ2LTFoMWMuMjcyIDAgLjUzMi0uMTEuNzItLjMwNmwuNTc3LS42Yy42NDUuMTc2IDEuMzIzLjI3IDIuMDIxLjI3IDQuMjQzIDAgNy42ODItMy40NCA3LjY4Mi03LjY4MkMyMyA0LjQzOSAxOS41NiAxIDE1LjMxOCAxek0xNSA4YzAtLjU1Mi40NDgtMSAxLTFzMSAuNDQ4IDEgMS0uNDQ4IDEtMSAxLTEtLjQ0OC0xLTF6bTEtM2MtMS42NTcgMC0zIDEuMzQzLTMgM3MxLjM0MyAzIDMgMyAzLTEuMzQzIDMtMy0xLjM0My0zLTMtM3oiIGZpbGw9IiMwMDAiIGZpbGwtb3BhY2l0eT0iLjkiLz4KPC9zdmc+');\n}\n.tooltip__button--data--creditCard::before {\n background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+CiAgICA8cGF0aCBkPSJNNSA5Yy0uNTUyIDAtMSAuNDQ4LTEgMXYyYzAgLjU1Mi40NDggMSAxIDFoM2MuNTUyIDAgMS0uNDQ4IDEtMXYtMmMwLS41NTItLjQ0OC0xLTEtMUg1eiIgZmlsbD0iIzAwMCIvPgogICAgPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xIDZjMC0yLjIxIDEuNzktNCA0LTRoMTRjMi4yMSAwIDQgMS43OSA0IDR2MTJjMCAyLjIxLTEuNzkgNC00IDRINWMtMi4yMSAwLTQtMS43OS00LTRWNnptNC0yYy0xLjEwNSAwLTIgLjg5NS0yIDJ2OWgxOFY2YzAtMS4xMDUtLjg5NS0yLTItMkg1em0wIDE2Yy0xLjEwNSAwLTItLjg5NS0yLTJoMThjMCAxLjEwNS0uODk1IDItMiAySDV6IiBmaWxsPSIjMDAwIi8+Cjwvc3ZnPgo=');\n}\n.tooltip__button--data--identities::before {\n background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+CiAgICA8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTEyIDIxYzIuMTQzIDAgNC4xMTEtLjc1IDUuNjU3LTItLjYyNi0uNTA2LTEuMzE4LS45MjctMi4wNi0xLjI1LTEuMS0uNDgtMi4yODUtLjczNS0zLjQ4Ni0uNzUtMS4yLS4wMTQtMi4zOTIuMjExLTMuNTA0LjY2NC0uODE3LjMzMy0xLjU4Ljc4My0yLjI2NCAxLjMzNiAxLjU0NiAxLjI1IDMuNTE0IDIgNS42NTcgMnptNC4zOTctNS4wODNjLjk2Ny40MjIgMS44NjYuOTggMi42NzIgMS42NTVDMjAuMjc5IDE2LjAzOSAyMSAxNC4xMDQgMjEgMTJjMC00Ljk3LTQuMDMtOS05LTlzLTkgNC4wMy05IDljMCAyLjEwNC43MjIgNC4wNCAxLjkzMiA1LjU3Mi44NzQtLjczNCAxLjg2LTEuMzI4IDIuOTIxLTEuNzYgMS4zNi0uNTU0IDIuODE2LS44MyA0LjI4My0uODExIDEuNDY3LjAxOCAyLjkxNi4zMyA0LjI2LjkxNnpNMTIgMjNjNi4wNzUgMCAxMS00LjkyNSAxMS0xMVMxOC4wNzUgMSAxMiAxIDEgNS45MjUgMSAxMnM0LjkyNSAxMSAxMSAxMXptMy0xM2MwIDEuNjU3LTEuMzQzIDMtMyAzcy0zLTEuMzQzLTMtMyAxLjM0My0zIDMtMyAzIDEuMzQzIDMgM3ptMiAwYzAgMi43NjEtMi4yMzkgNS01IDVzLTUtMi4yMzktNS01IDIuMjM5LTUgNS01IDUgMi4yMzkgNSA1eiIgZmlsbD0iIzAwMCIvPgo8L3N2Zz4=');\n}\n\nhr {\n display: block;\n margin: 5px 10px;\n border: none; /* reset the border */\n border-top: 1px solid rgba(0,0,0,.1);\n}\n\nhr:first-child {\n display: none;\n}\n\n#privateAddress {\n align-items: flex-start;\n}\n#personalAddress::before,\n#privateAddress::before,\n#personalAddress.currentFocus::before,\n#personalAddress:hover::before,\n#privateAddress.currentFocus::before,\n#privateAddress:hover::before {\n filter: none;\n background-image: url('data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgNDQgNDQiIHdpZHRoPSIyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+PGxpbmVhckdyYWRpZW50IGlkPSJhIj48c3RvcCBvZmZzZXQ9Ii4wMSIgc3RvcC1jb2xvcj0iIzYxNzZiOSIvPjxzdG9wIG9mZnNldD0iLjY5IiBzdG9wLWNvbG9yPSIjMzk0YTlmIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImIiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMTMuOTI5NyIgeDI9IjE3LjA3MiIgeGxpbms6aHJlZj0iI2EiIHkxPSIxNi4zOTgiIHkyPSIxNi4zOTgiLz48bGluZWFyR3JhZGllbnQgaWQ9ImMiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMjMuODExNSIgeDI9IjI2LjY3NTIiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMTQuOTY3OSIgeTI9IjE0Ljk2NzkiLz48bWFzayBpZD0iZCIgaGVpZ2h0PSI0MCIgbWFza1VuaXRzPSJ1c2VyU3BhY2VPblVzZSIgd2lkdGg9IjQwIiB4PSIyIiB5PSIyIj48cGF0aCBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Im0yMi4wMDAzIDQxLjA2NjljMTAuNTMwMiAwIDE5LjA2NjYtOC41MzY0IDE5LjA2NjYtMTkuMDY2NiAwLTEwLjUzMDMtOC41MzY0LTE5LjA2NjcxLTE5LjA2NjYtMTkuMDY2NzEtMTAuNTMwMyAwLTE5LjA2NjcxIDguNTM2NDEtMTkuMDY2NzEgMTkuMDY2NzEgMCAxMC41MzAyIDguNTM2NDEgMTkuMDY2NiAxOS4wNjY3MSAxOS4wNjY2eiIgZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIi8+PC9tYXNrPjxwYXRoIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0ibTIyIDQ0YzEyLjE1MDMgMCAyMi05Ljg0OTcgMjItMjIgMC0xMi4xNTAyNi05Ljg0OTctMjItMjItMjItMTIuMTUwMjYgMC0yMiA5Ljg0OTc0LTIyIDIyIDAgMTIuMTUwMyA5Ljg0OTc0IDIyIDIyIDIyeiIgZmlsbD0iI2RlNTgzMyIgZmlsbC1ydWxlPSJldmVub2RkIi8+PGcgbWFzaz0idXJsKCNkKSI+PHBhdGggY2xpcC1ydWxlPSJldmVub2RkIiBkPSJtMjYuMDgxMyA0MS42Mzg2Yy0uOTIwMy0xLjc4OTMtMS44MDAzLTMuNDM1Ni0yLjM0NjYtNC41MjQ2LTEuNDUyLTIuOTA3Ny0yLjkxMTQtNy4wMDctMi4yNDc3LTkuNjUwNy4xMjEtLjQ4MDMtMS4zNjc3LTE3Ljc4Njk5LTIuNDItMTguMzQ0MzItMS4xNjk3LS42MjMzMy0zLjcxMDctMS40NDQ2Ny01LjAyNy0xLjY2NDY3LS45MTY3LS4xNDY2Ni0xLjEyNTcuMTEtMS41MTA3LjE2ODY3LjM2My4wMzY2NyAyLjA5Ljg4NzMzIDIuNDIzNy45MzUtLjMzMzcuMjI3MzMtMS4zMi0uMDA3MzMtMS45NTA3LjI3MTMzLS4zMTkuMTQ2NjctLjU1NzMuNjg5MzQtLjU1Ljk0NiAxLjc5NjctLjE4MzMzIDQuNjA1NC0uMDAzNjYgNi4yNy43MzMyOS0xLjMyMzYuMTUwNC0zLjMzMy4zMTktNC4xOTgzLjc3MzctMi41MDggMS4zMi0zLjYxNTMgNC40MTEtMi45NTUzIDguMTE0My42NTYzIDMuNjk2IDMuNTY0IDE3LjE3ODQgNC40OTE2IDIxLjY4MS45MjQgNC40OTkgMTEuNTUzNyAzLjU1NjcgMTAuMDE3NC41NjF6IiBmaWxsPSIjZDVkN2Q4IiBmaWxsLXJ1bGU9ImV2ZW5vZGQiLz48cGF0aCBkPSJtMjIuMjg2NSAyNi44NDM5Yy0uNjYgMi42NDM2Ljc5MiA2LjczOTMgMi4yNDc2IDkuNjUwNi40ODkxLjk3MjcgMS4yNDM4IDIuMzkyMSAyLjA1NTggMy45NjM3LTEuODk0LjQ2OTMtNi40ODk1IDEuMTI2NC05LjcxOTEgMC0uOTI0LTQuNDkxNy0zLjgzMTctMTcuOTc3Ny00LjQ5NTMtMjEuNjgxLS42Ni0zLjcwMzMgMC02LjM0NyAyLjUxNTMtNy42NjcuODYxNy0uNDU0NyAyLjA5MzctLjc4NDcgMy40MTM3LS45MzEzLTEuNjY0Ny0uNzQwNy0zLjYzNzQtMS4wMjY3LTUuNDQxNC0uODQzMzYtLjAwNzMtLjc2MjY3IDEuMzM4NC0uNzE4NjcgMS44NDQ0LTEuMDYzMzQtLjMzMzctLjA0NzY2LTEuMTYyNC0uNzk1NjYtMS41MjktLjgzMjMzIDIuMjg4My0uMzkyNDQgNC42NDIzLS4wMjEzOCA2LjY5OSAxLjA1NiAxLjA0ODYuNTYxIDEuNzg5MyAxLjE2MjMzIDIuMjQ3NiAxLjc5MzAzIDEuMTk1NC4yMjczIDIuMjUxNC42NiAyLjk0MDcgMS4zNDkzIDIuMTE5MyAyLjExNTcgNC4wMTEzIDYuOTUyIDMuMjE5MyA5LjczMTMtLjIyMzYuNzctLjczMzMgMS4zMzEtMS4zNzEzIDEuNzk2Ny0xLjIzOTMuOTAyLTEuMDE5My0xLjA0NS00LjEwMy45NzE3LS4zOTk3LjI2MDMtLjM5OTcgMi4yMjU2LS41MjQzIDIuNzA2eiIgZmlsbD0iI2ZmZiIvPjwvZz48ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCI+PHBhdGggZD0ibTE2LjY3MjQgMjAuMzU0Yy43Njc1IDAgMS4zODk2LS42MjIxIDEuMzg5Ni0xLjM4OTZzLS42MjIxLTEuMzg5Ny0xLjM4OTYtMS4zODk3LTEuMzg5Ny42MjIyLTEuMzg5NyAxLjM4OTcuNjIyMiAxLjM4OTYgMS4zODk3IDEuMzg5NnoiIGZpbGw9IiMyZDRmOGUiLz48cGF0aCBkPSJtMTcuMjkyNCAxOC44NjE3Yy4xOTg1IDAgLjM1OTQtLjE2MDguMzU5NC0uMzU5M3MtLjE2MDktLjM1OTMtLjM1OTQtLjM1OTNjLS4xOTg0IDAtLjM1OTMuMTYwOC0uMzU5My4zNTkzcy4xNjA5LjM1OTMuMzU5My4zNTkzeiIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Im0yNS45NTY4IDE5LjMzMTFjLjY1ODEgMCAxLjE5MTctLjUzMzUgMS4xOTE3LTEuMTkxNyAwLS42NTgxLS41MzM2LTEuMTkxNi0xLjE5MTctMS4xOTE2cy0xLjE5MTcuNTMzNS0xLjE5MTcgMS4xOTE2YzAgLjY1ODIuNTMzNiAxLjE5MTcgMS4xOTE3IDEuMTkxN3oiIGZpbGw9IiMyZDRmOGUiLz48cGF0aCBkPSJtMjYuNDg4MiAxOC4wNTExYy4xNzAxIDAgLjMwOC0uMTM3OS4zMDgtLjMwOHMtLjEzNzktLjMwOC0uMzA4LS4zMDgtLjMwOC4xMzc5LS4zMDguMzA4LjEzNzkuMzA4LjMwOC4zMDh6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTE3LjA3MiAxNC45NDJzLTEuMDQ4Ni0uNDc2Ni0yLjA2NDMuMTY1Yy0xLjAxNTcuNjM4LS45NzkgMS4yOTA3LS45NzkgMS4yOTA3cy0uNTM5LTEuMjAyNy44OTgzLTEuNzkzYzEuNDQxLS41ODY3IDIuMTQ1LjMzNzMgMi4xNDUuMzM3M3oiIGZpbGw9InVybCgjYikiLz48cGF0aCBkPSJtMjYuNjc1MiAxNC44NDY3cy0uNzUxNy0uNDI5LTEuMzM4My0uNDIxN2MtMS4xOTkuMDE0Ny0xLjUyNTQuNTQyNy0xLjUyNTQuNTQyN3MuMjAxNy0xLjI2MTQgMS43MzQ0LTEuMDA4NGMuNDk5Ny4wOTE0LjkyMjMuNDIzNCAxLjEyOTMuODg3NHoiIGZpbGw9InVybCgjYykiLz48cGF0aCBkPSJtMjAuOTI1OCAyNC4zMjFjLjEzOTMtLjg0MzMgMi4zMS0yLjQzMSAzLjg1LTIuNTMgMS41NC0uMDk1MyAyLjAxNjctLjA3MzMgMy4zLS4zODEzIDEuMjg3LS4zMDQzIDQuNTk4LTEuMTI5MyA1LjUxMS0xLjU1NDcuOTE2Ny0uNDIxNiA0LjgwMzMuMjA5IDIuMDY0MyAxLjczOC0xLjE4NDMuNjYzNy00LjM3OCAxLjg4MS02LjY2MjMgMi41NjMtMi4yODA3LjY4Mi0zLjY2My0uNjUyNi00LjQyMi40Njk0LS42MDEzLjg5MS0uMTIxIDIuMTEyIDIuNjAzMyAyLjM2NSAzLjY4MTQuMzQxIDcuMjA4Ny0xLjY1NzQgNy41OTc0LS41OTQuMzg4NiAxLjA2MzMtMy4xNjA3IDIuMzgzMy01LjMyNCAyLjQyNzMtMi4xNjM0LjA0MDMtNi41MTk0LTEuNDMtNy4xNzItMS44ODQ3LS42NTY0LS40NTEtMS41MjU0LTEuNTE0My0xLjM0NTctMi42MTh6IiBmaWxsPSIjZmRkMjBhIi8+PHBhdGggZD0ibTI4Ljg4MjUgMzEuODM4NmMtLjc3NzMtLjE3MjQtNC4zMTIgMi41MDA2LTQuMzEyIDIuNTAwNmguMDAzN2wtLjE2NSAyLjA1MzRzNC4wNDA2IDEuNjUzNiA0LjczIDEuMzk3Yy42ODkzLS4yNjQuNTE3LTUuNzc1LS4yNTY3LTUuOTUxem0tMTEuNTQ2MyAxLjAzNGMuMDg0My0xLjExODQgNS4yNTQzIDEuNjQyNiA1LjI1NDMgMS42NDI2bC4wMDM3LS4wMDM2LjI1NjYgMi4xNTZzLTQuMzA4MyAyLjU4MTMtNC45MTMzIDIuMjM2NmMtLjYwMTMtLjM0NDYtLjY4OTMtNC45MDk2LS42MDEzLTYuMDMxNnoiIGZpbGw9IiM2NWJjNDYiLz48cGF0aCBkPSJtMjEuMzQgMzQuODA0OWMwIDEuODA3Ny0uMjYwNCAyLjU4NS41MTMzIDIuNzU3NC43NzczLjE3MjMgMi4yNDAzIDAgMi43NjEtLjM0NDcuNTEzMy0uMzQ0Ny4wODQzLTIuNjY5My0uMDg4LTMuMTAycy0zLjE5LS4wODgtMy4xOS42ODkzeiIgZmlsbD0iIzQzYTI0NCIvPjxwYXRoIGQ9Im0yMS42NzAxIDM0LjQwNTFjMCAxLjgwNzYtLjI2MDQgMi41ODEzLjUxMzMgMi43NTM2Ljc3MzcuMTc2IDIuMjM2NyAwIDIuNzU3My0uMzQ0Ni41MTctLjM0NDcuMDg4LTIuNjY5NC0uMDg0My0zLjEwMi0uMTcyMy0uNDMyNy0zLjE5LS4wODQ0LTMuMTkuNjg5M3oiIGZpbGw9IiM2NWJjNDYiLz48cGF0aCBkPSJtMjIuMDAwMiA0MC40NDgxYzEwLjE4ODUgMCAxOC40NDc5LTguMjU5NCAxOC40NDc5LTE4LjQ0NzlzLTguMjU5NC0xOC40NDc5NS0xOC40NDc5LTE4LjQ0Nzk1LTE4LjQ0Nzk1IDguMjU5NDUtMTguNDQ3OTUgMTguNDQ3OTUgOC4yNTk0NSAxOC40NDc5IDE4LjQ0Nzk1IDE4LjQ0Nzl6bTAgMS43MTg3YzExLjEzNzcgMCAyMC4xNjY2LTkuMDI4OSAyMC4xNjY2LTIwLjE2NjYgMC0xMS4xMzc4LTkuMDI4OS0yMC4xNjY3LTIwLjE2NjYtMjAuMTY2Ny0xMS4xMzc4IDAtMjAuMTY2NyA5LjAyODktMjAuMTY2NyAyMC4xNjY3IDAgMTEuMTM3NyA5LjAyODkgMjAuMTY2NiAyMC4xNjY3IDIwLjE2NjZ6IiBmaWxsPSIjZmZmIi8+PC9nPjwvc3ZnPg==');\n}\n\n/* Email tooltip specific */\n.tooltip__button--email {\n flex-direction: column;\n justify-content: center;\n align-items: flex-start;\n font-size: 14px;\n padding: 4px 8px;\n}\n.tooltip__button--email__primary-text {\n font-weight: bold;\n}\n.tooltip__button--email__secondary-text {\n font-size: 12px;\n}\n"; -},{}],15:[function(require,module,exports){ +},{}],34:[function(require,module,exports){ "use strict"; // Do not remove -- Apple devices change this when they support modern webkit messaging @@ -1889,15 +7403,22 @@ const ddgGlobals = require('./captureDdgGlobals'); * Sends message to the webkit layer (fire and forget) * @param {String} handler * @param {*} data - * @returns {*} */ -const wkSend = (handler, data = {}) => window.webkit.messageHandlers[handler].postMessage({ ...data, - messageHandling: { ...data.messageHandling, - secret +const wkSend = function (handler) { + let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (!(handler in window.webkit.messageHandlers)) { + throw new Error("Missing webkit handler: '".concat(handler, "'")); } -}); + + return window.webkit.messageHandlers[handler].postMessage({ ...data, + messageHandling: { ...data.messageHandling, + secret + } + }); +}; /** * Generate a random method name and adds it to the global scope * The native layer will use this method to send the response @@ -1912,8 +7433,8 @@ const generateRandomMethod = (randomMethodName, callback) => { // configurable, To allow for deletion later configurable: true, writable: false, - value: (...args) => { - callback(...args); + value: function () { + callback(...arguments); delete ddgGlobals.window[randomMethodName]; } }); @@ -1926,10 +7447,12 @@ const generateRandomMethod = (randomMethodName, callback) => { */ -const wkSendAndWait = async (handler, data = {}) => { +const wkSendAndWait = async function (handler) { + let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + if (hasModernWebkitAPI) { const response = await wkSend(handler, data); - return ddgGlobals.JSONparse(response); + return ddgGlobals.JSONparse(response || '{}'); } try { @@ -1951,7 +7474,7 @@ const wkSendAndWait = async (handler, data = {}) => { }); const cipher = new ddgGlobals.Uint8Array([...ciphertext, ...tag]); const decrypted = await decrypt(cipher, key, iv); - return ddgGlobals.JSONparse(decrypted); + return ddgGlobals.JSONparse(decrypted || '{}'); } catch (e) { console.error('decryption failed', e); return { @@ -1993,7 +7516,7 @@ module.exports = { wkSendAndWait }; -},{"./captureDdgGlobals":16}],16:[function(require,module,exports){ +},{"./captureDdgGlobals":35}],35:[function(require,module,exports){ "use strict"; // Capture the globals we need on page start @@ -2019,16 +7542,27 @@ const secretGlobals = { }; module.exports = secretGlobals; -},{}],17:[function(require,module,exports){ +},{}],36:[function(require,module,exports){ "use strict"; -let isApp = false; // Do not modify or remove the next line -- the app code will replace it with `isApp = true;` +const { + getInputSubtype +} = require('./Form/matching'); + +let isApp = false; +let isTopFrame = false; +let supportsTopFrame = false; // Do not modify or remove the next line -- the app code will replace it with `isApp = true;` // INJECT isApp HERE +// INJECT isTopFrame HERE +// INJECT supportsTopFrame HERE -const isDDGApp = /(iPhone|iPad|Android|Mac).*DuckDuckGo\/[0-9]/i.test(window.navigator.userAgent) || isApp; +let isDDGApp = /(iPhone|iPad|Android|Mac).*DuckDuckGo\/[0-9]/i.test(window.navigator.userAgent) || isApp || isTopFrame; const isAndroid = isDDGApp && /Android/i.test(window.navigator.userAgent); const isMobileApp = isDDGApp && !isApp; const DDG_DOMAIN_REGEX = new RegExp(/^https:\/\/(([a-z0-9-_]+?)\.)?duckduckgo\.com\/email/); +const SIGN_IN_MSG = { + signMeIn: true +}; const isDDGDomain = () => window.location.href.match(DDG_DOMAIN_REGEX); // Send a message to the web app (only on DDG domains) @@ -2063,7 +7597,31 @@ const sendAndWaitForAnswer = (msgOrFn, expectedResponse) => { window.addEventListener('message', handler); }); +}; + +const autofillEnabled = processConfig => { + let contentScope = null; + let userUnprotectedDomains = null; + let userPreferences = null; // INJECT contentScope HERE + // INJECT userUnprotectedDomains HERE + // INJECT userPreferences HERE + + if (!contentScope) { + // Return enabled for platforms that haven't implemented the config yet + return true; + } // Check config on Apple platforms + + + const privacyConfig = processConfig(contentScope, userUnprotectedDomains, userPreferences); + const site = privacyConfig.site; + + if (site.isBroken || !site.enabledFeatures.includes('autofill')) { + return false; + } + + return true; }; // Access the original setter (needed to bypass React's implementation on mobile) +// @ts-ignore const originalSet = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set; @@ -2071,6 +7629,7 @@ const originalSet = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prot * Ensures the value is set properly and dispatches events to simulate real user action * @param {HTMLInputElement} el * @param {string | number} val + * @return {boolean} */ const setValueForInput = (el, val) => { @@ -2079,19 +7638,44 @@ const setValueForInput = (el, val) => { el.focus(); } - originalSet.call(el, val); - const events = [new Event('keydown', { + el.dispatchEvent(new Event('keydown', { bubbles: true - }), new Event('keyup', { + })); + originalSet === null || originalSet === void 0 ? void 0 : originalSet.call(el, val); + const events = [new Event('input', { bubbles: true - }), new Event('input', { + }), new Event('keyup', { bubbles: true }), new Event('change', { bubbles: true })]; events.forEach(ev => el.dispatchEvent(ev)); // We call this again to make sure all forms are happy - originalSet.call(el, val); + originalSet === null || originalSet === void 0 ? void 0 : originalSet.call(el, val); + events.forEach(ev => el.dispatchEvent(ev)); + el.blur(); + return true; +}; +/** + * Fires events on a select element to simulate user interaction + * @param {HTMLSelectElement} el + */ + + +const fireEventsOnSelect = el => { + const events = [new Event('mousedown', { + bubbles: true + }), new Event('focus', { + bubbles: true + }), new Event('change', { + bubbles: true + }), new Event('mouseup', { + bubbles: true + }), new Event('click', { + bubbles: true + })]; // Events fire on the select el, not option + + events.forEach(ev => el.dispatchEvent(ev)); events.forEach(ev => el.dispatchEvent(ev)); el.blur(); }; @@ -2100,46 +7684,54 @@ const setValueForInput = (el, val) => { * We assume Select is only used for dates, i.e. in the credit card * @param {HTMLSelectElement} el * @param {string | number} val + * @return {boolean} */ const setValueForSelect = (el, val) => { + const subtype = getInputSubtype(el); + const isMonth = subtype.includes('Month'); + const isZeroBasedNumber = isMonth && el.options[0].value === '0' && el.options.length === 12; // Loop first through all values because they tend to be more precise + for (const option of el.options) { - // TODO: try to match localised month names - const optValue = option.value || option.innerText; - - if (optValue.includes(val)) { - const events = [new Event('mousedown', { - bubbles: true - }), new Event('focus', { - bubbles: true - }), new Event('change', { - bubbles: true - }), new Event('mouseup', { - bubbles: true - }), new Event('click', { - bubbles: true - })]; - option.selected = true; // Events fire on the select el, not option - - events.forEach(ev => el.dispatchEvent(ev)); + // If values for months are zero-based (Jan === 0), add one to match our data type + let value = option.value; + + if (isZeroBasedNumber) { + value = "".concat(Number(value) + 1); + } // TODO: try to match localised month names + + + if (value.includes(String(val))) { option.selected = true; - events.forEach(ev => el.dispatchEvent(ev)); - el.blur(); - return; + fireEventsOnSelect(el); + return true; } } + + for (const option of el.options) { + if (option.innerText.includes(String(val))) { + option.selected = true; + fireEventsOnSelect(el); + return true; + } + } // If we didn't find a matching option return false + + + return false; }; /** * Sets or selects a value to a form element * @param {HTMLInputElement | HTMLSelectElement} el * @param {string | number} val + * @return {boolean} */ const setValue = (el, val) => { - if (el.nodeName === 'INPUT') setValueForInput(el, val); - if (el.nodeName === 'SELECT') setValueForSelect(el, val); + if (el instanceof HTMLInputElement) return setValueForInput(el, val); + if (el instanceof HTMLSelectElement) return setValueForSelect(el, val); + return false; }; /** * Use IntersectionObserver v2 to make sure the element is visible when clicked @@ -2225,7 +7817,10 @@ const isEventWithinDax = (e, input) => { */ -const addInlineStyles = (el, styles) => Object.entries(styles).forEach(([property, val]) => el.style.setProperty(property, val, 'important')); +const addInlineStyles = (el, styles) => Object.entries(styles).forEach(_ref => { + let [property, val] = _ref; + return el.style.setProperty(property, val, 'important'); +}); /** * Removes inline styles from a prop:value object * @param {HTMLElement} el @@ -2242,7 +7837,7 @@ const ADDRESS_DOMAIN = '@duck.com'; * @returns {string} */ -const formatAddress = address => address + ADDRESS_DOMAIN; +const formatDuckAddress = address => address + ADDRESS_DOMAIN; /** * Escapes any occurrences of &, ", <, > or / with XML entities. * @param {string} str The string to escape. @@ -2264,112 +7859,56 @@ function escapeXML(str) { module.exports = { isApp, + isTopFrame, isDDGApp, isAndroid, isMobileApp, + supportsTopFrame, DDG_DOMAIN_REGEX, isDDGDomain, notifyWebApp, sendAndWaitForAnswer, + autofillEnabled, setValue, safeExecute, getDaxBoundingBox, isEventWithinDax, addInlineStyles, removeInlineStyles, + SIGN_IN_MSG, ADDRESS_DOMAIN, - formatAddress, + formatDuckAddress, escapeXML }; -},{}],18:[function(require,module,exports){ +},{"./Form/matching":22}],37:[function(require,module,exports){ "use strict"; -(() => { - try { - if (!window.isSecureContext) return; - - const listenForGlobalFormSubmission = require('./Form/listenForFormSubmission'); - - const { - forms - } = require('./scanForInputs'); - - const { - isApp - } = require('./autofill-utils'); - - const inject = () => { - // Polyfills/shims - require('./requestIdleCallback'); - - const DeviceInterface = require('./DeviceInterface'); // Global listener for event delegation - - - window.addEventListener('pointerdown', e => { - if (!e.isTrusted) return; - - if (e.target.nodeName === 'DDG-AUTOFILL') { - e.preventDefault(); - e.stopImmediatePropagation(); - const activeForm = [...forms.values()].find(form => form.tooltip); - - if (activeForm) { - activeForm.tooltip.dispatchClick(); - } - } - - if (!isApp) return; // Check for clicks on submit buttons - - const matchingForm = [...forms.values()].find(form => { - const btns = [...form.submitButtons]; - if (btns.includes(e.target)) return true; - if (btns.find(btn => btn.contains(e.target))) return true; - }); - matchingForm === null || matchingForm === void 0 ? void 0 : matchingForm.submitHandler(); - }, true); - - if (isApp) { - window.addEventListener('submit', e => { - var _forms$get; - - return (_forms$get = forms.get(e.target)) === null || _forms$get === void 0 ? void 0 : _forms$get.submitHandler(); - }, true); - } - - DeviceInterface.init(); - }; // chrome is only present in desktop browsers +// Polyfills/shims +require('./requestIdleCallback'); +(() => { + if (!window.isSecureContext) return false; - if (typeof chrome === 'undefined') { - listenForGlobalFormSubmission(); - inject(); - } else { - // Check if the site is marked to skip autofill - chrome.runtime.sendMessage({ - registeredTempAutofillContentScript: true, - documentUrl: window.location.href - }, response => { - var _response$site, _response$site$broken; + try { + const deviceInterface = require('./DeviceInterface'); - if (!(response !== null && response !== void 0 && (_response$site = response.site) !== null && _response$site !== void 0 && (_response$site$broken = _response$site.brokenFeatures) !== null && _response$site$broken !== void 0 && _response$site$broken.includes('autofill'))) { - inject(); - } - }); - } - } catch (e) {// Noop, we errored + deviceInterface.init(); + } catch (e) { + console.error(e); // Noop, we errored } })(); -},{"./DeviceInterface":1,"./Form/listenForFormSubmission":7,"./autofill-utils":17,"./requestIdleCallback":20,"./scanForInputs":21}],19:[function(require,module,exports){ +},{"./DeviceInterface":7,"./requestIdleCallback":39}],38:[function(require,module,exports){ "use strict"; module.exports = { ATTR_INPUT_TYPE: 'data-ddg-inputType', - ATTR_AUTOFILL: 'data-ddg-autofill' + ATTR_AUTOFILL: 'data-ddg-autofill', + TEXT_LENGTH_CUTOFF: 50 }; -},{}],20:[function(require,module,exports){ +},{}],39:[function(require,module,exports){ "use strict"; /*! @@ -2391,6 +7930,7 @@ module.exports = { /* * @see https://developers.google.com/web/updates/2015/08/using-requestidlecallback */ +// @ts-ignore window.requestIdleCallback = window.requestIdleCallback || function (cb) { return setTimeout(function () { const start = Date.now(); // eslint-disable-next-line standard/no-callback-literal @@ -2408,30 +7948,52 @@ window.cancelIdleCallback = window.cancelIdleCallback || function (id) { clearTimeout(id); }; -},{}],21:[function(require,module,exports){ +module.exports = {}; + +},{}],40:[function(require,module,exports){ "use strict"; -const Form = require('./Form/Form'); +const { + Form +} = require('./Form/Form'); const { notifyWebApp } = require('./autofill-utils'); const { - FIELD_SELECTOR, - SUBMIT_BUTTON_SELECTOR -} = require('./Form/selectors'); + SUBMIT_BUTTON_SELECTOR, + FORM_INPUTS_SELECTOR +} = require('./Form/selectors-css'); +/** @type Map */ -const forms = new Map(); // Accepts the DeviceInterface as an explicit dependency -const scanForInputs = DeviceInterface => { +const _forms = new Map(); +/** + * This will return `init` and `findEligibleInputs` which allows consumers + * to either `init` if in the context of a webpage, or alternatively just perform + * the synchronous mutations via findEligibleInputs + * + * @param DeviceInterface + * @param {Map} [forms] + * @returns {{ + * init: () => () => void, + * findEligibleInputs: (element: Element|Document) => void + * }} + */ + + +const scanForInputs = function (DeviceInterface) { + let forms = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _forms; + const getParentForm = input => { if (input.form) return input.form; let element = input; // traverse the DOM to search for related inputs - while (element.parentNode && element !== document.body) { - element = element.parentElement; - const inputs = element.querySelectorAll(FIELD_SELECTOR); + while (element.parentElement && element.parentElement !== document.body) { + element = element.parentElement; // todo: These selectors should be configurable + + const inputs = element.querySelectorAll(FORM_INPUTS_SELECTOR); const buttons = element.querySelectorAll(SUBMIT_BUTTON_SELECTOR); // If we find a button or another input, we assume that's our form if (inputs.length > 1 || buttons.length) { @@ -2449,21 +8011,32 @@ const scanForInputs = DeviceInterface => { const previouslyFoundParent = [...forms.keys()].find(form => form.contains(parentForm)); if (previouslyFoundParent) { + var _forms$get; + // If we've already met the form or a descendant, add the input - forms.get(previouslyFoundParent).addInput(input); + (_forms$get = forms.get(previouslyFoundParent)) === null || _forms$get === void 0 ? void 0 : _forms$get.addInput(input); } else { // if this form is an ancestor of an existing form, remove that before adding this const childForm = [...forms.keys()].find(form => parentForm.contains(form)); - forms.delete(childForm); + + if (childForm) { + var _forms$get2; + + (_forms$get2 = forms.get(childForm)) === null || _forms$get2 === void 0 ? void 0 : _forms$get2.destroy(); + forms.delete(childForm); + } + forms.set(parentForm, new Form(parentForm, input, DeviceInterface)); } }; - const findEligibleInput = context => { - if (context.nodeName === 'INPUT' && context.matches(FIELD_SELECTOR)) { + const findEligibleInputs = context => { + var _context$matches; + + if ((_context$matches = context.matches) !== null && _context$matches !== void 0 && _context$matches.call(context, FORM_INPUTS_SELECTOR)) { addInput(context); } else { - context.querySelectorAll(FIELD_SELECTOR).forEach(addInput); + context.querySelectorAll(FORM_INPUTS_SELECTOR).forEach(addInput); } }; // For all DOM mutations, search for new eligible inputs and update existing inputs positions @@ -2477,7 +8050,7 @@ const scanForInputs = DeviceInterface => { if (el instanceof HTMLElement) { window.requestIdleCallback(() => { - findEligibleInput(el); + findEligibleInputs(el); }); } }); @@ -2499,20 +8072,37 @@ const scanForInputs = DeviceInterface => { } }); }; + /** + * Requiring consumers to explicitly call this `init` method allows + * us to view this as stateless, which helps with tests and general hygiene + * + * We return the logoutHandler to allow consumers to do with it as they please, + * rather than this module needing to know to register it. + * + * @returns {logoutHandler} + */ - DeviceInterface.addLogoutListener(logoutHandler); - window.requestIdleCallback(() => { - findEligibleInput(document); - mutObs.observe(document.body, { - childList: true, - subtree: true + + const init = () => { + window.requestIdleCallback(() => { + findEligibleInputs(document); + mutObs.observe(document.body, { + childList: true, + subtree: true + }); }); - }); + return logoutHandler; + }; + + return { + init, + findEligibleInputs + }; }; module.exports = { scanForInputs, - forms + forms: _forms }; -},{"./Form/Form":2,"./Form/selectors":9,"./autofill-utils":17}]},{},[18]); +},{"./Form/Form":12,"./Form/selectors-css":23,"./autofill-utils":36}]},{},[37]); diff --git a/docs/matcher-configuration.md b/docs/matcher-configuration.md new file mode 100644 index 000000000..adaff420c --- /dev/null +++ b/docs/matcher-configuration.md @@ -0,0 +1,167 @@ +## Matcher Definitions + +First of all we have the concept of 'Matcher Definitions', which are small pieces of configuration that +describe how a matcher works at runtime. + +For example, the following `email` definition states that it will use 3 different matching `strategies` at runtime. + +- `cssSelector` +- `ddgMatcher` +- `vendorRegex` + +Under `strategies`, the keys of the object match up to a strategy name, and the values are references to the particular +named item. + +```json +{ + "matchers": { + "fields": { + "email": { + "type": "email", + "strategies": { + "cssSelector": "email", + "ddgMatcher": "email", + "vendorRegex": "email" + } + } + } + } +} +``` + +Matcher definitions are just that, definitions - they cannot perform work alone. They serve only as a declarative +format for specifying which strategies should be executed and in which order. + +Where you see `"cssSelector": "email"` on a field, you can assume that there's a strategy called `cssSelector` +and that it has a field called `email`. + +In the configuration, it will look like this. + +```json +{ + "strategies": { + "cssSelector": { + "selectors": { + "email": "input:not([type])[name*=mail i]:not([readonly]):not([disabled]):not([hidden]):not([aria-hidden=true])" + } + } + } +} +``` + +--- + +A similar format will exist for `ddgMatcher` and `vendorRegex` too. + +## CSS Strategy format + +The CSS strategy is straight forward as it's just a CSS selector + +```json +{ "firstName": "[name*=fname i], [autocomplete*=given-name i]" } +``` + +## DDG Strategy format + +The DDG matcher contains a `match` regex and an optional `not` regex too. + +**NOTE**: The DDG matcher currently only operates on the following: + +- label text +- autocomplete attribute +- related text + +The `name` attribute is missing here because of historical reasons. When the multiple matching strategies were implemented +the DDG regexes + +```json +{ "match": "(first|given|fore).?name" } +``` + +## Vendor Regex Strategy + +For the vendor regexes, we are *mostly* using the regexes provided by the [firefox codebase](https://searchfox.org/mozilla-central/source/toolkit/components/formautofill/content/heuristicsRegexp.js) +- we aim to roughly maintain their format so that we can easily compare updates in the fiuture. + +--- + +## Putting it together + +With those 2 pieces of information, we can say that at runtime if we want to match an input as an `email` field, then we +have the opportunity to execute any of the 3 strategies (or all of them!). + +The ordering will be determined by a private class field on the `Matching` class. + +```javascript +/** @type {Array} */ +#defaultStrategyOrder = ['cssSelector', 'ddgMatcher', 'vendorRegex'] +``` + +The following is pseudocode, but it demonstrates the lookup nature of the matcher definition -> strategies + +```javascript +// loop through all strategy names +for (let strategy of this.#defaultStrategyOrder) { + + // for each strategy, now loop through given fields + for (let field of fields) { + + // does this field reference this particular strategy? + const lookup = matcher.strategies[strategy]; + + // if it does and strategy = `cssSelector`, execute the logic for `cssSelector` + if (lookup && strategy === "cssSelector") { + const css = config.strategies.cssSelector.selectors[lookup]; + if (inputElement.matches(css)) { + return true + } + } + + // repeat for other strategies... + } +} +``` + +## Future-proofing and Remote configuration + +Because this system was carefully designed to accept a declarative configuration format, it will enable modifications +and additions to be easily applied and tested since the bulk of the changes would just be to the configuration only. + +For example, if we ever needed to configure the matching order on a field, a CSS selectors or any of the regexes, +then we can simply apply a patch to the configuration directly, without touching the application logic. + +Although Remote Configuration of this feature will be tackled separately, the work I've done was deliberately designed +in a way that will make these sorts of patches possible in the future. + + +## Matching Logic + +Matching logic runs on lists of Matchers, known in the codebase as `MatcherLists`. For example, the `id` matcher list +consists of `firstname`, `middlename`, `lastname` etc. + +This means that when trying to infer the type of input, we need to consider the fact that each individual matcher +may or may not implement a given strategy. + +For example, this table uses a ✅ to indicate that a matcher uses a particular strategy: + +| type | cssSelector | ddgRegex | vendorRegex | +|------------|-------------|----------|-------------| +| firstname | ✅ | ✅ | ✅ | +| middlename | ✅ | ❌ | ✅ | +| lastname | ✅ | ✅ | ✅ | + + +In that example, the execution order of mathcing would be the following: + +- (`cssSelector`) firstname +- (`cssSelector`) lastname +- (`cssSelector`) middlename +- (`ddgRegex`) firstname +- (`ddgRegex`) lastname +- (`vendorRegex`) firstname +- (`vendorRegex`) middlename +- (`vendorRegex`) lastname + + +You can see that the `cssSelector` selector strategy is attempted for each field before moving onto `ddgRegex` and then +to `vendorRegex` diff --git a/docs/real-world-html-tests.md b/docs/real-world-html-tests.md new file mode 100644 index 000000000..6d1df33ff --- /dev/null +++ b/docs/real-world-html-tests.md @@ -0,0 +1,57 @@ +## Tracking improvements and regressions of Real-world Tests + +Since we cannot offer a 100% perfect solution in terms of input classification, we should instead +aim to create a system that allows us to accurately measure improvement and regressions over time. + +For example, we can configure our test of Twitter's login & signup forms with the following configuration. + +```javascript +// src/Form/test-cases/index.js +module.exports = [ + // snip + { html: 'twitter_login.html' }, + { html: 'twitter_signup.html', expectedFailures: ['birthdayMonth', 'birthdayDay', 'birthdayYear'] }, + // snip +] +``` + +Notice how we are being explicit about `3` known failures in the sign-up forms' html with `expectedFailures`. +This is in contrast to the login form, in which we expect `0` failures. (the absence of the `expectedFailures` has the same meaning as it being empty) + +This gives a clear indication of what is known to be broken, and what is working as expected. + +Then, as we work on individual features, it will be become very clear if we've improved the matching, or if we've made it worse. Either way, this testing setup forces you to either address the regressions, add new exceptions, or remove old ones that are no longer valid. + +### Improvements + +This is the test output you'd see if you've **improved** the matching on `twitter_signup.html` + + Test twitter_signup.html should contain 3 known failures: ['birthdayMonth', 'birthdayDay', 'birthdayYear'], found 0 + +This means you can remove the `expectedFailures` from the test configuration and it's clear in the git log that an improvement was made + +### Regressions + +If a change has reduced the accuracy of matching, for example on `twitter_login` from above, where no failures where expected, you'll get this output instead + + Test twitter_signup.html should NOT contain failures, found 1 ["email"] + +At that point it's very clear what has broken, and you can work to resolve the issue before filing a PR. + + +## Testing Tips + +To run a single real-world test case, you can do the following + +```shell +# Run costco_checkout.html real-world test only +./node_modules/.bin/jest --verbose=false -t 'costco_checkout.html' +``` + +To produce test results as an HTML file, run the following. This is particularly useful +when multiple tests have changed status, and you want an overview. + +```shell +# This will create `test-report.html` in the root of the project which can be opened in a browser +npm run test:report +``` diff --git a/integration-test/config.js b/integration-test/config.js new file mode 100644 index 000000000..111ce810f --- /dev/null +++ b/integration-test/config.js @@ -0,0 +1,10 @@ +export default { + spec_dir: 'integration-test', + jsLoader: 'import', + spec_files: [ + '**/*.js', + '!pages/**/*.js', + '!extension/**/*.js' + ], + random: false +} diff --git a/integration-test/extension/.gitignore b/integration-test/extension/.gitignore new file mode 100644 index 000000000..fbfc94e8c --- /dev/null +++ b/integration-test/extension/.gitignore @@ -0,0 +1,2 @@ +/autofill.js +/public/css/autofill.css diff --git a/integration-test/extension/background.js b/integration-test/extension/background.js new file mode 100644 index 000000000..57be0800f --- /dev/null +++ b/integration-test/extension/background.js @@ -0,0 +1,88 @@ +// const domain = 'duck.co' +let random = Math.round(Math.random() * 10) +const userData = { + userName: 'shane-123', + nextAlias: random +} + +function getAddresses () { + return { + personalAddress: `${userData.userName}`, + privateAddress: `${userData.nextAlias}` + } +} + +async function addUserData (userData, sender) { + const { userName, token } = userData + // Check the origin. Shouldn't be necessary, but better safe than sorry + if (!sender.url.match(/^https:\/\/(([a-z0-9-_]+?)\.)?duckduckgo\.com\/email/)) return + + const sendDdgUserReady = async () => { + const tabs = await browser.tabs.query({}) + tabs.forEach((tab) => + // eslint-disable-next-line no-undef + utils.sendTabMessage(tab.id, { type: 'ddgUserReady' }) + ) + } + + // eslint-disable-next-line no-undef + await settings.ready() + // eslint-disable-next-line no-undef + const { existingToken } = settings.getSetting('userData') || {} + + // If the user is already registered, just notify tabs that we're ready + if (existingToken === token) { + await sendDdgUserReady() + return { success: true } + } + + // Check general data validity + // eslint-disable-next-line no-undef + if (isValidUsername(userName) && isValidToken(token)) { + // eslint-disable-next-line no-undef + settings.updateSetting('userData', userData) + // Once user is set, fetch the alias and notify all tabs + // eslint-disable-next-line no-undef + const response = await fetchAlias() + if (response && response.error) { + return { error: response.error.message } + } + + sendDdgUserReady() + // eslint-disable-next-line no-undef + showContextMenuAction() + return { success: true } + } else { + return { error: 'Something seems wrong with the user data' } + } +} + +function registeredTempAutofillContentScript () { + return { + debug: false, + site: { + isBroken: false, + allowlisted: false, + enabledFeatures: ['autofill'] + } + } +} + +function init () { + chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { + if (message.registeredTempAutofillContentScript) { + return sendResponse(registeredTempAutofillContentScript()) + } else if (message.getAddresses) { + return sendResponse(getAddresses()) + } else if (message.refreshAlias) { + userData.nextAlias = random + 1 + return sendResponse(getAddresses()) + } else if (message.addUserData) { + return sendResponse(addUserData(message.addUserData, sender)) + } + }) + + // TODO handle logout, contextualAutofill and ddgUserReady messages +} + +init() diff --git a/integration-test/extension/img/logo-small.svg b/integration-test/extension/img/logo-small.svg new file mode 100644 index 000000000..c11135856 --- /dev/null +++ b/integration-test/extension/img/logo-small.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/integration-test/extension/inject.js b/integration-test/extension/inject.js new file mode 100644 index 000000000..cc152d04a --- /dev/null +++ b/integration-test/extension/inject.js @@ -0,0 +1,11 @@ +function injectContentScript (src) { + const elem = document.head || document.documentElement + const script = document.createElement('script') + script.src = src + script.onload = function () { + this.remove() + } + elem.appendChild(script) +} + +injectContentScript(chrome.runtime.getURL('/autofill.js')) diff --git a/integration-test/extension/manifest.json b/integration-test/extension/manifest.json new file mode 100644 index 000000000..1eb419d77 --- /dev/null +++ b/integration-test/extension/manifest.json @@ -0,0 +1,29 @@ +{ + "name": "integration-test-extension", + "description": "integration-test-extension", + "version": "1.0", + "manifest_version": 2, + "background": { + "scripts": [ + "background.js" + ] + }, + "permissions": [ + "", + "tabs" + ], + "content_scripts": [ + { + "matches": [""], + "run_at": "document_start", + "js": ["autofill.js"], + "all_frames": true, + "match_about_blank": true + } + ], + "web_accessible_resources": [ + "public/css/autofill.css", + "img/logo-small.svg", + "autofill.js" + ] +} diff --git a/integration-test/extension/public/css/.gitkeep b/integration-test/extension/public/css/.gitkeep new file mode 100644 index 000000000..72e8ffc0d --- /dev/null +++ b/integration-test/extension/public/css/.gitkeep @@ -0,0 +1 @@ +* diff --git a/integration-test/helpers/harness.js b/integration-test/helpers/harness.js new file mode 100644 index 000000000..facb1af24 --- /dev/null +++ b/integration-test/helpers/harness.js @@ -0,0 +1,127 @@ +import * as fs from 'fs' +import * as os from 'os' +import * as path from 'path' +import * as http from 'http' +import puppeteer from 'puppeteer' +import { spawnSync } from 'child_process' + +jasmine.DEFAULT_TIMEOUT_INTERVAL = 20000 +if (process.env.KEEP_OPEN) { + jasmine.DEFAULT_TIMEOUT_INTERVAL = 20000 * 1000 +} + +const DATA_DIR_PREFIX = 'ddg-temp-' + +export async function setup (ops = {}) { + const { withExtension = false } = ops + const tmpDirPrefix = path.join(os.tmpdir(), DATA_DIR_PREFIX) + const dataDir = fs.mkdtempSync(tmpDirPrefix) + const args = [ + `--user-data-dir=${dataDir}` + ] + if (withExtension) { + args.push('--disable-extensions-except=integration-test/extension') + args.push('--load-extension=integration-test/extension') + } + + // github actions + if (process.env.CI) { + args.push('--no-sandbox') + } + + const puppeteerOps = { + args, + headless: false + } + + const browser = await puppeteer.launch(puppeteerOps) + // for some reason we need to init a blank page + // before the extension is initialized + await browser.newPage() + const servers = [] + + async function teardown () { + if (process.env.KEEP_OPEN) { + return new Promise((resolve) => { + browser.on('disconnected', async () => { + await teardownInternal() + resolve() + }) + }) + } else { + await teardownInternal() + } + } + + async function teardownInternal () { + await Promise.all(servers.map(server => server.close())) + await browser.close() + + // necessary so e.g. local storage + // doesn't carry over between test runs + spawnSync('rm', ['-rf', dataDir]) + } + + /** + * @param {number|string} [port] + * @returns {http.Server} + */ + function setupServer (port) { + const server = http.createServer(function (req, res) { + const url = new URL(req.url, `http://${req.headers.host}`) + const importUrl = new URL(import.meta.url) + const dirname = importUrl.pathname.replace(/\/[^/]*$/, '') + const pathname = path.join(dirname, '../pages', url.pathname) + + fs.readFile(pathname, (err, data) => { + if (err) { + res.writeHead(404) + res.end(JSON.stringify(err)) + return + } + res.writeHead(200) + res.end(data) + }) + }).listen(port) + servers.push(server) + return server + } + + /** + * A wrapper around page.goto() that supports sending additional + * arguments to content-scope's init methods + waits for a known + * indicators to avoid race conditions + * + * @param {import("puppeteer").Page} page + * @param {string} urlString + * @param {Record} [args] + * @returns {Promise} + */ + async function gotoAndWait (page, urlString, args = {}) { + const url = new URL(urlString) + + // Append the flag so that the script knows to wait for incoming args. + // url.searchParams.append('wait-for-init-args', 'true') + + await page.goto(url.href, {waitUntil: 'networkidle0'}) + + // // wait until contentScopeFeatures.load() has completed + // await page.waitForFunction(() => { + // return window.__content_scope_status === 'loaded' + // }) + // + // const evalString = ` + // const detail = ${JSON.stringify(args)} + // const evt = new CustomEvent('content-scope-init-args', { detail }) + // document.dispatchEvent(evt) + // ` + // await page.evaluate(evalString) + // + // // wait until contentScopeFeatures.init(args) has completed + // await page.waitForFunction(() => { + // return window.__content_scope_status === 'initialized' + // }) + } + + return { browser, teardown, setupServer, gotoAndWait } +} diff --git a/integration-test/package.json b/integration-test/package.json new file mode 100644 index 000000000..472002573 --- /dev/null +++ b/integration-test/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/integration-test/pages/email-autofill.html b/integration-test/pages/email-autofill.html new file mode 100644 index 000000000..3fe16fc7e --- /dev/null +++ b/integration-test/pages/email-autofill.html @@ -0,0 +1,29 @@ + + + + + + + Email autofill form + + + + +

[Home]

+ +

+ +
+
+

Sign up for our newsletter

+
+ + + +
+
+
+ + + + diff --git a/integration-test/pages/signup.html b/integration-test/pages/signup.html new file mode 100644 index 000000000..52afd1eeb --- /dev/null +++ b/integration-test/pages/signup.html @@ -0,0 +1,40 @@ + + + + + + + Email autofill form + + + + +

[Home]

+ +

+ +
+
+

Sign up for our services

+
+ + + + + + + + + +
+
+
+ + + + diff --git a/integration-test/pages/style.css b/integration-test/pages/style.css new file mode 100644 index 000000000..f5168ae8d --- /dev/null +++ b/integration-test/pages/style.css @@ -0,0 +1,79 @@ +body { + font-family: "Lucida Sans", "Lucida Sans Regular", "Lucida Grande", + "Lucida Sans Unicode", Geneva, Verdana, sans-serif; + padding: 1em; +} + +.dialog { + position: fixed; + left: 50%; + top: 100px; + width: 350px; + height: auto; + padding: 30px; + background-color: #fefefe; + border-radius: 4px; + border: 0.5px solid #999; + box-shadow: 0 5px 20px rgba(0, 0, 0, 0.3); + transform: translateX(-50%); + text-align: center; +} + +hr { + margin: 2em auto; +} + +fieldset { + display: grid; + grid-template-columns: max-content 1fr; + grid-gap: 1em; + max-width: 410px; + padding: 0; + border: none; +} + +label { + align-self: center; + text-align: right; +} + +input, +button, +.button { + font-family: inherit; + font-size: 16px; + line-height: 24px; +} + +button, +.button { + grid-column: span 2; + display: block; + margin: auto; + padding: 5px 20px; + background-color: black; + color: white; + font-weight: bold; + border-radius: 3px; + border: none; + appearance: none; + box-shadow: none; +} + +.button-with-child { + position: relative; + width: 250px; + height: 40px; +} + +.button-with-child i { + position: absolute; + left: 0; + top: 0; + right: 0; + bottom: 0; + display: flex; + justify-content: center; + align-items: center; + z-index: 1000; +} diff --git a/integration-test/tests/email-autofill.extension.js b/integration-test/tests/email-autofill.extension.js new file mode 100644 index 000000000..fbc00edfc --- /dev/null +++ b/integration-test/tests/email-autofill.extension.js @@ -0,0 +1,49 @@ +/** + * Tests for email autofill + */ +import { setup } from '../helpers/harness.js' + +describe('Ensure email autofill works in extension', () => { + /** + * @type {import("puppeteer").Browser} + */ + let browser + let server + let teardown + let setupServer + let gotoAndWait + beforeAll(async () => { + ({ browser, setupServer, teardown, gotoAndWait } = await setup({ withExtension: true })) + server = setupServer() + }) + afterAll(async () => { + await server?.close() + await teardown() + }) + + it('should populate and select email autofill', async () => { + const page = await browser.newPage() + const selector = '[data-ddg-inputtype="identities.emailAddress"]' + const email = 'shane-123@duck.com' + await gotoAndWait(page, `http://localhost:${server.address().port}/email-autofill.html`) + const inputElement = await page.$(selector) + await inputElement.click() + const autofill = await page.$(`ddg-autofill`) + const buttons = await autofill.$$('pierce/button') + + // assert values are populated into the email tooltip + const button1Text = await page.evaluate(elem => elem.textContent.trim(), buttons[0]) + expect(button1Text).toContain('shane-123@duck.com') + expect(button1Text).toContain('Blocks email trackers') + + const button2Text = await page.evaluate(elem => elem.textContent.trim(), buttons[1]) + expect(button2Text).toContain('Use a Private Address') + expect(button2Text).toContain('Blocks email trackers and hides your address') + + // now check that selecting an element works + await buttons[0].click() + + // this is to avoid race conditions with checking the field's value before it's set. + await page.waitForFunction((selector, email) => document.querySelector(selector).value === email, {}, selector, email) + }) +}) diff --git a/jest-test-environment.js b/jest-test-environment.js index 99d1f5981..dabfbba5e 100644 --- a/jest-test-environment.js +++ b/jest-test-environment.js @@ -6,6 +6,7 @@ module.exports = class CustomTestEnvironment extends Environment { if (typeof this.global.TextEncoder === 'undefined') { const { TextEncoder, TextDecoder } = require('util') this.global.TextEncoder = TextEncoder + // @ts-ignore this.global.TextDecoder = TextDecoder } } diff --git a/jest.setup.js b/jest.setup.js index 815e013eb..dd442de1a 100644 --- a/jest.setup.js +++ b/jest.setup.js @@ -1,11 +1,72 @@ Object.assign(global, require('jest-chrome')) +// Mocks chrome API calls needed for autofill to run successfully +// @ts-ignore +chrome.runtime.sendMessage.mockImplementation( + (message, callback) => { + let response = {} + if (message.getAddresses) { + response = { + privateAddress: '123test321', + personalAddress: 'test' + } + } + callback(response) + } +) + +// The autofill script bails if context is insecure, this enables tests to run +global.isSecureContext = true const crypto = require('crypto') Object.defineProperty(global.self, 'crypto', { value: { ...global.self.crypto, + // @ts-ignore TS doesn't know of `crypto.webcrypto.subtle` subtle: crypto.webcrypto.subtle, getRandomValues: arr => crypto.randomFillSync(arr) } }) + +/** + * Utility function that mocks the `IntersectionObserver` API. Necessary for components that rely + * on it, otherwise the tests will crash. Recommended to execute inside `beforeEach`. + * @param intersectionObserverMock - Parameter that is sent to the `Object.defineProperty` + * overwrite method. `jest.fn()` mock functions can be passed here if the goal is to not only + * mock the intersection observer, but its methods. + * @source https://javascript.tutorialink.com/js-testing-code-that-uses-an-intersectionobserver/ + */ +function setupIntersectionObserverMock ({ + root = null, + rootMargin = '', + thresholds = [], + disconnect = () => null, + observe = () => null, + takeRecords = () => [], + unobserve = () => null +} = {}) { + class MockIntersectionObserver { + constructor () { + this.root = root + this.rootMargin = rootMargin + this.thresholds = thresholds + this.disconnect = disconnect + this.observe = observe + this.takeRecords = takeRecords + this.unobserve = unobserve + } + } + + Object.defineProperty(window, 'IntersectionObserver', { + writable: true, + configurable: true, + value: MockIntersectionObserver + }) + + Object.defineProperty(global, 'IntersectionObserver', { + writable: true, + configurable: true, + value: MockIntersectionObserver + }) +} +setupIntersectionObserverMock() diff --git a/jesthtmlreporter.config.json b/jesthtmlreporter.config.json new file mode 100644 index 000000000..5a3ecd590 --- /dev/null +++ b/jesthtmlreporter.config.json @@ -0,0 +1,4 @@ +{ + "includeFailureMsg": true, + "includeConsoleLog": true +} diff --git a/package-lock.json b/package-lock.json index d037139f5..112f43472 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,11 +6,17 @@ "packages": { "": { "name": "@duckduckgo/autofill", + "hasInstallScript": true, "license": "Apache-2.0", + "dependencies": { + "@duckduckgo/content-scope-scripts": "github:duckduckgo/content-scope-scripts" + }, "devDependencies": { - "@babel/core": "^7.13.16", - "@babel/eslint-parser": "^7.13.14", - "@babel/preset-env": "^7.13.15", + "@babel/core": "^7.17.5", + "@babel/eslint-parser": "^7.17.0", + "@babel/preset-env": "^7.16.11", + "@types/jest": "^27.4.0", + "@types/node": "^16.11.7", "asana": "^0.18.6", "babelify": "^10.0.0", "eslint": "^7.25.0", @@ -19,142 +25,211 @@ "eslint-plugin-node": "^11.1.0", "eslint-plugin-promise": "^4.3.1", "eslint-plugin-standard": "^5.0.0", + "fast-check": "^2.21.0", "grunt": "^1.4.0", "grunt-babel": "^8.0.0", "grunt-browserify": "^6.0.0", "grunt-contrib-watch": "^1.1.0", "grunt-eslint": "^23.0.0", "grunt-exec": "^3.0.0", - "jest": "^26.6.3", + "jasmine": "^4.0.2", + "jest": "^27.4.7", "jest-chrome": "^0.7.1", + "jest-html-reporter": "^3.4.2", "load-grunt-tasks": "^5.1.0", - "markdown-it": "^12.2.0" + "markdown-it": "^12.2.0", + "puppeteer": "^13.0.1", + "typescript": "^4.5.5" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.2.tgz", + "integrity": "sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.0" + }, + "engines": { + "node": ">=6.0.0" } }, "node_modules/@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", "dev": true, "dependencies": { - "@babel/highlight": "^7.12.13" + "@babel/highlight": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.13.15.tgz", - "integrity": "sha512-ltnibHKR1VnrU4ymHyQ/CXtNXI6yZC0oJThyW78Hft8XndANwi+9H+UIklBDraIjFEJzw8wmcM427oDd9KS5wA==", - "dev": true + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.0.tgz", + "integrity": "sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, "node_modules/@babel/core": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.16.tgz", - "integrity": "sha512-sXHpixBiWWFti0AV2Zq7avpTasr6sIAu7Y396c608541qAU2ui4a193m0KSQmfPSKFZLnQ3cvlKDOm3XkuXm3Q==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.16", - "@babel/helper-compilation-targets": "^7.13.16", - "@babel/helper-module-transforms": "^7.13.14", - "@babel/helpers": "^7.13.16", - "@babel/parser": "^7.13.16", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.15", - "@babel/types": "^7.13.16", + "version": "7.17.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.5.tgz", + "integrity": "sha512-/BBMw4EvjmyquN5O+t5eh0+YqB3XXJkYD2cjKpYtWOfFy4lQ4UozNSmxAcWT8r2XtZs0ewG+zrfsqeR15i1ajA==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.3", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helpers": "^7.17.2", + "@babel/parser": "^7.17.3", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.3", + "@babel/types": "^7.17.0", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.1.2", - "semver": "^6.3.0", - "source-map": "^0.5.0" + "semver": "^6.3.0" }, "engines": { "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" } }, "node_modules/@babel/eslint-parser": { - "version": "7.13.14", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.13.14.tgz", - "integrity": "sha512-I0HweR36D73Ibn/FfrRDMKlMqJHFwidIUgYdMpH+aXYuQC+waq59YaJ6t9e9N36axJ82v1jR041wwqDrDXEwRA==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.17.0.tgz", + "integrity": "sha512-PUEJ7ZBXbRkbq3qqM/jZ2nIuakUBqCYc7Qf52Lj7dlZ6zERnqisdHioL0l4wwQZnmskMeasqUNzLBFKs3nylXA==", "dev": true, "dependencies": { - "eslint-scope": "^5.1.0", - "eslint-visitor-keys": "^1.3.0", + "eslint-scope": "^5.1.1", + "eslint-visitor-keys": "^2.1.0", "semver": "^6.3.0" }, "engines": { "node": "^10.13.0 || ^12.13.0 || >=14.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.11.0", + "eslint": "^7.5.0 || ^8.0.0" + } + }, + "node_modules/@babel/eslint-parser/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" } }, "node_modules/@babel/generator": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.16.tgz", - "integrity": "sha512-grBBR75UnKOcUWMp8WoDxNsWCFl//XCK6HWTrBQKTr5SV9f5g0pNOjdyzi/DTBv12S9GnYPInIXQBTky7OXEMg==", + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.3.tgz", + "integrity": "sha512-+R6Dctil/MgUsZsZAkYgK+ADNSZzJRRy0TvY65T71z/CR854xHQ1EweBYXdfT+HNeN7w0cSJJEzgxZMv40pxsg==", "dev": true, "dependencies": { - "@babel/types": "^7.13.16", + "@babel/types": "^7.17.0", "jsesc": "^2.5.1", "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz", - "integrity": "sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz", + "integrity": "sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==", "dev": true, "dependencies": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.12.13.tgz", - "integrity": "sha512-CZOv9tGphhDRlVjVkAgm8Nhklm9RzSmWpX2my+t7Ua/KT616pEzXsQCjinzvkRvHWJ9itO4f296efroX23XCMA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.7.tgz", + "integrity": "sha512-C6FdbRaxYjwVu/geKW4ZeQ0Q31AftgRcdSnZ5/jsH6BzCJbtvXvhpfkbkThYSuutZA7nCXpPR6AD9zd1dprMkA==", "dev": true, "dependencies": { - "@babel/helper-explode-assignable-expression": "^7.12.13", - "@babel/types": "^7.12.13" + "@babel/helper-explode-assignable-expression": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz", - "integrity": "sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", + "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.13.15", - "@babel/helper-validator-option": "^7.12.17", - "browserslist": "^4.14.5", + "@babel/compat-data": "^7.16.4", + "@babel/helper-validator-option": "^7.16.7", + "browserslist": "^4.17.5", "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.13.11", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.13.11.tgz", - "integrity": "sha512-ays0I7XYq9xbjCSvT+EvysLgfc3tOkwCULHjrnscGT3A9qD4sk3wXnJ3of0MAWsWGjdinFvajHU2smYuqXKMrw==", + "version": "7.17.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.6.tgz", + "integrity": "sha512-SogLLSxXm2OkBbSsHZMM4tUi8fUzjs63AT/d0YQIzr6GSd8Hxsbk2KYDX0k0DweAzGMj/YWeiCsorIdtdcW8Eg==", "dev": true, "dependencies": { - "@babel/helper-function-name": "^7.12.13", - "@babel/helper-member-expression-to-functions": "^7.13.0", - "@babel/helper-optimise-call-expression": "^7.12.13", - "@babel/helper-replace-supers": "^7.13.0", - "@babel/helper-split-export-declaration": "^7.12.13" + "@babel/helper-annotate-as-pure": "^7.16.7", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-member-expression-to-functions": "^7.16.7", + "@babel/helper-optimise-call-expression": "^7.16.7", + "@babel/helper-replace-supers": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.12.17", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.17.tgz", - "integrity": "sha512-p2VGmBu9oefLZ2nQpgnEnG0ZlRPvL8gAGvPUMQwUdaE8k49rOMuZpOwdQoy5qJf6K8jL3bcAMhVUlHAjIgJHUg==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.17.0.tgz", + "integrity": "sha512-awO2So99wG6KnlE+TPs6rn83gCz5WlEePJDTnLEqbchMVrBeAujURVphRdigsk094VhvZehFoNOihSlcBjwsXA==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.12.13", - "regexpu-core": "^4.7.1" + "@babel/helper-annotate-as-pure": "^7.16.7", + "regexpu-core": "^5.0.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.0.tgz", - "integrity": "sha512-JT8tHuFjKBo8NnaUbblz7mIu1nnvUDiHVjXXkulZULyidvo/7P6TY7+YqpV37IfF+KUFxmlK04elKtGKXaiVgw==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz", + "integrity": "sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA==", "dev": true, "dependencies": { "@babel/helper-compilation-targets": "^7.13.0", @@ -165,196 +240,268 @@ "lodash.debounce": "^4.0.8", "resolve": "^1.14.2", "semver": "^6.1.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0-0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", + "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-explode-assignable-expression": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.13.0.tgz", - "integrity": "sha512-qS0peLTDP8kOisG1blKbaoBg/o9OSa1qoumMjTK5pM+KDTtpxpsiubnCGP34vK8BXGcb2M9eigwgvoJryrzwWA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.7.tgz", + "integrity": "sha512-KyUenhWMC8VrxzkGP0Jizjo4/Zx+1nNZhgocs+gLzyZyB8SHidhoq9KK/8Ato4anhwsivfkBLftky7gvzbZMtQ==", "dev": true, "dependencies": { - "@babel/types": "^7.13.0" + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", - "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", + "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", "dev": true, "dependencies": { - "@babel/helper-get-function-arity": "^7.12.13", - "@babel/template": "^7.12.13", - "@babel/types": "^7.12.13" + "@babel/helper-get-function-arity": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-get-function-arity": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", - "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", + "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", "dev": true, "dependencies": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.13.16.tgz", - "integrity": "sha512-1eMtTrXtrwscjcAeO4BVK+vvkxaLJSPFz1w1KLawz6HLNi9bPFGBNwwDyVfiu1Tv/vRRFYfoGaKhmAQPGPn5Wg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", + "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", "dev": true, "dependencies": { - "@babel/traverse": "^7.13.15", - "@babel/types": "^7.13.16" + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz", - "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.7.tgz", + "integrity": "sha512-VtJ/65tYiU/6AbMTDwyoXGPKHgTsfRarivm+YbB5uAzKUyuPjgZSgAFeG87FCigc7KNHu2Pegh1XIT3lXjvz3Q==", "dev": true, "dependencies": { - "@babel/types": "^7.13.12" + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz", - "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", + "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", "dev": true, "dependencies": { - "@babel/types": "^7.13.12" + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.13.14", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.13.14.tgz", - "integrity": "sha512-QuU/OJ0iAOSIatyVZmfqB0lbkVP0kDRiKj34xy+QNsnVZi/PA6BoSoreeqnxxa9EHFAIL0R9XOaAR/G9WlIy5g==", + "version": "7.17.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.17.6.tgz", + "integrity": "sha512-2ULmRdqoOMpdvkbT8jONrZML/XALfzxlb052bldftkicAUy8AxSCkD5trDPQcwHNmolcl7wP6ehNqMlyUw6AaA==", "dev": true, "dependencies": { - "@babel/helper-module-imports": "^7.13.12", - "@babel/helper-replace-supers": "^7.13.12", - "@babel/helper-simple-access": "^7.13.12", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/helper-validator-identifier": "^7.12.11", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.13", - "@babel/types": "^7.13.14" + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-simple-access": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.3", + "@babel/types": "^7.17.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", - "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz", + "integrity": "sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w==", "dev": true, "dependencies": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", - "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==", - "dev": true + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", + "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.13.0.tgz", - "integrity": "sha512-pUQpFBE9JvC9lrQbpX0TmeNIy5s7GnZjna2lhhcHC7DzgBs6fWn722Y5cfwgrtrqc7NAJwMvOa0mKhq6XaE4jg==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.8.tgz", + "integrity": "sha512-fm0gH7Flb8H51LqJHy3HJ3wnE1+qtYR2A99K06ahwrawLdOFsCEWjZOrYricXJHoPSudNKxrMBUPEIPxiIIvBw==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.12.13", - "@babel/helper-wrap-function": "^7.13.0", - "@babel/types": "^7.13.0" + "@babel/helper-annotate-as-pure": "^7.16.7", + "@babel/helper-wrap-function": "^7.16.8", + "@babel/types": "^7.16.8" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz", - "integrity": "sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz", + "integrity": "sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw==", "dev": true, "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.13.12", - "@babel/helper-optimise-call-expression": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.12" + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-member-expression-to-functions": "^7.16.7", + "@babel/helper-optimise-call-expression": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz", - "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", + "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==", "dev": true, "dependencies": { - "@babel/types": "^7.13.12" + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz", - "integrity": "sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz", + "integrity": "sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw==", "dev": true, "dependencies": { - "@babel/types": "^7.12.1" + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", - "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", + "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", "dev": true, "dependencies": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", - "dev": true + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, "node_modules/@babel/helper-validator-option": { - "version": "7.12.17", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", - "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==", - "dev": true + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", + "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.13.0.tgz", - "integrity": "sha512-1UX9F7K3BS42fI6qd2A4BjKzgGjToscyZTdp1DjknHLCIvpgne6918io+aL5LXFcER/8QWiwpoY902pVEqgTXA==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.16.8.tgz", + "integrity": "sha512-8RpyRVIAW1RcDDGTA+GpPAwV22wXCfKOoM9bet6TLkGIFTkRQSkH1nMQ5Yet4MpoXe1ZwHPVtNasc2w0uZMqnw==", "dev": true, "dependencies": { - "@babel/helper-function-name": "^7.12.13", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.0" + "@babel/helper-function-name": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.8", + "@babel/types": "^7.16.8" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.13.17", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.13.17.tgz", - "integrity": "sha512-Eal4Gce4kGijo1/TGJdqp3WuhllaMLSrW6XcL0ulyUAQOuxHcCafZE8KHg9857gcTehsm/v7RcOx2+jp0Ryjsg==", + "version": "7.17.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.2.tgz", + "integrity": "sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ==", "dev": true, "dependencies": { - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.17", - "@babel/types": "^7.13.17" + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.0", + "@babel/types": "^7.17.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.13.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.10.tgz", - "integrity": "sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==", + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.12.11", + "@babel/helper-validator-identifier": "^7.16.7", "chalk": "^2.0.0", "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.16.tgz", - "integrity": "sha512-6bAg36mCwuqLO0hbR+z7PHuqWiCeP7Dzg73OpQwsAB1Eb8HnGEz5xYBzCfbu+YjoaJsJs+qheDxVAuqbt3ILEw==", + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.3.tgz", + "integrity": "sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -363,153 +510,284 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.7.tgz", + "integrity": "sha512-anv/DObl7waiGEnC24O9zqL0pSuI9hljihqiDuFHC8d7/bjr/4RLGPWuc8rYOff/QPzbEPSkzG8wGG9aDuhHRg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.13.12.tgz", - "integrity": "sha512-d0u3zWKcoZf379fOeJdr1a5WPDny4aOFZ6hlfKivgK0LY7ZxNfoaHL2fWwdGtHyVvra38FC+HVYkO+byfSA8AQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.7.tgz", + "integrity": "sha512-di8vUHRdf+4aJ7ltXhaDbPoszdkh59AQtJM5soLsuHpQJdFQZOA4uGj0V2u/CZ8bJ/u8ULDL5yq6FO/bCXnKHw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1", - "@babel/plugin-proposal-optional-chaining": "^7.13.12" + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", + "@babel/plugin-proposal-optional-chaining": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" } }, "node_modules/@babel/plugin-proposal-async-generator-functions": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.13.15.tgz", - "integrity": "sha512-VapibkWzFeoa6ubXy/NgV5U2U4MVnUlvnx6wo1XhlsaTrLYWE0UFpDQsVrmn22q5CzeloqJ8gEMHSKxuee6ZdA==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.8.tgz", + "integrity": "sha512-71YHIvMuiuqWJQkebWJtdhQTfd4Q4mF76q2IX37uZPkG9+olBxsX+rH1vkhFto4UeJZ9dPY2s+mDvhDm1u2BGQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-remap-async-to-generator": "^7.13.0", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-remap-async-to-generator": "^7.16.8", "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-class-properties": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.13.0.tgz", - "integrity": "sha512-KnTDjFNC1g+45ka0myZNvSBFLhNCLN+GeGYLDEA8Oq7MZ6yMgfLoIRh86GRT0FjtJhZw8JyUskP9uvj5pHM9Zg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz", + "integrity": "sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-class-static-block": { + "version": "7.17.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.17.6.tgz", + "integrity": "sha512-X/tididvL2zbs7jZCeeRJ8167U/+Ac135AM6jCAx6gYXDUviZV5Ku9UDvWS2NCuWlFjIRXklYhwo6HhAC7ETnA==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.13.0", - "@babel/helper-plugin-utils": "^7.13.0" + "@babel/helper-create-class-features-plugin": "^7.17.6", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" } }, "node_modules/@babel/plugin-proposal-dynamic-import": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.13.8.tgz", - "integrity": "sha512-ONWKj0H6+wIRCkZi9zSbZtE/r73uOhMVHh256ys0UzfM7I3d4n+spZNWjOnJv2gzopumP2Wxi186vI8N0Y2JyQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.7.tgz", + "integrity": "sha512-I8SW9Ho3/8DRSdmDdH3gORdyUuYnk1m4cMxUAdu5oy4n3OfN8flDEH+d60iG7dUfi0KkYwSvoalHzzdRzpWHTg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-export-namespace-from": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.13.tgz", - "integrity": "sha512-INAgtFo4OnLN3Y/j0VwAgw3HDXcDtX+C/erMvWzuV9v71r7urb6iyMXu7eM9IgLr1ElLlOkaHjJ0SbCmdOQ3Iw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.7.tgz", + "integrity": "sha512-ZxdtqDXLRGBL64ocZcs7ovt71L3jhC1RGSyR996svrCi3PYqHNkb3SwPJCs8RIzD86s+WPpt2S73+EHCGO+NUA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-json-strings": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.13.8.tgz", - "integrity": "sha512-w4zOPKUFPX1mgvTmL/fcEqy34hrQ1CRcGxdphBc6snDnnqJ47EZDIyop6IwXzAC8G916hsIuXB2ZMBCExC5k7Q==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.7.tgz", + "integrity": "sha512-lNZ3EEggsGY78JavgbHsK9u5P3pQaW7k4axlgFLYkMd7UBsiNahCITShLjNQschPyjtO6dADrL24757IdhBrsQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.13.8.tgz", - "integrity": "sha512-aul6znYB4N4HGweImqKn59Su9RS8lbUIqxtXTOcAGtNIDczoEFv+l1EhmX8rUBp3G1jMjKJm8m0jXVp63ZpS4A==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.7.tgz", + "integrity": "sha512-K3XzyZJGQCr00+EtYtrDjmwX7o7PLK6U9bi1nCwkQioRFVUv6dJoxbQjtWVtP+bCPy82bONBKG8NPyQ4+i6yjg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.13.8.tgz", - "integrity": "sha512-iePlDPBn//UhxExyS9KyeYU7RM9WScAG+D3Hhno0PLJebAEpDZMocbDe64eqynhNAnwz/vZoL/q/QB2T1OH39A==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.7.tgz", + "integrity": "sha512-aUOrYU3EVtjf62jQrCj63pYZ7k6vns2h/DQvHPWGmsJRYzWXZ6/AsfgpiRy6XiuIDADhJzP2Q9MwSMKauBQ+UQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-numeric-separator": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.13.tgz", - "integrity": "sha512-O1jFia9R8BUCl3ZGB7eitaAPu62TXJRHn7rh+ojNERCFyqRwJMTmhz+tJ+k0CwI6CLjX/ee4qW74FSqlq9I35w==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.7.tgz", + "integrity": "sha512-vQgPMknOIgiuVqbokToyXbkY/OmmjAzr/0lhSIbG/KmnzXPGwW/AdhdKpi+O4X/VkWiWjnkKOBiqJrTaC98VKw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.13.8.tgz", - "integrity": "sha512-DhB2EuB1Ih7S3/IRX5AFVgZ16k3EzfRbq97CxAVI1KSYcW+lexV8VZb7G7L8zuPVSdQMRn0kiBpf/Yzu9ZKH0g==", + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.17.3.tgz", + "integrity": "sha512-yuL5iQA/TbZn+RGAfxQXfi7CNLmKi1f8zInn4IgobuCWcAb7i+zj4TYzQ9l8cEzVyJ89PDGuqxK1xZpUDISesw==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.13.8", - "@babel/helper-compilation-targets": "^7.13.8", - "@babel/helper-plugin-utils": "^7.13.0", + "@babel/compat-data": "^7.17.0", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.13.0" + "@babel/plugin-transform-parameters": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-optional-catch-binding": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.13.8.tgz", - "integrity": "sha512-0wS/4DUF1CuTmGo+NiaHfHcVSeSLj5S3e6RivPTg/2k3wOv3jO35tZ6/ZWsQhQMvdgI7CwphjQa/ccarLymHVA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.7.tgz", + "integrity": "sha512-eMOH/L4OvWSZAE1VkHbr1vckLG1WUcHGJSLqqQwl2GaUqG6QjddvrOaTUMNYiv77H5IKPMZ9U9P7EaHwvAShfA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.13.12.tgz", - "integrity": "sha512-fcEdKOkIB7Tf4IxrgEVeFC4zeJSTr78no9wTdBuZZbqF64kzllU0ybo2zrzm7gUQfxGhBgq4E39oRs8Zx/RMYQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz", + "integrity": "sha512-eC3xy+ZrUcBtP7x+sq62Q/HYd674pPTb/77XZMb5wbDPGWIdUbSr4Agr052+zaUPSb+gGRnjxXfKFvx5iMJ+DA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-private-methods": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.13.0.tgz", - "integrity": "sha512-MXyyKQd9inhx1kDYPkFRVOBXQ20ES8Pto3T7UZ92xj2mY0EVD8oAVzeyYuVfy/mxAdTSIayOvg+aVzcHV2bn6Q==", + "version": "7.16.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.11.tgz", + "integrity": "sha512-F/2uAkPlXDr8+BHpZvo19w3hLFKge+k75XUprE6jaqKxjGkSYcK+4c+bup5PdW/7W/Rpjwql7FTVEDW+fRAQsw==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.16.10", + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.7.tgz", + "integrity": "sha512-rMQkjcOFbm+ufe3bTZLyOfsOUOxyvLXZJCTARhJr+8UMSoZmqTe1K1BgkFcrW37rAchWg57yI69ORxiWvUINuQ==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.13.0", - "@babel/helper-plugin-utils": "^7.13.0" + "@babel/helper-annotate-as-pure": "^7.16.7", + "@babel/helper-create-class-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-unicode-property-regex": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.13.tgz", - "integrity": "sha512-XyJmZidNfofEkqFV5VC/bLabGmO5QzenPO/YOfGuEbgU+2sSwMmio3YLb4WtBgcmmdwZHyVyv8on77IUjQ5Gvg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.7.tgz", + "integrity": "sha512-QRK0YI/40VLhNVGIjRNAAQkEHws0cswSdFFjpFyt943YmJIU1da9uW63Iu6NFV6CxTZW5eTDCrwZUstBWgp/Rg==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.12.13", - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-create-regexp-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-async-generators": { @@ -528,6 +806,9 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-class-properties": { @@ -539,6 +820,21 @@ "@babel/helper-plugin-utils": "^7.12.13" } }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-dynamic-import": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", @@ -546,6 +842,9 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-export-namespace-from": { @@ -555,6 +854,9 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-import-meta": { @@ -564,6 +866,9 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-json-strings": { @@ -629,353 +934,604 @@ "@babel/helper-plugin-utils": "^7.8.0" } }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz", - "integrity": "sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ==", + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.13.0.tgz", - "integrity": "sha512-96lgJagobeVmazXFaDrbmCLQxBysKu7U6Do3mLsx27gf5Dk85ezysrs2BZUpXD703U/Su1xTBDxxar2oa4jAGg==", + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0" + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.13.0.tgz", - "integrity": "sha512-3j6E004Dx0K3eGmhxVJxwwI89CTJrce7lg3UrtFuDAVQ/2+SJ/h/aSFOeE6/n0WB1GsOffsJp6MnPQNQ8nmwhg==", + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz", + "integrity": "sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A==", "dev": true, "dependencies": { - "@babel/helper-module-imports": "^7.12.13", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-remap-async-to-generator": "^7.13.0" - } + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.7.tgz", + "integrity": "sha512-9ffkFFMbvzTvv+7dTp/66xvZAWASuPD5Tl9LK3Z9vhOmANo6j94rik+5YMBt4CwHVMWLWpMsriIc2zsa3WW3xQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.8.tgz", + "integrity": "sha512-MtmUmTJQHCnyJVrScNzNlofQJ3dLFuobYn3mwOTKHnSCMtbNsqvF71GQmJfFjdrXSsAA7iysFmYWw4bXZ20hOg==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-remap-async-to-generator": "^7.16.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.13.tgz", - "integrity": "sha512-zNyFqbc3kI/fVpqwfqkg6RvBgFpC4J18aKKMmv7KdQ/1GgREapSJAykLMVNwfRGO3BtHj3YQZl8kxCXPcVMVeg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.7.tgz", + "integrity": "sha512-JUuzlzmF40Z9cXyytcbZEZKckgrQzChbQJw/5PuEHYeqzCsvebDx0K0jWnIIVcmmDOAVctCgnYs0pMcrYj2zJg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.13.16.tgz", - "integrity": "sha512-ad3PHUxGnfWF4Efd3qFuznEtZKoBp0spS+DgqzVzRPV7urEBvPLue3y2j80w4Jf2YLzZHj8TOv/Lmvdmh3b2xg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.7.tgz", + "integrity": "sha512-ObZev2nxVAYA4bhyusELdo9hb3H+A56bxH3FZMbEImZFiEDYVHXQSJ1hQKFlDnlt8G9bBrCZ5ZpURZUrV4G5qQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0" + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.13.0.tgz", - "integrity": "sha512-9BtHCPUARyVH1oXGcSJD3YpsqRLROJx5ZNP6tN5vnk17N0SVf9WCtf8Nuh1CFmgByKKAIMstitKduoCmsaDK5g==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.12.13", - "@babel/helper-function-name": "^7.12.13", - "@babel/helper-optimise-call-expression": "^7.12.13", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-replace-supers": "^7.13.0", - "@babel/helper-split-export-declaration": "^7.12.13", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.7.tgz", + "integrity": "sha512-WY7og38SFAGYRe64BrjKf8OrE6ulEHtr5jEYaZMwox9KebgqPi67Zqz8K53EKk1fFEJgm96r32rkKZ3qA2nCWQ==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.16.7", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-optimise-call-expression": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-replace-supers": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.13.0.tgz", - "integrity": "sha512-RRqTYTeZkZAz8WbieLTvKUEUxZlUTdmL5KGMyZj7FnMfLNKV4+r5549aORG/mgojRmFlQMJDUupwAMiF2Q7OUg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.7.tgz", + "integrity": "sha512-gN72G9bcmenVILj//sv1zLNaPyYcOzUho2lIJBMh/iakJ9ygCo/hEF9cpGb61SCMEDxbbyBoVQxrt+bWKu5KGw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0" + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.13.17", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.13.17.tgz", - "integrity": "sha512-UAUqiLv+uRLO+xuBKKMEpC+t7YRNVRqBsWWq1yKXbBZBje/t3IXCiSinZhjn/DC3qzBfICeYd2EFGEbHsh5RLA==", + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.17.3.tgz", + "integrity": "sha512-dDFzegDYKlPqa72xIlbmSkly5MluLoaC1JswABGktyt6NTXSBcUuse/kWE/wvKFWJHPETpi158qJZFS3JmykJg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0" + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.13.tgz", - "integrity": "sha512-foDrozE65ZFdUC2OfgeOCrEPTxdB3yjqxpXh8CH+ipd9CHd4s/iq81kcUpyH8ACGNEPdFqbtzfgzbT/ZGlbDeQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.7.tgz", + "integrity": "sha512-Lyttaao2SjZF6Pf4vk1dVKv8YypMpomAbygW+mU5cYP3S5cWTfCJjG8xV6CFdzGFlfWK81IjL9viiTvpb6G7gQ==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.12.13", - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-create-regexp-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.13.tgz", - "integrity": "sha512-NfADJiiHdhLBW3pulJlJI2NB0t4cci4WTZ8FtdIuNc2+8pslXdPtRRAEWqUY+m9kNOk2eRYbTAOipAxlrOcwwQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.7.tgz", + "integrity": "sha512-03DvpbRfvWIXyK0/6QiR1KMTWeT6OcQ7tbhjrXyFS02kjuX/mu5Bvnh5SDSWHxyawit2g5aWhKwI86EE7GUnTw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.13.tgz", - "integrity": "sha512-fbUelkM1apvqez/yYx1/oICVnGo2KM5s63mhGylrmXUxK/IAXSIf87QIxVfZldWf4QsOafY6vV3bX8aMHSvNrA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.7.tgz", + "integrity": "sha512-8UYLSlyLgRixQvlYH3J2ekXFHDFLQutdy7FfFAMm3CPZ6q9wHCwnUyiXpQCe3gVVnQlHc5nsuiEVziteRNTXEA==", "dev": true, "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.12.13", - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.13.0.tgz", - "integrity": "sha512-IHKT00mwUVYE0zzbkDgNRP6SRzvfGCYsOxIRz8KsiaaHCcT9BWIkO+H9QRJseHBLOGBZkHUdHiqj6r0POsdytg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.7.tgz", + "integrity": "sha512-/QZm9W92Ptpw7sjI9Nx1mbcsWz33+l8kuMIQnDwgQBG5s3fAfQvkRjQ7NqXhtNcKOnPkdICmUHyCaWW06HCsqg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0" + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.13.tgz", - "integrity": "sha512-6K7gZycG0cmIwwF7uMK/ZqeCikCGVBdyP2J5SKNCXO5EOHcqi+z7Jwf8AmyDNcBgxET8DrEtCt/mPKPyAzXyqQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.7.tgz", + "integrity": "sha512-SU/C68YVwTRxqWj5kgsbKINakGag0KTgq9f2iZEXdStoAbOzLHEBRYzImmA6yFo8YZhJVflvXmIHUO7GWHmxxA==", "dev": true, "dependencies": { - "@babel/helper-function-name": "^7.12.13", - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.13.tgz", - "integrity": "sha512-FW+WPjSR7hiUxMcKqyNjP05tQ2kmBCdpEpZHY1ARm96tGQCCBvXKnpjILtDplUnJ/eHZ0lALLM+d2lMFSpYJrQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.7.tgz", + "integrity": "sha512-6tH8RTpTWI0s2sV6uq3e/C9wPo4PTqqZps4uF0kzQ9/xPLFQtipynvmT1g/dOfEJ+0EQsHhkQ/zyRId8J2b8zQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.13.tgz", - "integrity": "sha512-kxLkOsg8yir4YeEPHLuO2tXP9R/gTjpuTOjshqSpELUN3ZAg2jfDnKUvzzJxObun38sw3wm4Uu69sX/zA7iRvg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.7.tgz", + "integrity": "sha512-mBruRMbktKQwbxaJof32LT9KLy2f3gH+27a5XSuXo6h7R3vqltl0PgZ80C8ZMKw98Bf8bqt6BEVi3svOh2PzMw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.13.0.tgz", - "integrity": "sha512-EKy/E2NHhY/6Vw5d1k3rgoobftcNUmp9fGjb9XZwQLtTctsRBOTRO7RHHxfIky1ogMN5BxN7p9uMA3SzPfotMQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.7.tgz", + "integrity": "sha512-KaaEtgBL7FKYwjJ/teH63oAmE3lP34N3kshz8mm4VMAw7U3PxjVwwUmxEFksbgsNUaO3wId9R2AVQYSEGRa2+g==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.13.0", - "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.13.8.tgz", - "integrity": "sha512-9QiOx4MEGglfYZ4XOnU79OHr6vIWUakIj9b4mioN8eQIoEh+pf5p/zEB36JpDFWA12nNMiRf7bfoRvl9Rn79Bw==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.8.tgz", + "integrity": "sha512-oflKPvsLT2+uKQopesJt3ApiaIS2HW+hzHFcwRNtyDGieAeC/dIHZX8buJQ2J2X1rxGPy4eRcUijm3qcSPjYcA==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.13.0", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-simple-access": "^7.12.13", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-simple-access": "^7.16.7", "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.13.8.tgz", - "integrity": "sha512-hwqctPYjhM6cWvVIlOIe27jCIBgHCsdH2xCJVAYQm7V5yTMoilbVMi9f6wKg0rpQAOn6ZG4AOyvCqFF/hUh6+A==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.7.tgz", + "integrity": "sha512-DuK5E3k+QQmnOqBR9UkusByy5WZWGRxfzV529s9nPra1GE7olmxfqO2FHobEOYSPIjPBTr4p66YDcjQnt8cBmw==", "dev": true, "dependencies": { - "@babel/helper-hoist-variables": "^7.13.0", - "@babel/helper-module-transforms": "^7.13.0", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-validator-identifier": "^7.12.11", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.13.0.tgz", - "integrity": "sha512-D/ILzAh6uyvkWjKKyFE/W0FzWwasv6vPTSqPcjxFqn6QpX3u8DjRVliq4F2BamO2Wee/om06Vyy+vPkNrd4wxw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.7.tgz", + "integrity": "sha512-EMh7uolsC8O4xhudF2F6wedbSHm1HHZ0C6aJ7K67zcDNidMzVcxWdGr+htW9n21klm+bOn+Rx4CBsAntZd3rEQ==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.13.0", - "@babel/helper-plugin-utils": "^7.13.0" + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.13.tgz", - "integrity": "sha512-Xsm8P2hr5hAxyYblrfACXpQKdQbx4m2df9/ZZSQ8MAhsadw06+jW7s9zsSw6he+mJZXRlVMyEnVktJo4zjk1WA==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.8.tgz", + "integrity": "sha512-j3Jw+n5PvpmhRR+mrgIh04puSANCk/T/UA3m3P1MjJkhlK906+ApHhDIqBQDdOgL/r1UYpz4GNclTXxyZrYGSw==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.12.13" + "@babel/helper-create-regexp-features-plugin": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/plugin-transform-new-target": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.13.tgz", - "integrity": "sha512-/KY2hbLxrG5GTQ9zzZSc3xWiOy379pIETEhbtzwZcw9rvuaVV4Fqy7BYGYOWZnaoXIQYbbJ0ziXLa/sKcGCYEQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.7.tgz", + "integrity": "sha512-xiLDzWNMfKoGOpc6t3U+etCE2yRnn3SM09BXqWPIZOBpL2gvVrBWUKnsJx0K/ADi5F5YC5f8APFfWrz25TdlGg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-object-super": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.13.tgz", - "integrity": "sha512-JzYIcj3XtYspZDV8j9ulnoMPZZnF/Cj0LUxPOjR89BdBVx+zYJI9MdMIlUZjbXDX+6YVeS6I3e8op+qQ3BYBoQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.7.tgz", + "integrity": "sha512-14J1feiQVWaGvRxj2WjyMuXS2jsBkgB3MdSN5HuC2G5nRspa5RK9COcs82Pwy5BuGcjb+fYaUj94mYcOj7rCvw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13", - "@babel/helper-replace-supers": "^7.12.13" + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-replace-supers": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.13.0.tgz", - "integrity": "sha512-Jt8k/h/mIwE2JFEOb3lURoY5C85ETcYPnbuAJ96zRBzh1XHtQZfs62ChZ6EP22QlC8c7Xqr9q+e1SU5qttwwjw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.7.tgz", + "integrity": "sha512-AT3MufQ7zZEhU2hwOA11axBnExW0Lszu4RL/tAlUJBuNoRak+wehQW8h6KcXOcgjY42fHtDxswuMhMjFEuv/aw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0" + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.13.tgz", - "integrity": "sha512-nqVigwVan+lR+g8Fj8Exl0UQX2kymtjcWfMOYM1vTYEKujeyv2SkMgazf2qNcK7l4SDiKyTA/nHCPqL4e2zo1A==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.7.tgz", + "integrity": "sha512-z4FGr9NMGdoIl1RqavCqGG+ZuYjfZ/hkCIeuH6Do7tXmSm0ls11nYVSJqFEUOSJbDab5wC6lRE/w6YjVcr6Hqw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.13.15.tgz", - "integrity": "sha512-Bk9cOLSz8DiurcMETZ8E2YtIVJbFCPGW28DJWUakmyVWtQSm6Wsf0p4B4BfEr/eL2Nkhe/CICiUiMOCi1TPhuQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.7.tgz", + "integrity": "sha512-mF7jOgGYCkSJagJ6XCujSQg+6xC1M77/03K2oBmVJWoFGNUtnVJO4WHKJk3dnPC8HCcj4xBQP1Egm8DWh3Pb3Q==", "dev": true, "dependencies": { "regenerator-transform": "^0.14.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.13.tgz", - "integrity": "sha512-xhUPzDXxZN1QfiOy/I5tyye+TRz6lA7z6xaT4CLOjPRMVg1ldRf0LHw0TDBpYL4vG78556WuHdyO9oi5UmzZBg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.7.tgz", + "integrity": "sha512-KQzzDnZ9hWQBjwi5lpY5v9shmm6IVG0U9pB18zvMu2i4H90xpT4gmqwPYsn8rObiadYe2M0gmgsiOIF5A/2rtg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.13.tgz", - "integrity": "sha512-xpL49pqPnLtf0tVluuqvzWIgLEhuPpZzvs2yabUHSKRNlN7ScYU7aMlmavOeyXJZKgZKQRBlh8rHbKiJDraTSw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.7.tgz", + "integrity": "sha512-hah2+FEnoRoATdIb05IOXf+4GzXYTq75TVhIn1PewihbpyrNWUt2JbudKQOETWw6QpLe+AIUpJ5MVLYTQbeeUg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.13.0.tgz", - "integrity": "sha512-V6vkiXijjzYeFmQTr3dBxPtZYLPcUfY34DebOU27jIl2M/Y8Egm52Hw82CSjjPqd54GTlJs5x+CR7HeNr24ckg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.7.tgz", + "integrity": "sha512-+pjJpgAngb53L0iaA5gU/1MLXJIfXcYepLgXB3esVRf4fqmj8f2cxM3/FKaHsZms08hFQJkFccEWuIpm429TXg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1" + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.13.tgz", - "integrity": "sha512-Jc3JSaaWT8+fr7GRvQP02fKDsYk4K/lYwWq38r/UGfaxo89ajud321NH28KRQ7xy1Ybc0VUE5Pz8psjNNDUglg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.7.tgz", + "integrity": "sha512-NJa0Bd/87QV5NZZzTuZG5BPJjLYadeSZ9fO6oOUoL4iQx+9EEuw/eEM92SrsT19Yc2jgB1u1hsjqDtH02c3Drw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.13.0.tgz", - "integrity": "sha512-d67umW6nlfmr1iehCcBv69eSUSySk1EsIS8aTDX4Xo9qajAh6mYtcl4kJrBkGXuxZPEgVr7RVfAvNW6YQkd4Mw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.7.tgz", + "integrity": "sha512-VwbkDDUeenlIjmfNeDX/V0aWrQH2QiVyJtwymVQSzItFDTpxfyJh3EVaQiS0rIN/CqbLGr0VcGmuwyTdZtdIsA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0" + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.13.tgz", - "integrity": "sha512-eKv/LmUJpMnu4npgfvs3LiHhJua5fo/CysENxa45YCQXZwKnGCQKAg87bvoqSW1fFT+HA32l03Qxsm8ouTY3ZQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.7.tgz", + "integrity": "sha512-p2rOixCKRJzpg9JB4gjnG4gjWkWa89ZoYUnl9snJ1cWIcTH/hvxZqfO+WjG6T8DRBpctEol5jw1O5rA8gkCokQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.8.tgz", + "integrity": "sha512-bHdQ9k7YpBDO2d0NVfkj51DpQcvwIzIusJ7mEUaMlbZq3Kt/U47j24inXZHQ5MDiYpCs+oZiwnXyKedE8+q7AQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-typescript": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.13.tgz", - "integrity": "sha512-0bHEkdwJ/sN/ikBHfSmOXPypN/beiGqjo+o4/5K+vxEFNPRPdImhviPakMKG4x96l85emoa0Z6cDflsdBusZbw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.7.tgz", + "integrity": "sha512-TAV5IGahIz3yZ9/Hfv35TV2xEm+kaBDaZQCn2S/hG9/CZ0DktxJv9eKfPc7yYCvOYR4JGx1h8C+jcSOvgaaI/Q==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.13.tgz", - "integrity": "sha512-mDRzSNY7/zopwisPZ5kM9XKCfhchqIYwAKRERtEnhYscZB79VRekuRSoYbN0+KVe3y8+q1h6A4svXtP7N+UoCA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.7.tgz", + "integrity": "sha512-oC5tYYKw56HO75KZVLQ+R/Nl3Hro9kf8iG0hXoaHP7tjAyCpvqBiSNe6vGrZni1Z6MggmUOC6A7VP7AVmw225Q==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.12.13", - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-create-regexp-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/preset-env": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.13.15.tgz", - "integrity": "sha512-D4JAPMXcxk69PKe81jRJ21/fP/uYdcTZ3hJDF5QX2HSI9bBxxYw/dumdR6dGumhjxlprHPE4XWoPaqzZUVy2MA==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.13.15", - "@babel/helper-compilation-targets": "^7.13.13", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-validator-option": "^7.12.17", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.13.12", - "@babel/plugin-proposal-async-generator-functions": "^7.13.15", - "@babel/plugin-proposal-class-properties": "^7.13.0", - "@babel/plugin-proposal-dynamic-import": "^7.13.8", - "@babel/plugin-proposal-export-namespace-from": "^7.12.13", - "@babel/plugin-proposal-json-strings": "^7.13.8", - "@babel/plugin-proposal-logical-assignment-operators": "^7.13.8", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.13.8", - "@babel/plugin-proposal-numeric-separator": "^7.12.13", - "@babel/plugin-proposal-object-rest-spread": "^7.13.8", - "@babel/plugin-proposal-optional-catch-binding": "^7.13.8", - "@babel/plugin-proposal-optional-chaining": "^7.13.12", - "@babel/plugin-proposal-private-methods": "^7.13.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.12.13", + "version": "7.16.11", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.16.11.tgz", + "integrity": "sha512-qcmWG8R7ZW6WBRPZK//y+E3Cli151B20W1Rv7ln27vuPaXU/8TKms6jFdiJtF7UDTxcrb7mZd88tAeK9LjdT8g==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.16.8", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-validator-option": "^7.16.7", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.16.7", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.16.7", + "@babel/plugin-proposal-async-generator-functions": "^7.16.8", + "@babel/plugin-proposal-class-properties": "^7.16.7", + "@babel/plugin-proposal-class-static-block": "^7.16.7", + "@babel/plugin-proposal-dynamic-import": "^7.16.7", + "@babel/plugin-proposal-export-namespace-from": "^7.16.7", + "@babel/plugin-proposal-json-strings": "^7.16.7", + "@babel/plugin-proposal-logical-assignment-operators": "^7.16.7", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.7", + "@babel/plugin-proposal-numeric-separator": "^7.16.7", + "@babel/plugin-proposal-object-rest-spread": "^7.16.7", + "@babel/plugin-proposal-optional-catch-binding": "^7.16.7", + "@babel/plugin-proposal-optional-chaining": "^7.16.7", + "@babel/plugin-proposal-private-methods": "^7.16.11", + "@babel/plugin-proposal-private-property-in-object": "^7.16.7", + "@babel/plugin-proposal-unicode-property-regex": "^7.16.7", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", "@babel/plugin-syntax-json-strings": "^7.8.3", @@ -985,52 +1541,59 @@ "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.12.13", - "@babel/plugin-transform-arrow-functions": "^7.13.0", - "@babel/plugin-transform-async-to-generator": "^7.13.0", - "@babel/plugin-transform-block-scoped-functions": "^7.12.13", - "@babel/plugin-transform-block-scoping": "^7.12.13", - "@babel/plugin-transform-classes": "^7.13.0", - "@babel/plugin-transform-computed-properties": "^7.13.0", - "@babel/plugin-transform-destructuring": "^7.13.0", - "@babel/plugin-transform-dotall-regex": "^7.12.13", - "@babel/plugin-transform-duplicate-keys": "^7.12.13", - "@babel/plugin-transform-exponentiation-operator": "^7.12.13", - "@babel/plugin-transform-for-of": "^7.13.0", - "@babel/plugin-transform-function-name": "^7.12.13", - "@babel/plugin-transform-literals": "^7.12.13", - "@babel/plugin-transform-member-expression-literals": "^7.12.13", - "@babel/plugin-transform-modules-amd": "^7.13.0", - "@babel/plugin-transform-modules-commonjs": "^7.13.8", - "@babel/plugin-transform-modules-systemjs": "^7.13.8", - "@babel/plugin-transform-modules-umd": "^7.13.0", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.12.13", - "@babel/plugin-transform-new-target": "^7.12.13", - "@babel/plugin-transform-object-super": "^7.12.13", - "@babel/plugin-transform-parameters": "^7.13.0", - "@babel/plugin-transform-property-literals": "^7.12.13", - "@babel/plugin-transform-regenerator": "^7.13.15", - "@babel/plugin-transform-reserved-words": "^7.12.13", - "@babel/plugin-transform-shorthand-properties": "^7.12.13", - "@babel/plugin-transform-spread": "^7.13.0", - "@babel/plugin-transform-sticky-regex": "^7.12.13", - "@babel/plugin-transform-template-literals": "^7.13.0", - "@babel/plugin-transform-typeof-symbol": "^7.12.13", - "@babel/plugin-transform-unicode-escapes": "^7.12.13", - "@babel/plugin-transform-unicode-regex": "^7.12.13", - "@babel/preset-modules": "^0.1.4", - "@babel/types": "^7.13.14", - "babel-plugin-polyfill-corejs2": "^0.2.0", - "babel-plugin-polyfill-corejs3": "^0.2.0", - "babel-plugin-polyfill-regenerator": "^0.2.0", - "core-js-compat": "^3.9.0", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-transform-arrow-functions": "^7.16.7", + "@babel/plugin-transform-async-to-generator": "^7.16.8", + "@babel/plugin-transform-block-scoped-functions": "^7.16.7", + "@babel/plugin-transform-block-scoping": "^7.16.7", + "@babel/plugin-transform-classes": "^7.16.7", + "@babel/plugin-transform-computed-properties": "^7.16.7", + "@babel/plugin-transform-destructuring": "^7.16.7", + "@babel/plugin-transform-dotall-regex": "^7.16.7", + "@babel/plugin-transform-duplicate-keys": "^7.16.7", + "@babel/plugin-transform-exponentiation-operator": "^7.16.7", + "@babel/plugin-transform-for-of": "^7.16.7", + "@babel/plugin-transform-function-name": "^7.16.7", + "@babel/plugin-transform-literals": "^7.16.7", + "@babel/plugin-transform-member-expression-literals": "^7.16.7", + "@babel/plugin-transform-modules-amd": "^7.16.7", + "@babel/plugin-transform-modules-commonjs": "^7.16.8", + "@babel/plugin-transform-modules-systemjs": "^7.16.7", + "@babel/plugin-transform-modules-umd": "^7.16.7", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.16.8", + "@babel/plugin-transform-new-target": "^7.16.7", + "@babel/plugin-transform-object-super": "^7.16.7", + "@babel/plugin-transform-parameters": "^7.16.7", + "@babel/plugin-transform-property-literals": "^7.16.7", + "@babel/plugin-transform-regenerator": "^7.16.7", + "@babel/plugin-transform-reserved-words": "^7.16.7", + "@babel/plugin-transform-shorthand-properties": "^7.16.7", + "@babel/plugin-transform-spread": "^7.16.7", + "@babel/plugin-transform-sticky-regex": "^7.16.7", + "@babel/plugin-transform-template-literals": "^7.16.7", + "@babel/plugin-transform-typeof-symbol": "^7.16.7", + "@babel/plugin-transform-unicode-escapes": "^7.16.7", + "@babel/plugin-transform-unicode-regex": "^7.16.7", + "@babel/preset-modules": "^0.1.5", + "@babel/types": "^7.16.8", + "babel-plugin-polyfill-corejs2": "^0.3.0", + "babel-plugin-polyfill-corejs3": "^0.5.0", + "babel-plugin-polyfill-regenerator": "^0.3.0", + "core-js-compat": "^3.20.2", "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/preset-modules": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz", - "integrity": "sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==", + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", + "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", @@ -1038,52 +1601,86 @@ "@babel/plugin-transform-dotall-regex": "^7.4.4", "@babel/types": "^7.4.4", "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.16.7.tgz", + "integrity": "sha512-WbVEmgXdIyvzB77AQjGBEyYPZx+8tTsO50XtfozQrkW8QB2rLJpH2lgx0TRw5EJrBxOZQ+wCcyPVQvS8tjEHpQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-validator-option": "^7.16.7", + "@babel/plugin-transform-typescript": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/runtime": { - "version": "7.13.17", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.17.tgz", - "integrity": "sha512-NCdgJEelPTSh+FEFylhnP1ylq848l1z9t9N0j1Lfbcw0+KXGjsTvUmkxy+voLLXB5SOKMbLLx4jxYliGrYQseA==", + "version": "7.17.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.2.tgz", + "integrity": "sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==", "dev": true, "dependencies": { "regenerator-runtime": "^0.13.4" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/template": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", - "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", + "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.12.13", - "@babel/parser": "^7.12.13", - "@babel/types": "^7.12.13" + "@babel/code-frame": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.13.17", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.17.tgz", - "integrity": "sha512-BMnZn0R+X6ayqm3C3To7o1j7Q020gWdqdyP50KEoVqaCO2c/Im7sYZSmVgvefp8TTMQ+9CtwuBp0Z1CZ8V3Pvg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.16", - "@babel/helper-function-name": "^7.12.13", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.13.16", - "@babel/types": "^7.13.17", + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.3.tgz", + "integrity": "sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.3", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/parser": "^7.17.3", + "@babel/types": "^7.17.0", "debug": "^4.1.0", "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/types": { - "version": "7.13.17", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.17.tgz", - "integrity": "sha512-RawydLgxbOPDlTLJNtoIypwdmAy//uQIzlKt2+iBiJaRlVuI6QLUxVAyWGNfOzp8Yu4L4lLIacoCyTNtpb4wiA==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.12.11", + "@babel/helper-validator-identifier": "^7.16.7", "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@bcoe/v8-coverage": { @@ -1092,20 +1689,13 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "node_modules/@cnakazawa/watch": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", - "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", - "dev": true, + "node_modules/@duckduckgo/content-scope-scripts": { + "version": "1.0.0", + "resolved": "git+ssh://git@github.com/duckduckgo/content-scope-scripts.git#943d9ca3d3f32e57eaa918b46fb6b1954b7c3319", + "hasInstallScript": true, "dependencies": { - "exec-sh": "^0.3.2", - "minimist": "^1.2.0" - }, - "bin": { - "watch": "cli.js" - }, - "engines": { - "node": ">=0.1.95" + "seedrandom": "^3.0.5", + "sjcl": "^1.0.8" } }, "node_modules/@eslint/eslintrc": { @@ -1128,6 +1718,22 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/@eslint/eslintrc/node_modules/globals": { "version": "12.4.0", "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", @@ -1140,6 +1746,12 @@ "node": ">=8" } }, + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -1191,6 +1803,9 @@ }, "engines": { "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { @@ -1242,20 +1857,20 @@ } }, "node_modules/@jest/console": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", - "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.4.6.tgz", + "integrity": "sha512-jauXyacQD33n47A44KrlOVeiXHEXDqapSdfb9kTekOchH/Pd18kBIO1+xxJQRLuG+LUuljFCwTG92ra4NW7SpA==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", + "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.6.2", - "jest-util": "^26.6.2", + "jest-message-util": "^27.4.6", + "jest-util": "^27.4.2", "slash": "^3.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/console/node_modules/ansi-styles": { @@ -1268,12 +1883,15 @@ }, "engines": { "node": ">=8" - } + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } }, "node_modules/@jest/console/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -1281,6 +1899,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/@jest/console/node_modules/color-convert": { @@ -1323,42 +1944,50 @@ } }, "node_modules/@jest/core": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.6.3.tgz", - "integrity": "sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==", + "version": "27.4.7", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.4.7.tgz", + "integrity": "sha512-n181PurSJkVMS+kClIFSX/LLvw9ExSb+4IMtD6YnfxZVerw9ANYtW0bPrm0MJu2pfe9SY9FJ9FtQ+MdZkrZwjg==", "dev": true, "dependencies": { - "@jest/console": "^26.6.2", - "@jest/reporters": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/console": "^27.4.6", + "@jest/reporters": "^27.4.6", + "@jest/test-result": "^27.4.6", + "@jest/transform": "^27.4.6", + "@jest/types": "^27.4.2", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", + "emittery": "^0.8.1", "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "jest-changed-files": "^26.6.2", - "jest-config": "^26.6.3", - "jest-haste-map": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-resolve-dependencies": "^26.6.3", - "jest-runner": "^26.6.3", - "jest-runtime": "^26.6.3", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "jest-watcher": "^26.6.2", - "micromatch": "^4.0.2", - "p-each-series": "^2.1.0", + "jest-changed-files": "^27.4.2", + "jest-config": "^27.4.7", + "jest-haste-map": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-regex-util": "^27.4.0", + "jest-resolve": "^27.4.6", + "jest-resolve-dependencies": "^27.4.6", + "jest-runner": "^27.4.6", + "jest-runtime": "^27.4.6", + "jest-snapshot": "^27.4.6", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.6", + "jest-watcher": "^27.4.6", + "micromatch": "^4.0.4", "rimraf": "^3.0.0", "slash": "^3.0.0", "strip-ansi": "^6.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, "node_modules/@jest/core/node_modules/ansi-styles": { @@ -1371,12 +2000,15 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/@jest/core/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -1384,6 +2016,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/@jest/core/node_modules/color-convert": { @@ -1426,87 +2061,93 @@ } }, "node_modules/@jest/environment": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", - "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.4.6.tgz", + "integrity": "sha512-E6t+RXPfATEEGVidr84WngLNWZ8ffCPky8RqqRK6u1Bn0LK92INe0MDttyPl/JOzaq92BmDzOeuqk09TvM22Sg==", "dev": true, "dependencies": { - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/fake-timers": "^27.4.6", + "@jest/types": "^27.4.2", "@types/node": "*", - "jest-mock": "^26.6.2" + "jest-mock": "^27.4.6" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/fake-timers": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", - "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.4.6.tgz", + "integrity": "sha512-mfaethuYF8scV8ntPpiVGIHQgS0XIALbpY2jt2l7wb/bvq4Q5pDLk4EP4D7SAvYT1QrPOPVZAtbdGAOOyIgs7A==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "@sinonjs/fake-timers": "^6.0.1", + "@jest/types": "^27.4.2", + "@sinonjs/fake-timers": "^8.0.1", "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" + "jest-message-util": "^27.4.6", + "jest-mock": "^27.4.6", + "jest-util": "^27.4.2" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/globals": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz", - "integrity": "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.4.6.tgz", + "integrity": "sha512-kAiwMGZ7UxrgPzu8Yv9uvWmXXxsy0GciNejlHvfPIfWkSxChzv6bgTS3YqBkGuHcis+ouMFI2696n2t+XYIeFw==", "dev": true, "dependencies": { - "@jest/environment": "^26.6.2", - "@jest/types": "^26.6.2", - "expect": "^26.6.2" + "@jest/environment": "^27.4.6", + "@jest/types": "^27.4.2", + "expect": "^27.4.6" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/reporters": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz", - "integrity": "sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.4.6.tgz", + "integrity": "sha512-+Zo9gV81R14+PSq4wzee4GC2mhAN9i9a7qgJWL90Gpx7fHYkWpTBvwWNZUXvJByYR9tAVBdc8VxDWqfJyIUrIQ==", "dev": true, "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/console": "^27.4.6", + "@jest/test-result": "^27.4.6", + "@jest/transform": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/node": "*", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", "glob": "^7.1.2", "graceful-fs": "^4.2.4", "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-instrument": "^5.1.0", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "jest-haste-map": "^26.6.2", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", + "istanbul-reports": "^3.1.3", + "jest-haste-map": "^27.4.6", + "jest-resolve": "^27.4.6", + "jest-util": "^27.4.2", + "jest-worker": "^27.4.6", "slash": "^3.0.0", "source-map": "^0.6.0", "string-length": "^4.0.1", "terminal-link": "^2.0.0", - "v8-to-istanbul": "^7.0.0" + "v8-to-istanbul": "^8.1.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" }, - "optionalDependencies": { - "node-notifier": "^8.0.0" + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, "node_modules/@jest/reporters/node_modules/ansi-styles": { @@ -1519,12 +2160,15 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/@jest/reporters/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -1532,6 +2176,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/@jest/reporters/node_modules/color-convert": { @@ -1583,9 +2230,9 @@ } }, "node_modules/@jest/source-map": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz", - "integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.4.0.tgz", + "integrity": "sha512-Ntjx9jzP26Bvhbm93z/AKcPRj/9wrkI88/gK60glXDx1q+IeI0rf7Lw2c89Ch6ofonB0On/iRDreQuQ6te9pgQ==", "dev": true, "dependencies": { "callsites": "^3.0.0", @@ -1593,7 +2240,7 @@ "source-map": "^0.6.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/source-map/node_modules/source-map": { @@ -1606,60 +2253,59 @@ } }, "node_modules/@jest/test-result": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", - "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.4.6.tgz", + "integrity": "sha512-fi9IGj3fkOrlMmhQqa/t9xum8jaJOOAi/lZlm6JXSc55rJMXKHxNDN1oCP39B0/DhNOa2OMupF9BcKZnNtXMOQ==", "dev": true, "dependencies": { - "@jest/console": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/console": "^27.4.6", + "@jest/types": "^27.4.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/test-sequencer": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz", - "integrity": "sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.4.6.tgz", + "integrity": "sha512-3GL+nsf6E1PsyNsJuvPyIz+DwFuCtBdtvPpm/LMXVkBJbdFvQYCDpccYT56qq5BGniXWlE81n2qk1sdXfZebnw==", "dev": true, "dependencies": { - "@jest/test-result": "^26.6.2", + "@jest/test-result": "^27.4.6", "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.6.2", - "jest-runner": "^26.6.3", - "jest-runtime": "^26.6.3" + "jest-haste-map": "^27.4.6", + "jest-runtime": "^27.4.6" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/transform": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz", - "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.4.6.tgz", + "integrity": "sha512-9MsufmJC8t5JTpWEQJ0OcOOAXaH5ioaIX6uHVBLBMoCZPfKKQF+EqP8kACAvCZ0Y1h2Zr3uOccg8re+Dr5jxyw==", "dev": true, "dependencies": { "@babel/core": "^7.1.0", - "@jest/types": "^26.6.2", - "babel-plugin-istanbul": "^6.0.0", + "@jest/types": "^27.4.2", + "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-util": "^26.6.2", - "micromatch": "^4.0.2", - "pirates": "^4.0.1", + "jest-haste-map": "^27.4.6", + "jest-regex-util": "^27.4.0", + "jest-util": "^27.4.2", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", "slash": "^3.0.0", "source-map": "^0.6.1", "write-file-atomic": "^3.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/transform/node_modules/ansi-styles": { @@ -1672,12 +2318,15 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/@jest/transform/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -1685,6 +2334,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/@jest/transform/node_modules/color-convert": { @@ -1736,19 +2388,19 @@ } }, "node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.4.2.tgz", + "integrity": "sha512-j35yw0PMTPpZsUoOBiuHzr1zTYoad1cVIE0ajEjcrJONxxrko/IRGKkXx3os0Nsi4Hu3+5VmDbVfq5WhG/pWAg==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", - "@types/yargs": "^15.0.0", + "@types/yargs": "^16.0.0", "chalk": "^4.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/types/node_modules/ansi-styles": { @@ -1761,12 +2413,15 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/@jest/types/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -1774,6 +2429,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/@jest/types/node_modules/color-convert": { @@ -1815,6 +2473,31 @@ "node": ">=8" } }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", + "integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", + "integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", + "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "node_modules/@sinonjs/commons": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", @@ -1825,18 +2508,44 @@ } }, "node_modules/@sinonjs/fake-timers": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", - "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", + "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", "dev": true, "dependencies": { "@sinonjs/commons": "^1.7.0" } }, + "node_modules/@sinonjs/samsam": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.3.1.tgz", + "integrity": "sha512-1Hc0b1TtyfBu8ixF/tpfSHTVWKwCBLY4QJbkgnE7HcwyvT2xArDxb4K7dMgqRm3szI+LJbzmW/s4xxEhv6hwDg==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.6.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + } + }, + "node_modules/@sinonjs/text-encoding": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", + "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "dev": true + }, + "node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/@types/babel__core": { - "version": "7.1.14", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.14.tgz", - "integrity": "sha512-zGZJzzBUVDo/eV6KgbE0f0ZI7dInEYvo12Rb70uNQDshC3SkRMb67ja0GgRHZgAX3Za6rhaWlvbDO8rrGyAb1g==", + "version": "7.1.18", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.18.tgz", + "integrity": "sha512-S7unDjm/C7z2A2R9NzfKCK1I+BAALDtxEmsJBwlB3EzNfb929ykjL++1CK9LO++EIp2fQrC8O+BwjKvz6UeDyQ==", "dev": true, "dependencies": { "@babel/parser": "^7.1.0", @@ -1847,18 +2556,18 @@ } }, "node_modules/@types/babel__generator": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.2.tgz", - "integrity": "sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", "dev": true, "dependencies": { "@babel/types": "^7.0.0" } }, "node_modules/@types/babel__template": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.0.tgz", - "integrity": "sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A==", + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", "dev": true, "dependencies": { "@babel/parser": "^7.1.0", @@ -1866,9 +2575,9 @@ } }, "node_modules/@types/babel__traverse": { - "version": "7.11.1", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.11.1.tgz", - "integrity": "sha512-Vs0hm0vPahPMYi9tDjtP66llufgO3ST16WXaSTtDGEl9cewAl3AibmxWw6TINOqHPT9z0uABKAYjT9jNSg4npw==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", + "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", "dev": true, "dependencies": { "@babel/types": "^7.3.0" @@ -1884,6 +2593,12 @@ "@types/har-format": "*" } }, + "node_modules/@types/dateformat": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/dateformat/-/dateformat-3.0.1.tgz", + "integrity": "sha512-KlPPdikagvL6ELjWsljbyDIPzNCeliYkqRpI+zea99vBBbCIA5JNshZAwQKTON139c87y9qvTFVgkFd14rtS4g==", + "dev": true + }, "node_modules/@types/filesystem": { "version": "0.0.30", "resolved": "https://registry.npmjs.org/@types/filesystem/-/filesystem-0.0.30.tgz", @@ -1915,9 +2630,9 @@ "dev": true }, "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", "dev": true }, "node_modules/@types/istanbul-lib-report": { @@ -1930,14 +2645,24 @@ } }, "node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" } }, + "node_modules/@types/jest": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.0.tgz", + "integrity": "sha512-gHl8XuC1RZ8H2j5sHv/JqsaxXkDDM9iDOgu0Wp8sjs4u/snb2PVehyWXJPr+ORA0RPpgw231mnutWI1+0hgjIQ==", + "dev": true, + "dependencies": { + "jest-diff": "^27.0.0", + "pretty-format": "^27.0.0" + } + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -1950,45 +2675,64 @@ "integrity": "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA==", "dev": true }, + "node_modules/@types/mkdirp": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-1.0.2.tgz", + "integrity": "sha512-o0K1tSO0Dx5X6xlU5F1D6625FawhC3dU3iqr25lluNv/+/QIVH8RLNEiVokgIZo+mz+87w/3Mkg/VvQS+J51fQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/node": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-15.3.0.tgz", - "integrity": "sha512-8/bnjSZD86ZfpBsDlCIkNXIvm+h6wi9g7IqL+kmFkQ+Wvu3JrasgLElfiPgoo8V8vVfnEi0QVS12gbl94h9YsQ==", + "version": "16.11.25", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.25.tgz", + "integrity": "sha512-NrTwfD7L1RTc2qrHQD4RTTy4p0CO2LatKBEKEds3CaVuhoM/+DJzmWZl5f+ikR8cm8F5mfJxK+9rQq07gRiSjQ==", "dev": true }, - "node_modules/@types/normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "node_modules/@types/prettier": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.3.tgz", + "integrity": "sha512-QzSuZMBuG5u8HqYz01qtMdg/Jfctlnvj1z/lYnIDXs/golxw0fxtRAHd9KrzjR7Yxz1qVeI00o0kiO3PmVdJ9w==", "dev": true }, - "node_modules/@types/prettier": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz", - "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==", + "node_modules/@types/sinon": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-7.5.2.tgz", + "integrity": "sha512-T+m89VdXj/eidZyejvmoP9jivXgBDdkOSBVQjU9kF349NEx10QdPNGxHeZUaj1IlJ32/ewdyXJjnJxyxJroYwg==", "dev": true }, "node_modules/@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, "node_modules/@types/yargs": { - "version": "15.0.13", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.13.tgz", - "integrity": "sha512-kQ5JNTrbDv3Rp5X2n/iUu37IJBDU2gsZ5R/g1/KHOOEc5IKfUFjXT6DENPGduh08I/pamwtEq4oul7gUqKTQDQ==", + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", "dev": true, "dependencies": { "@types/yargs-parser": "*" } }, "node_modules/@types/yargs-parser": { - "version": "20.2.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz", - "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==", + "version": "20.2.1", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", + "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", "dev": true }, + "node_modules/@types/yauzl": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz", + "integrity": "sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/abab": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", @@ -2049,16 +2793,32 @@ "node": ">=0.4.0" } }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.10.0.tgz", + "integrity": "sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, "node_modules/ansi-colors": { @@ -2080,6 +2840,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/ansi-escapes/node_modules/type-fest": { @@ -2089,12 +2852,15 @@ "dev": true, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "engines": { "node": ">=8" @@ -2134,33 +2900,6 @@ "sprintf-js": "~1.0.2" } }, - "node_modules/arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/array-differ": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", @@ -2219,15 +2958,6 @@ "node": ">=8" } }, - "node_modules/array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/array.prototype.flat": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", @@ -2325,15 +3055,6 @@ "inherits": "2.0.1" } }, - "node_modules/assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", @@ -2355,18 +3076,6 @@ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "dev": true }, - "node_modules/atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true, - "bin": { - "atob": "bin/atob.js" - }, - "engines": { - "node": ">= 4.5.0" - } - }, "node_modules/available-typed-arrays": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz", @@ -2395,22 +3104,25 @@ "dev": true }, "node_modules/babel-jest": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.6.3.tgz", - "integrity": "sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.4.6.tgz", + "integrity": "sha512-qZL0JT0HS1L+lOuH+xC2DVASR3nunZi/ozGhpgauJHgmI7f8rudxf6hUjEHympdQ/J64CdKmPkgfJ+A3U6QCrg==", "dev": true, "dependencies": { - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/babel__core": "^7.1.7", - "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^26.6.2", + "@jest/transform": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^27.4.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "slash": "^3.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" } }, "node_modules/babel-jest/node_modules/ansi-styles": { @@ -2423,12 +3135,15 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/babel-jest/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -2436,6 +3151,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/babel-jest/node_modules/color-convert": { @@ -2487,15 +3205,15 @@ } }, "node_modules/babel-plugin-istanbul": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", - "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@istanbuljs/load-nyc-config": "^1.0.0", "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-instrument": "^5.0.4", "test-exclude": "^6.0.0" }, "engines": { @@ -2503,9 +3221,9 @@ } }, "node_modules/babel-plugin-jest-hoist": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz", - "integrity": "sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.4.0.tgz", + "integrity": "sha512-Jcu7qS4OX5kTWBc45Hz7BMmgXuJqRnhatqpUhnzGC3OBYpOmf2tv6jFNwZpwM7wU7MUuv2r9IPS/ZlYOuburVw==", "dev": true, "dependencies": { "@babel/template": "^7.3.3", @@ -2514,37 +3232,46 @@ "@types/babel__traverse": "^7.0.6" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.0.tgz", - "integrity": "sha512-9bNwiR0dS881c5SHnzCmmGlMkJLl0OUZvxrxHo9w/iNoRuqaPjqlvBf4HrovXtQs/au5yKkpcdgfT1cC5PAZwg==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz", + "integrity": "sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w==", "dev": true, "dependencies": { "@babel/compat-data": "^7.13.11", - "@babel/helper-define-polyfill-provider": "^0.2.0", + "@babel/helper-define-polyfill-provider": "^0.3.1", "semver": "^6.1.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.0.tgz", - "integrity": "sha512-zZyi7p3BCUyzNxLx8KV61zTINkkV65zVkDAFNZmrTCRVhjo1jAS+YLvDJ9Jgd/w2tsAviCwFHReYfxO3Iql8Yg==", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.2.tgz", + "integrity": "sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ==", "dev": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.2.0", - "core-js-compat": "^3.9.1" + "@babel/helper-define-polyfill-provider": "^0.3.1", + "core-js-compat": "^3.21.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.0.tgz", - "integrity": "sha512-J7vKbCuD2Xi/eEHxquHN14bXAW9CXtecwuLrOIDJtcZzTaPzV1VdEfoUf9AzcRBMolKUQKM9/GVojeh0hFiqMg==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz", + "integrity": "sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A==", "dev": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.2.0" + "@babel/helper-define-polyfill-provider": "^0.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/babel-preset-current-node-syntax": { @@ -2565,19 +3292,25 @@ "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/babel-preset-jest": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz", - "integrity": "sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.4.0.tgz", + "integrity": "sha512-NK4jGYpnBvNxcGo7/ZpZJr51jCGT+3bwwpVIDY2oNfTxJJldRtB4VAcYdgp1loDE50ODuTu+yBjpMAswv5tlpg==", "dev": true, "dependencies": { - "babel-plugin-jest-hoist": "^26.6.2", + "babel-plugin-jest-hoist": "^27.4.0", "babel-preset-current-node-syntax": "^1.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/babelify": { @@ -2595,96 +3328,77 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "node_modules/base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", "dev": true, "dependencies": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" + "tweetnacl": "^0.14.3" } }, - "node_modules/base/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/base/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "dev": true, "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" } }, - "node_modules/base/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "node_modules/bl/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" } }, - "node_modules/base/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "node_modules/bl/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true - }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "engines": { - "node": ">=8" + "node": ">= 6" } }, "node_modules/bluebird": { @@ -2999,22 +3713,26 @@ "dev": true }, "node_modules/browserslist": { - "version": "4.16.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.5.tgz", - "integrity": "sha512-C2HAjrM1AI/djrpAUU/tr4pml1DqLIzJKSLDBXBrNErl9ZCCTXdhwxdJjYc16953+mBWf7Lw+uUJgpgb8cN71A==", + "version": "4.19.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.3.tgz", + "integrity": "sha512-XK3X4xtKJ+Txj8G5c30B4gsm71s69lqXlkYui4s6EkKxuv49qjYlY6oVd+IFJ73d4YymtM3+djvvt/R/iJwwDg==", "dev": true, "dependencies": { - "caniuse-lite": "^1.0.30001214", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.719", + "caniuse-lite": "^1.0.30001312", + "electron-to-chromium": "^1.4.71", "escalade": "^3.1.1", - "node-releases": "^1.1.71" + "node-releases": "^2.0.2", + "picocolors": "^1.0.0" }, "bin": { "browserslist": "cli.js" }, "engines": { "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" } }, "node_modules/bser": { @@ -3036,6 +3754,15 @@ "ieee754": "^1.1.4" } }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", @@ -3060,26 +3787,6 @@ "integrity": "sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=", "dev": true }, - "node_modules/cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "dependencies": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/cached-path-relative": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.2.tgz", @@ -3115,21 +3822,13 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001219", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001219.tgz", - "integrity": "sha512-c0yixVG4v9KBc/tQ2rlbB3A/bgBFRvl8h8M4IeUbqCca4gsiCfvtaheUssbnux/Mb66Vjz7x8yYjDgYcNQOhyQ==", - "dev": true - }, - "node_modules/capture-exit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", - "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", + "version": "1.0.30001312", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz", + "integrity": "sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ==", "dev": true, - "dependencies": { - "rsvp": "^4.8.4" - }, - "engines": { - "node": "6.* || 8.* || >= 10.*" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" } }, "node_modules/caseless": { @@ -3182,10 +3881,16 @@ "fsevents": "~2.3.1" } }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, "node_modules/ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", + "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==", "dev": true }, "node_modules/cipher-base": { @@ -3199,47 +3904,20 @@ } }, "node_modules/cjs-module-lexer": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz", - "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", "dev": true }, - "node_modules/class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "dependencies": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" + "wrap-ansi": "^7.0.0" } }, "node_modules/co": { @@ -3258,19 +3936,6 @@ "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", "dev": true }, - "node_modules/collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "dependencies": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -3286,12 +3951,6 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, - "node_modules/colorette": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", - "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", - "dev": true - }, "node_modules/colors": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", @@ -3331,12 +3990,6 @@ "node": ">= 0.8" } }, - "node_modules/component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -3394,23 +4047,18 @@ "safe-buffer": "~5.1.1" } }, - "node_modules/copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/core-js-compat": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.11.0.tgz", - "integrity": "sha512-3wsN9YZJohOSDCjVB0GequOyHax8zFiogSX3XWLE28M1Ew7dTU57tgHjIylSBKSIouwmLBp3g61sKMz/q3xEGA==", + "version": "3.21.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.21.1.tgz", + "integrity": "sha512-gbgX5AUvMb8gwxC7FLVWYT7Kkgu/y7+h/h1X43yJkNqhlK2fuYyQimqvKGNZFAY6CKii/GFKJ2cp/1/42TN36g==", "dev": true, "dependencies": { - "browserslist": "^4.16.4", + "browserslist": "^4.19.1", "semver": "7.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" } }, "node_modules/core-js-compat/node_modules/semver": { @@ -3573,40 +4221,33 @@ } }, "node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "dependencies": { "ms": "2.1.2" }, "engines": { "node": ">=6.0" - } - }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true, - "engines": { - "node": ">=0.10.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, "node_modules/decimal.js": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz", - "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==", + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", + "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", "dev": true }, - "node_modules/decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true, - "engines": { - "node": ">=0.10" - } + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true }, "node_modules/deep-is": { "version": "0.1.3", @@ -3635,57 +4276,6 @@ "node": ">= 0.4" } }, - "node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-property/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-property/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-property/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/defined": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", @@ -3761,13 +4351,28 @@ "node": ">=0.8.0" } }, + "node_modules/devtools-protocol": { + "version": "0.0.948846", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.948846.tgz", + "integrity": "sha512-5fGyt9xmMqUl2VI7+rnUkKCiAQIpLns8sfQtTENy5L70ktbNw0Z3TFJ1JoFNYdx/jffz4YXU45VF75wKZD7sZQ==", + "dev": true + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/diff-sequences": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", - "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.4.0.tgz", + "integrity": "sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww==", "dev": true, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/diffie-hellman": { @@ -3850,9 +4455,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.3.723", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.723.tgz", - "integrity": "sha512-L+WXyXI7c7+G1V8ANzRsPI5giiimLAUDC6Zs1ojHHPhYXb3k/iTABFmWjivEtsWrRQymjnO66/rO2ZTABGdmWg==", + "version": "1.4.71", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.71.tgz", + "integrity": "sha512-Hk61vXXKRb2cd3znPE9F+2pLWdIOmP7GjiTj45y6L3W/lO+hSnUSUhq+6lEaERWBdZOHbk2s3YV5c9xVl3boVw==", "dev": true }, "node_modules/elliptic": { @@ -3877,12 +4482,15 @@ "dev": true }, "node_modules/emittery": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", - "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==", + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", + "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", "dev": true, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" } }, "node_modules/emoji-regex": { @@ -4021,9 +4629,9 @@ } }, "node_modules/escodegen/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "engines": { "node": ">=4.0" @@ -4349,6 +4957,22 @@ "@babel/highlight": "^7.10.4" } }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/eslint/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -4422,6 +5046,12 @@ "node": ">=8" } }, + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "node_modules/eslint/node_modules/semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", @@ -4570,332 +5200,104 @@ "safe-buffer": "^5.1.1" } }, - "node_modules/exec-sh": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.6.tgz", - "integrity": "sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w==", - "dev": true - }, "node_modules/execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, "dependencies": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" }, "engines": { - "node": ">=6" - } - }, - "node_modules/execa/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "node": ">=10" }, - "engines": { - "node": ">=4.8" + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/execa/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", "dev": true, "engines": { - "node": ">=4" - } - }, - "node_modules/execa/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" + "node": ">= 0.8.0" } }, - "node_modules/execa/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "node_modules/expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", "dev": true, "dependencies": { - "shebang-regex": "^1.0.0" + "homedir-polyfill": "^1.0.1" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/execa/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "node_modules/expect": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.4.6.tgz", + "integrity": "sha512-1M/0kAALIaj5LaG66sFJTbRsWTADnylly82cu4bspI0nl+pgP4E6Bh/aqdHlTUjul06K7xQnnrAoqfxVU0+/ag==", "dev": true, + "dependencies": { + "@jest/types": "^27.4.2", + "jest-get-type": "^27.4.0", + "jest-matcher-utils": "^27.4.6", + "jest-message-util": "^27.4.6" + }, "engines": { - "node": ">=0.10.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/execa/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", "dev": true, "dependencies": { - "isexe": "^2.0.0" + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" }, "bin": { - "which": "bin/which" - } - }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true, + "extract-zip": "cli.js" + }, "engines": { - "node": ">= 0.8.0" + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" } }, - "node_modules/expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "node_modules/extract-zip/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "dependencies": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/expand-brackets/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", - "dev": true, - "dependencies": { - "homedir-polyfill": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expect": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", - "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "ansi-styles": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/expect/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" + "pump": "^3.0.0" }, "engines": { "node": ">=8" - } - }, - "node_modules/expect/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/expect/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extend-shallow/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "dependencies": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/extsprintf": { @@ -4907,6 +5309,22 @@ "node >=0.6.0" ] }, + "node_modules/fast-check": { + "version": "2.22.0", + "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-2.22.0.tgz", + "integrity": "sha512-Yrx1E8fZk6tfSqYaNkwnxj/lOk+vj2KTbbpHDtYoK9MrrL/D204N/rCtcaVSz5bE29g6gW4xj0byresjlFyybg==", + "dev": true, + "dependencies": { + "pure-rand": "^5.0.0" + }, + "engines": { + "node": ">=8.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -4952,6 +5370,15 @@ "bser": "2.1.1" } }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -5110,17 +5537,11 @@ "node": ">= 0.12" } }, - "node_modules/fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "dependencies": { - "map-cache": "^0.2.2" - }, - "engines": { - "node": ">=0.10.0" - } + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true }, "node_modules/fs.realpath": { "version": "1.0.0", @@ -5210,24 +5631,15 @@ } }, "node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/getobject": { @@ -5353,7 +5765,8 @@ "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", "dev": true, - "optional": true + "optional": true, + "peer": true }, "node_modules/grunt": { "version": "1.4.0", @@ -5703,6 +6116,28 @@ "node": ">=6" } }, + "node_modules/har-validator/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/har-validator/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -5739,69 +6174,6 @@ "node": ">= 0.4" } }, - "node_modules/has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "dependencies": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "dependencies": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/hash-base": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", @@ -5917,6 +6289,20 @@ "integrity": "sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg==", "dev": true }, + "node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -5938,13 +6324,26 @@ "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", "dev": true }, - "node_modules/human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "node_modules/https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, "engines": { - "node": ">=8.12.0" + "node": ">=10.17.0" } }, "node_modules/iconv-lite": { @@ -5988,9 +6387,9 @@ } }, "node_modules/import-local": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", - "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", "dev": true, "dependencies": { "pkg-dir": "^4.2.0", @@ -6001,6 +6400,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/import-local/node_modules/find-up": { @@ -6038,6 +6440,9 @@ }, "engines": { "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/import-local/node_modules/p-locate": { @@ -6162,30 +6567,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-arguments": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", @@ -6261,6 +6642,12 @@ "is-ci": "bin.js" } }, + "node_modules/is-ci/node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, "node_modules/is-core-module": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.3.0.tgz", @@ -6270,30 +6657,6 @@ "has": "^1.0.3" } }, - "node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-date-object": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", @@ -6303,49 +6666,21 @@ "node": ">= 0.4" } }, - "node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-descriptor/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-docker": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "dev": true, "optional": true, + "peer": true, "bin": { "is-docker": "cli.js" }, "engines": { "node": ">=8" - } - }, - "node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true, - "engines": { - "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-extglob": { @@ -6385,9 +6720,9 @@ } }, "node_modules/is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "dependencies": { "is-extglob": "^2.1.1" @@ -6467,12 +6802,15 @@ } }, "node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-string": { @@ -6545,6 +6883,7 @@ "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "dev": true, "optional": true, + "peer": true, "dependencies": { "is-docker": "^2.0.0" }, @@ -6580,23 +6919,24 @@ "dev": true }, "node_modules/istanbul-lib-coverage": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz", + "integrity": "sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==", "dev": true, "dependencies": { - "@babel/core": "^7.7.5", + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-coverage": "^3.2.0", "semver": "^6.3.0" }, "engines": { @@ -6639,9 +6979,9 @@ } }, "node_modules/istanbul-lib-source-maps": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", - "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, "dependencies": { "debug": "^4.1.1", @@ -6649,7 +6989,7 @@ "source-map": "^0.6.1" }, "engines": { - "node": ">=8" + "node": ">=10" } }, "node_modules/istanbul-lib-source-maps/node_modules/source-map": { @@ -6662,9 +7002,9 @@ } }, "node_modules/istanbul-reports": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", - "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.3.tgz", + "integrity": "sha512-x9LtDVtfm/t1GFiLl3NffC7hz+I1ragvgX1P/Lg1NlIagifZDKUkuuaAxH/qpwj2IuEfD8G2Bs/UKp+sZ/pKkg==", "dev": true, "dependencies": { "html-escaper": "^2.0.0", @@ -6674,88 +7014,62 @@ "node": ">=8" } }, - "node_modules/jest": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest/-/jest-26.6.3.tgz", - "integrity": "sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==", + "node_modules/jasmine": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-4.0.2.tgz", + "integrity": "sha512-YsrgxJQEggxzByYe4j68eQLOiQeSrPDYGv4sHhGBp3c6HHdq+uPXeAQ73kOAQpdLZ3/0zN7x/TZTloqeE1/qIA==", "dev": true, "dependencies": { - "@jest/core": "^26.6.3", - "import-local": "^3.0.2", - "jest-cli": "^26.6.3" + "glob": "^7.1.6", + "jasmine-core": "^4.0.0" }, "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": ">= 10.14.2" + "jasmine": "bin/jasmine.js" } }, - "node_modules/jest-changed-files": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.6.2.tgz", - "integrity": "sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "execa": "^4.0.0", - "throat": "^5.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } + "node_modules/jasmine-core": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.0.0.tgz", + "integrity": "sha512-tq24OCqHElgU9KDpb/8O21r1IfotgjIzalfW9eCmRR40LZpvwXT68iariIyayMwi0m98RDt16aljdbwK0sBMmQ==", + "dev": true }, - "node_modules/jest-changed-files/node_modules/execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "node_modules/jest": { + "version": "27.4.7", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.4.7.tgz", + "integrity": "sha512-8heYvsx7nV/m8m24Vk26Y87g73Ba6ueUd0MWed/NXMhSZIm62U/llVbS0PJe1SHunbyXjJ/BqG1z9bFjGUIvTg==", "dev": true, "dependencies": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" + "@jest/core": "^27.4.7", + "import-local": "^3.0.2", + "jest-cli": "^27.4.7" }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-changed-files/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" + "bin": { + "jest": "bin/jest.js" }, "engines": { - "node": ">=8" - } - }, - "node_modules/jest-changed-files/node_modules/is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "dev": true, - "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/jest-changed-files/node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "node_modules/jest-changed-files": { + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.4.2.tgz", + "integrity": "sha512-/9x8MjekuzUQoPjDHbBiXbNEBauhrPU2ct7m8TfCg69ywt1y/N+yYwGh3gCpnqUS3klYWDU/lSNgv+JhoD2k1A==", "dev": true, "dependencies": { - "path-key": "^3.0.0" + "@jest/types": "^27.4.2", + "execa": "^5.0.0", + "throat": "^6.0.1" }, "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-chrome": { @@ -6767,36 +7081,37 @@ "@types/chrome": "^0.0.114" } }, - "node_modules/jest-config": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", - "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", + "node_modules/jest-circus": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.4.6.tgz", + "integrity": "sha512-UA7AI5HZrW4wRM72Ro80uRR2Fg+7nR0GESbSI/2M+ambbzVuA63mn5T1p3Z/wlhntzGpIG1xx78GP2YIkf6PhQ==", "dev": true, "dependencies": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.6.3", - "@jest/types": "^26.6.2", - "babel-jest": "^26.6.3", + "@jest/environment": "^27.4.6", + "@jest/test-result": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/node": "*", "chalk": "^4.0.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.6.2", - "jest-environment-node": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-jasmine2": "^26.6.3", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2" + "co": "^4.6.0", + "dedent": "^0.7.0", + "expect": "^27.4.6", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.4.6", + "jest-matcher-utils": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-runtime": "^27.4.6", + "jest-snapshot": "^27.4.6", + "jest-util": "^27.4.2", + "pretty-format": "^27.4.6", + "slash": "^3.0.0", + "stack-utils": "^2.0.3", + "throat": "^6.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-config/node_modules/ansi-styles": { + "node_modules/jest-circus/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", @@ -6806,12 +7121,15 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-config/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "node_modules/jest-circus/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -6819,9 +7137,12 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-config/node_modules/color-convert": { + "node_modules/jest-circus/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", @@ -6833,13 +7154,13 @@ "node": ">=7.0.0" } }, - "node_modules/jest-config/node_modules/color-name": { + "node_modules/jest-circus/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/jest-config/node_modules/has-flag": { + "node_modules/jest-circus/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", @@ -6848,7 +7169,7 @@ "node": ">=8" } }, - "node_modules/jest-config/node_modules/supports-color": { + "node_modules/jest-circus/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", @@ -6860,22 +7181,41 @@ "node": ">=8" } }, - "node_modules/jest-diff": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", - "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", + "node_modules/jest-cli": { + "version": "27.4.7", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.4.7.tgz", + "integrity": "sha512-zREYhvjjqe1KsGV15mdnxjThKNDgza1fhDT+iUsXWLCq3sxe9w5xnvyctcYVT5PcdLSjv7Y5dCwTS3FCF1tiuw==", "dev": true, "dependencies": { + "@jest/core": "^27.4.7", + "@jest/test-result": "^27.4.6", + "@jest/types": "^27.4.2", "chalk": "^4.0.0", - "diff-sequences": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "jest-config": "^27.4.7", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.6", + "prompts": "^2.0.1", + "yargs": "^16.2.0" + }, + "bin": { + "jest": "bin/jest.js" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/jest-diff/node_modules/ansi-styles": { + "node_modules/jest-cli/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", @@ -6885,12 +7225,15 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-diff/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "node_modules/jest-cli/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -6898,9 +7241,12 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-diff/node_modules/color-convert": { + "node_modules/jest-cli/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", @@ -6912,13 +7258,13 @@ "node": ">=7.0.0" } }, - "node_modules/jest-diff/node_modules/color-name": { + "node_modules/jest-cli/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/jest-diff/node_modules/has-flag": { + "node_modules/jest-cli/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", @@ -6927,7 +7273,7 @@ "node": ">=8" } }, - "node_modules/jest-diff/node_modules/supports-color": { + "node_modules/jest-cli/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", @@ -6939,35 +7285,48 @@ "node": ">=8" } }, - "node_modules/jest-docblock": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", - "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", - "dev": true, - "dependencies": { - "detect-newline": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-each": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", - "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", + "node_modules/jest-config": { + "version": "27.4.7", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.4.7.tgz", + "integrity": "sha512-xz/o/KJJEedHMrIY9v2ParIoYSrSVY6IVeE4z5Z3i101GoA5XgfbJz+1C8EYPsv7u7f39dS8F9v46BHDhn0vlw==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", + "@babel/core": "^7.8.0", + "@jest/test-sequencer": "^27.4.6", + "@jest/types": "^27.4.2", + "babel-jest": "^27.4.6", "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2" + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-circus": "^27.4.6", + "jest-environment-jsdom": "^27.4.6", + "jest-environment-node": "^27.4.6", + "jest-get-type": "^27.4.0", + "jest-jasmine2": "^27.4.6", + "jest-regex-util": "^27.4.0", + "jest-resolve": "^27.4.6", + "jest-runner": "^27.4.6", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.6", + "micromatch": "^4.0.4", + "pretty-format": "^27.4.6", + "slash": "^3.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + } } }, - "node_modules/jest-each/node_modules/ansi-styles": { + "node_modules/jest-config/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", @@ -6977,12 +7336,15 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-each/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "node_modules/jest-config/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -6990,9 +7352,12 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-each/node_modules/color-convert": { + "node_modules/jest-config/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", @@ -7004,13 +7369,13 @@ "node": ">=7.0.0" } }, - "node_modules/jest-each/node_modules/color-name": { + "node_modules/jest-config/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/jest-each/node_modules/has-flag": { + "node_modules/jest-config/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", @@ -7019,7 +7384,7 @@ "node": ">=8" } }, - "node_modules/jest-each/node_modules/supports-color": { + "node_modules/jest-config/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", @@ -7031,122 +7396,40 @@ "node": ">=8" } }, - "node_modules/jest-environment-jsdom": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz", - "integrity": "sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==", + "node_modules/jest-diff": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.4.6.tgz", + "integrity": "sha512-zjaB0sh0Lb13VyPsd92V7HkqF6yKRH9vm33rwBt7rPYrpQvS1nCvlIy2pICbKta+ZjWngYLNn4cCK4nyZkjS/w==", "dev": true, "dependencies": { - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2", - "jsdom": "^16.4.0" + "chalk": "^4.0.0", + "diff-sequences": "^27.4.0", + "jest-get-type": "^27.4.0", + "pretty-format": "^27.4.6" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-environment-node": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.2.tgz", - "integrity": "sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==", + "node_modules/jest-diff/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" + "color-convert": "^2.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-haste-map": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", - "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-regex-util": "^26.0.0", - "jest-serializer": "^26.6.2", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "micromatch": "^4.0.2", - "sane": "^4.0.3", - "walker": "^1.0.7" - }, - "engines": { - "node": ">= 10.14.2" - }, - "optionalDependencies": { - "fsevents": "^2.1.2" - } - }, - "node_modules/jest-jasmine2": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz", - "integrity": "sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^26.6.2", - "@jest/source-map": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^26.6.2", - "is-generator-fn": "^2.0.0", - "jest-each": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-runtime": "^26.6.3", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2", - "throat": "^5.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-jasmine2/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-jasmine2/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "node_modules/jest-diff/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -7154,9 +7437,12 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-jasmine2/node_modules/color-convert": { + "node_modules/jest-diff/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", @@ -7168,13 +7454,13 @@ "node": ">=7.0.0" } }, - "node_modules/jest-jasmine2/node_modules/color-name": { + "node_modules/jest-diff/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/jest-jasmine2/node_modules/has-flag": { + "node_modules/jest-diff/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", @@ -7183,7 +7469,7 @@ "node": ">=8" } }, - "node_modules/jest-jasmine2/node_modules/supports-color": { + "node_modules/jest-diff/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", @@ -7195,35 +7481,35 @@ "node": ">=8" } }, - "node_modules/jest-leak-detector": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz", - "integrity": "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==", + "node_modules/jest-docblock": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.4.0.tgz", + "integrity": "sha512-7TBazUdCKGV7svZ+gh7C8esAnweJoG+SvcF6Cjqj4l17zA2q1cMwx2JObSioubk317H+cjcHgP+7fTs60paulg==", "dev": true, "dependencies": { - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" + "detect-newline": "^3.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-matcher-utils": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", - "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", + "node_modules/jest-each": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.4.6.tgz", + "integrity": "sha512-n6QDq8y2Hsmn22tRkgAk+z6MCX7MeVlAzxmZDshfS2jLcaBlyhpF3tZSJLR+kXmh23GEvS0ojMR8i6ZeRvpQcA==", "dev": true, "dependencies": { + "@jest/types": "^27.4.2", "chalk": "^4.0.0", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" + "jest-get-type": "^27.4.0", + "jest-util": "^27.4.2", + "pretty-format": "^27.4.6" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "node_modules/jest-each/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", @@ -7233,12 +7519,15 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-matcher-utils/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "node_modules/jest-each/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -7246,9 +7535,12 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-matcher-utils/node_modules/color-convert": { + "node_modules/jest-each/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", @@ -7260,13 +7552,13 @@ "node": ">=7.0.0" } }, - "node_modules/jest-matcher-utils/node_modules/color-name": { + "node_modules/jest-each/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/jest-matcher-utils/node_modules/has-flag": { + "node_modules/jest-each/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", @@ -7275,7 +7567,7 @@ "node": ">=8" } }, - "node_modules/jest-matcher-utils/node_modules/supports-color": { + "node_modules/jest-each/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", @@ -7287,155 +7579,251 @@ "node": ">=8" } }, - "node_modules/jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "node_modules/jest-environment-jsdom": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.4.6.tgz", + "integrity": "sha512-o3dx5p/kHPbUlRvSNjypEcEtgs6LmvESMzgRFQE6c+Prwl2JLA4RZ7qAnxc5VM8kutsGRTB15jXeeSbJsKN9iA==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" + "@jest/environment": "^27.4.6", + "@jest/fake-timers": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/node": "*", + "jest-mock": "^27.4.6", + "jest-util": "^27.4.2", + "jsdom": "^16.6.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-message-util/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/jest-environment-node": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.4.6.tgz", + "integrity": "sha512-yfHlZ9m+kzTKZV0hVfhVu6GuDxKAYeFHrfulmy7Jxwsq4V7+ZK7f+c0XP/tbVDMQW7E4neG2u147hFkuVz0MlQ==", "dev": true, "dependencies": { - "color-convert": "^2.0.1" + "@jest/environment": "^27.4.6", + "@jest/fake-timers": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/node": "*", + "jest-mock": "^27.4.6", + "jest-util": "^27.4.2" }, "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-message-util/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "node_modules/jest-get-type": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.4.0.tgz", + "integrity": "sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.4.6.tgz", + "integrity": "sha512-0tNpgxg7BKurZeFkIOvGCkbmOHbLFf4LUQOxrQSMjvrQaQe3l6E8x6jYC1NuWkGo5WDdbr8FEzUxV2+LWNawKQ==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@jest/types": "^27.4.2", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-regex-util": "^27.4.0", + "jest-serializer": "^27.4.0", + "jest-util": "^27.4.2", + "jest-worker": "^27.4.6", + "micromatch": "^4.0.4", + "walker": "^1.0.7" }, "engines": { - "node": ">=10" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" } }, - "node_modules/jest-message-util/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/jest-html-reporter": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/jest-html-reporter/-/jest-html-reporter-3.4.2.tgz", + "integrity": "sha512-2dA4oJdLP2+rewakwLdBhBCdk50zqzgD6Wk0fvsbdS0C9WwpuePwd0kQWRRdfLzNJM5CgC4O98wkK1lBFqJVrw==", "dev": true, "dependencies": { - "color-name": "~1.1.4" + "@babel/core": "^7.9.0", + "@babel/preset-env": "^7.8.7", + "@babel/preset-typescript": "^7.8.3", + "@jest/console": "^25.1.0", + "@jest/test-result": "^25.1.0", + "@jest/types": "^26.0.23", + "@types/dateformat": "^3.0.1", + "@types/jest": "^25.1.4", + "@types/mkdirp": "^1.0.0", + "@types/node": "^12.12.7", + "@types/sinon": "^7.5.2", + "dateformat": "3.0.2", + "mkdirp": "^1.0.3", + "sinon": "^9.0.1", + "strip-ansi": "6.0.1", + "xmlbuilder": "15.0.0" }, "engines": { - "node": ">=7.0.0" + "node": ">=4.8.3" + }, + "peerDependencies": { + "jest": "19.x - 27.x" } }, - "node_modules/jest-message-util/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-message-util/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/jest-html-reporter/node_modules/@jest/console": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", + "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "jest-message-util": "^25.5.0", + "jest-util": "^25.5.0", + "slash": "^3.0.0" + }, "engines": { - "node": ">=8" + "node": ">= 8.3" } }, - "node_modules/jest-message-util/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/jest-html-reporter/node_modules/@jest/console/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">= 8.3" } }, - "node_modules/jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "node_modules/jest-html-reporter/node_modules/@jest/console/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*" + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/jest-html-reporter/node_modules/@jest/test-result": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", + "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", + "dev": true, + "dependencies": { + "@jest/console": "^25.5.0", + "@jest/types": "^25.5.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 8.3" } }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "node_modules/jest-html-reporter/node_modules/@jest/test-result/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, "engines": { - "node": ">=6" + "node": ">= 8.3" } }, - "node_modules/jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "node_modules/jest-html-reporter/node_modules/@jest/test-result/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", "dev": true, - "engines": { - "node": ">= 10.14.2" + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" } }, - "node_modules/jest-resolve": { + "node_modules/jest-html-reporter/node_modules/@jest/types": { "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/jest-resolve-dependencies": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz", - "integrity": "sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg==", + "node_modules/jest-html-reporter/node_modules/@jest/types/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-snapshot": "^26.6.2" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-resolve/node_modules/ansi-styles": { + "node_modules/jest-html-reporter/node_modules/@types/jest": { + "version": "25.2.3", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-25.2.3.tgz", + "integrity": "sha512-JXc1nK/tXHiDhV55dvfzqtmP4S3sy3T3ouV2tkViZgxY/zeUkcpQcQPGRlgF4KmWzWW5oiWYSZwtCB+2RsE4Fw==", + "dev": true, + "dependencies": { + "jest-diff": "^25.2.1", + "pretty-format": "^25.2.1" + } + }, + "node_modules/jest-html-reporter/node_modules/@types/node": { + "version": "12.20.46", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.46.tgz", + "integrity": "sha512-cPjLXj8d6anFPzFvOPxS3fvly3Shm5nTfl6g8X5smexixbuGUf7hfr21J5tX9JW+UPStp/5P5R8qrKL5IyVJ+A==", + "dev": true + }, + "node_modules/jest-html-reporter/node_modules/@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", + "dev": true + }, + "node_modules/jest-html-reporter/node_modules/@types/yargs": { + "version": "15.0.14", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", + "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-html-reporter/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", @@ -7445,22 +7833,25 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-resolve/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "node_modules/jest-html-reporter/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/jest-resolve/node_modules/color-convert": { + "node_modules/jest-html-reporter/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", @@ -7472,26 +7863,40 @@ "node": ">=7.0.0" } }, - "node_modules/jest-resolve/node_modules/color-name": { + "node_modules/jest-html-reporter/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/jest-resolve/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "node_modules/jest-html-reporter/node_modules/dateformat": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.2.tgz", + "integrity": "sha1-mk30v/FYrC80vGN6vbFUcWB+Flk=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/jest-html-reporter/node_modules/diff-sequences": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", + "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", + "dev": true, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-html-reporter/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, "engines": { "node": ">=8" } }, - "node_modules/jest-resolve/node_modules/has-flag": { + "node_modules/jest-html-reporter/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", @@ -7500,209 +7905,174 @@ "node": ">=8" } }, - "node_modules/jest-resolve/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "node_modules/jest-html-reporter/node_modules/jest-diff": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", "dev": true, "dependencies": { - "p-locate": "^4.1.0" + "chalk": "^3.0.0", + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" }, "engines": { - "node": ">=8" + "node": ">= 8.3" } }, - "node_modules/jest-resolve/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/jest-html-reporter/node_modules/jest-get-type": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, "engines": { - "node": ">=6" + "node": ">= 8.3" } }, - "node_modules/jest-resolve/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "node_modules/jest-html-reporter/node_modules/jest-message-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", "dev": true, "dependencies": { - "p-limit": "^2.2.0" + "@babel/code-frame": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^1.0.1" }, "engines": { - "node": ">=8" - } - }, - "node_modules/jest-resolve/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" + "node": ">= 8.3" } }, - "node_modules/jest-resolve/node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "node_modules/jest-html-reporter/node_modules/jest-message-util/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/jest-resolve/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" + "node": ">= 8.3" } }, - "node_modules/jest-resolve/node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "node_modules/jest-html-reporter/node_modules/jest-message-util/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", "dev": true, "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "engines": { - "node": ">=8" + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" } }, - "node_modules/jest-resolve/node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "node_modules/jest-html-reporter/node_modules/jest-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", "dev": true, "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/jest-resolve/node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true, - "engines": { - "node": ">=8" + "node": ">= 8.3" } }, - "node_modules/jest-resolve/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/jest-html-reporter/node_modules/jest-util/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">= 8.3" } }, - "node_modules/jest-runner": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz", - "integrity": "sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==", + "node_modules/jest-html-reporter/node_modules/jest-util/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", "dev": true, "dependencies": { - "@jest/console": "^26.6.2", - "@jest/environment": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.7.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-config": "^26.6.3", - "jest-docblock": "^26.0.0", - "jest-haste-map": "^26.6.2", - "jest-leak-detector": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "jest-runtime": "^26.6.3", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "source-map-support": "^0.5.6", - "throat": "^5.0.0" - }, - "engines": { - "node": ">= 10.14.2" + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" } }, - "node_modules/jest-runner/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/jest-html-reporter/node_modules/pretty-format": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", "dev": true, "dependencies": { - "color-convert": "^2.0.1" + "@jest/types": "^25.5.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" }, "engines": { - "node": ">=8" + "node": ">= 8.3" } }, - "node_modules/jest-runner/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "node_modules/jest-html-reporter/node_modules/pretty-format/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" }, "engines": { - "node": ">=10" + "node": ">= 8.3" } }, - "node_modules/jest-runner/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/jest-html-reporter/node_modules/pretty-format/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", "dev": true, "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" } }, - "node_modules/jest-runner/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "node_modules/jest-html-reporter/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "dev": true }, - "node_modules/jest-runner/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/jest-html-reporter/node_modules/stack-utils": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.5.tgz", + "integrity": "sha512-KZiTzuV3CnSnSvgMRrARVCj+Ht7rMbauGDK0LdVFRGyenwdylpajAp4Q0i6SX8rEmbTpMMf6ryq2gb8pPq2WgQ==", "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, "engines": { "node": ">=8" } }, - "node_modules/jest-runner/node_modules/supports-color": { + "node_modules/jest-html-reporter/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", @@ -7714,48 +8084,35 @@ "node": ">=8" } }, - "node_modules/jest-runtime": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz", - "integrity": "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==", - "dev": true, - "dependencies": { - "@jest/console": "^26.6.2", - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/globals": "^26.6.2", - "@jest/source-map": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/yargs": "^15.0.0", + "node_modules/jest-jasmine2": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.4.6.tgz", + "integrity": "sha512-uAGNXF644I/whzhsf7/qf74gqy9OuhvJ0XYp8SDecX2ooGeaPnmJMjXjKt0mqh1Rl5dtRGxJgNrHlBQIBfS5Nw==", + "dev": true, + "dependencies": { + "@jest/environment": "^27.4.6", + "@jest/source-map": "^27.4.0", + "@jest/test-result": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/node": "*", "chalk": "^4.0.0", - "cjs-module-lexer": "^0.6.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.4", - "jest-config": "^26.6.3", - "jest-haste-map": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^15.4.1" - }, - "bin": { - "jest-runtime": "bin/jest-runtime.js" + "co": "^4.6.0", + "expect": "^27.4.6", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.4.6", + "jest-matcher-utils": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-runtime": "^27.4.6", + "jest-snapshot": "^27.4.6", + "jest-util": "^27.4.2", + "pretty-format": "^27.4.6", + "throat": "^6.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-runtime/node_modules/ansi-styles": { + "node_modules/jest-jasmine2/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", @@ -7765,12 +8122,15 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-runtime/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "node_modules/jest-jasmine2/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -7778,9 +8138,12 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-runtime/node_modules/color-convert": { + "node_modules/jest-jasmine2/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", @@ -7792,13 +8155,13 @@ "node": ">=7.0.0" } }, - "node_modules/jest-runtime/node_modules/color-name": { + "node_modules/jest-jasmine2/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/jest-runtime/node_modules/has-flag": { + "node_modules/jest-jasmine2/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", @@ -7807,16 +8170,7 @@ "node": ">=8" } }, - "node_modules/jest-runtime/node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runtime/node_modules/supports-color": { + "node_modules/jest-jasmine2/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", @@ -7828,47 +8182,35 @@ "node": ">=8" } }, - "node_modules/jest-serializer": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", - "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", + "node_modules/jest-leak-detector": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.4.6.tgz", + "integrity": "sha512-kkaGixDf9R7CjHm2pOzfTxZTQQQ2gHTIWKY/JZSiYTc90bZp8kSZnUMS3uLAfwTZwc0tcMRoEX74e14LG1WapA==", "dev": true, "dependencies": { - "@types/node": "*", - "graceful-fs": "^4.2.4" + "jest-get-type": "^27.4.0", + "pretty-format": "^27.4.6" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-snapshot": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", - "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", + "node_modules/jest-matcher-utils": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.4.6.tgz", + "integrity": "sha512-XD4PKT3Wn1LQnRAq7ZsTI0VRuEc9OrCPFiO1XL7bftTGmfNF0DcEwMHRgqiu7NGf8ZoZDREpGrCniDkjt79WbA==", "dev": true, "dependencies": { - "@babel/types": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.0.0", "chalk": "^4.0.0", - "expect": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-haste-map": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "natural-compare": "^1.4.0", - "pretty-format": "^26.6.2", - "semver": "^7.3.2" + "jest-diff": "^27.4.6", + "jest-get-type": "^27.4.0", + "pretty-format": "^27.4.6" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-snapshot/node_modules/ansi-styles": { + "node_modules/jest-matcher-utils/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", @@ -7878,12 +8220,15 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-snapshot/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "node_modules/jest-matcher-utils/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -7891,9 +8236,12 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-snapshot/node_modules/color-convert": { + "node_modules/jest-matcher-utils/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", @@ -7905,13 +8253,13 @@ "node": ">=7.0.0" } }, - "node_modules/jest-snapshot/node_modules/color-name": { + "node_modules/jest-matcher-utils/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/jest-snapshot/node_modules/has-flag": { + "node_modules/jest-matcher-utils/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", @@ -7920,22 +8268,7 @@ "node": ">=8" } }, - "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-snapshot/node_modules/supports-color": { + "node_modules/jest-matcher-utils/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", @@ -7947,24 +8280,27 @@ "node": ">=8" } }, - "node_modules/jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "node_modules/jest-message-util": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.4.6.tgz", + "integrity": "sha512-0p5szriFU0U74czRSFjH6RyS7UYIAkn/ntwMuOwTGWrQIOh5NzXXrq72LOqIkJKKvFbPq+byZKuBz78fjBERBA==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.4.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" + "micromatch": "^4.0.4", + "pretty-format": "^27.4.6", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-util/node_modules/ansi-styles": { + "node_modules/jest-message-util/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", @@ -7974,12 +8310,15 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-util/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "node_modules/jest-message-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -7987,9 +8326,12 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-util/node_modules/color-convert": { + "node_modules/jest-message-util/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", @@ -8001,13 +8343,13 @@ "node": ">=7.0.0" } }, - "node_modules/jest-util/node_modules/color-name": { + "node_modules/jest-message-util/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/jest-util/node_modules/has-flag": { + "node_modules/jest-message-util/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", @@ -8016,7 +8358,7 @@ "node": ">=8" } }, - "node_modules/jest-util/node_modules/supports-color": { + "node_modules/jest-message-util/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", @@ -8028,48 +8370,99 @@ "node": ">=8" } }, - "node_modules/jest-validate": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", - "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", + "node_modules/jest-mock": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.4.6.tgz", + "integrity": "sha512-kvojdYRkst8iVSZ1EJ+vc1RRD9llueBjKzXzeCytH3dMM7zvPV/ULcfI2nr0v0VUgm3Bjt3hBCQvOeaBz+ZTHw==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "camelcase": "^6.0.0", - "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", - "leven": "^3.1.0", - "pretty-format": "^26.6.2" + "@jest/types": "^27.4.2", + "@types/node": "*" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-validate/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" + "node_modules/jest-pnp-resolver": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "dev": true, + "engines": { + "node": ">=6" }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.4.0.tgz", + "integrity": "sha512-WeCpMpNnqJYMQoOjm1nTtsgbR4XHAk1u00qDoNBQoykM280+/TmgA5Qh5giC1ecy6a5d4hbSsHzpBtu5yvlbEg==", + "dev": true, "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "node_modules/jest-resolve": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.4.6.tgz", + "integrity": "sha512-SFfITVApqtirbITKFAO7jOVN45UgFzcRdQanOFzjnbd+CACDoyeX7206JyU92l4cRr73+Qy/TlW51+4vHGt+zw==", "dev": true, + "dependencies": { + "@jest/types": "^27.4.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.4.6", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.6", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", + "slash": "^3.0.0" + }, "engines": { - "node": ">=10" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-validate/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "node_modules/jest-resolve-dependencies": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.4.6.tgz", + "integrity": "sha512-W85uJZcFXEVZ7+MZqIPCscdjuctruNGXUZ3OHSXOfXR9ITgbUKeHj+uGcies+0SsvI5GtUfTw4dY7u9qjTvQOw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.4.2", + "jest-regex-util": "^27.4.0", + "jest-snapshot": "^27.4.6" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-resolve/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -8077,9 +8470,12 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-validate/node_modules/color-convert": { + "node_modules/jest-resolve/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", @@ -8091,13 +8487,13 @@ "node": ">=7.0.0" } }, - "node_modules/jest-validate/node_modules/color-name": { + "node_modules/jest-resolve/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/jest-validate/node_modules/has-flag": { + "node_modules/jest-resolve/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", @@ -8106,7 +8502,7 @@ "node": ">=8" } }, - "node_modules/jest-validate/node_modules/supports-color": { + "node_modules/jest-resolve/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", @@ -8118,25 +8514,40 @@ "node": ">=8" } }, - "node_modules/jest-watcher": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz", - "integrity": "sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==", + "node_modules/jest-runner": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.4.6.tgz", + "integrity": "sha512-IDeFt2SG4DzqalYBZRgbbPmpwV3X0DcntjezPBERvnhwKGWTW7C5pbbA5lVkmvgteeNfdd/23gwqv3aiilpYPg==", "dev": true, "dependencies": { - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/console": "^27.4.6", + "@jest/environment": "^27.4.6", + "@jest/test-result": "^27.4.6", + "@jest/transform": "^27.4.6", + "@jest/types": "^27.4.2", "@types/node": "*", - "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "jest-util": "^26.6.2", - "string-length": "^4.0.1" + "emittery": "^0.8.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-docblock": "^27.4.0", + "jest-environment-jsdom": "^27.4.6", + "jest-environment-node": "^27.4.6", + "jest-haste-map": "^27.4.6", + "jest-leak-detector": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-resolve": "^27.4.6", + "jest-runtime": "^27.4.6", + "jest-util": "^27.4.2", + "jest-worker": "^27.4.6", + "source-map-support": "^0.5.6", + "throat": "^6.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-watcher/node_modules/ansi-styles": { + "node_modules/jest-runner/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", @@ -8146,12 +8557,15 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-watcher/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "node_modules/jest-runner/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -8159,9 +8573,12 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-watcher/node_modules/color-convert": { + "node_modules/jest-runner/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", @@ -8173,13 +8590,13 @@ "node": ">=7.0.0" } }, - "node_modules/jest-watcher/node_modules/color-name": { + "node_modules/jest-runner/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/jest-watcher/node_modules/has-flag": { + "node_modules/jest-runner/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", @@ -8188,7 +8605,7 @@ "node": ">=8" } }, - "node_modules/jest-watcher/node_modules/supports-color": { + "node_modules/jest-runner/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", @@ -8200,21 +8617,89 @@ "node": ">=8" } }, - "node_modules/jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "node_modules/jest-runtime": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.4.6.tgz", + "integrity": "sha512-eXYeoR/MbIpVDrjqy5d6cGCFOYBFFDeKaNWqTp0h6E74dK0zLHzASQXJpl5a2/40euBmKnprNLJ0Kh0LCndnWQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^27.4.6", + "@jest/fake-timers": "^27.4.6", + "@jest/globals": "^27.4.6", + "@jest/source-map": "^27.4.0", + "@jest/test-result": "^27.4.6", + "@jest/transform": "^27.4.6", + "@jest/types": "^27.4.2", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-mock": "^27.4.6", + "jest-regex-util": "^27.4.0", + "jest-resolve": "^27.4.6", + "jest-snapshot": "^27.4.6", + "jest-util": "^27.4.2", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runtime/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">= 10.13.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-worker/node_modules/has-flag": { + "node_modules/jest-runtime/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-runtime/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-runtime/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-runtime/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", @@ -8223,7 +8708,16 @@ "node": ">=8" } }, - "node_modules/jest-worker/node_modules/supports-color": { + "node_modules/jest-runtime/node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", @@ -8235,7 +8729,53 @@ "node": ">=8" } }, - "node_modules/jest/node_modules/ansi-styles": { + "node_modules/jest-serializer": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.4.0.tgz", + "integrity": "sha512-RDhpcn5f1JYTX2pvJAGDcnsNTnsV9bjYPU8xcV+xPwOXnUPOQwf4ZEuiU6G9H1UztH+OapMgu/ckEVwO87PwnQ==", + "dev": true, + "dependencies": { + "@types/node": "*", + "graceful-fs": "^4.2.4" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.4.6.tgz", + "integrity": "sha512-fafUCDLQfzuNP9IRcEqaFAMzEe7u5BF7mude51wyWv7VRex60WznZIC7DfKTgSIlJa8aFzYmXclmN328aqSDmQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.7.2", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.0.0", + "@jest/transform": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^27.4.6", + "graceful-fs": "^4.2.4", + "jest-diff": "^27.4.6", + "jest-get-type": "^27.4.0", + "jest-haste-map": "^27.4.6", + "jest-matcher-utils": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-util": "^27.4.2", + "natural-compare": "^1.4.0", + "pretty-format": "^27.4.6", + "semver": "^7.3.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", @@ -8245,12 +8785,15 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "node_modules/jest-snapshot/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -8258,9 +8801,12 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest/node_modules/color-convert": { + "node_modules/jest-snapshot/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", @@ -8272,13 +8818,13 @@ "node": ">=7.0.0" } }, - "node_modules/jest/node_modules/color-name": { + "node_modules/jest-snapshot/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/jest/node_modules/has-flag": { + "node_modules/jest-snapshot/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", @@ -8287,34 +8833,22 @@ "node": ">=8" } }, - "node_modules/jest/node_modules/jest-cli": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz", - "integrity": "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==", + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, "dependencies": { - "@jest/core": "^26.6.3", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "import-local": "^3.0.2", - "is-ci": "^2.0.0", - "jest-config": "^26.6.3", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "prompts": "^2.0.1", - "yargs": "^15.4.1" + "lru-cache": "^6.0.0" }, "bin": { - "jest": "bin/jest.js" + "semver": "bin/semver.js" }, "engines": { - "node": ">= 10.14.2" + "node": ">=10" } }, - "node_modules/jest/node_modules/supports-color": { + "node_modules/jest-snapshot/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", @@ -8326,52 +8860,365 @@ "node": ">=8" } }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "node_modules/jest-util": { + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.4.2.tgz", + "integrity": "sha512-YuxxpXU6nlMan9qyLuxHaMMOzXAl5aGZWCSzben5DhLHemYQxCc4YK+4L3ZrCutT8GPQ+ui9k5D8rUJoDioMnA==", "dev": true, "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "@jest/types": "^27.4.2", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.4", + "picomatch": "^2.2.3" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true + "node_modules/jest-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } }, - "node_modules/jsdom": { - "version": "16.5.3", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.5.3.tgz", - "integrity": "sha512-Qj1H+PEvUsOtdPJ056ewXM4UJPCi4hhLA8wpiz9F2YvsRBhuFsXxtrIFAgGBDynQA9isAMGE91PfUYbdMPXuTA==", + "node_modules/jest-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { - "abab": "^2.0.5", - "acorn": "^8.1.0", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-util/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-util/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-util/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-util/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-validate": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.4.6.tgz", + "integrity": "sha512-872mEmCPVlBqbA5dToC57vA3yJaMRfIdpCoD3cyHWJOMx+SJwLNw0I71EkWs41oza/Er9Zno9XuTkRYCPDUJXQ==", + "dev": true, + "dependencies": { + "@jest/types": "^27.4.2", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^27.4.0", + "leven": "^3.1.0", + "pretty-format": "^27.4.6" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-validate/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-validate/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-validate/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-validate/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-validate/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watcher": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.4.6.tgz", + "integrity": "sha512-yKQ20OMBiCDigbD0quhQKLkBO+ObGN79MO4nT7YaCuQ5SM+dkBNWE8cZX0FjU6czwMvWw6StWbe+Wv4jJPJ+fw==", + "dev": true, + "dependencies": { + "@jest/test-result": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^27.4.2", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-watcher/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-watcher/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-watcher/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-watcher/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-watcher/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watcher/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.6.tgz", + "integrity": "sha512-gHWJF/6Xi5CTG5QCvROr6GcmpIqNYpDJyc8A1h/DyXqH1tD6SnRCM0d3U5msV31D2LB/U+E0M+W4oyvKV44oNw==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "node_modules/jsdom": { + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", + "dev": true, + "dependencies": { + "abab": "^2.0.5", + "acorn": "^8.2.4", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.3.0", + "data-urls": "^2.0.0", "decimal.js": "^10.2.1", "domexception": "^2.0.1", "escodegen": "^2.0.0", + "form-data": "^3.0.0", "html-encoding-sniffer": "^2.0.1", - "is-potential-custom-element-name": "^1.0.0", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", "nwsapi": "^2.2.0", "parse5": "6.0.1", - "request": "^2.88.2", - "request-promise-native": "^1.0.9", "saxes": "^5.0.1", "symbol-tree": "^3.2.4", "tough-cookie": "^4.0.0", @@ -8381,17 +9228,25 @@ "whatwg-encoding": "^1.0.5", "whatwg-mimetype": "^2.3.0", "whatwg-url": "^8.5.0", - "ws": "^7.4.4", + "ws": "^7.4.6", "xml-name-validator": "^3.0.0" }, "engines": { "node": ">=10" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } } }, "node_modules/jsdom/node_modules/acorn": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.2.4.tgz", - "integrity": "sha512-Ibt84YwBDDA890eDiDCEqcbwvHlBvzzDkU2cGBBDDI1QWT12jTiXIOn2CIw5KK4i6N5Z2HUxwYjzriDyqaqqZg==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -8400,6 +9255,20 @@ "node": ">=0.4.0" } }, + "node_modules/jsdom/node_modules/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -8412,12 +9281,6 @@ "node": ">=4" } }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, "node_modules/json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", @@ -8425,9 +9288,9 @@ "dev": true }, "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, "node_modules/json-stable-stringify-without-jsonify": { @@ -8497,6 +9360,12 @@ "verror": "1.10.0" } }, + "node_modules/just-extend": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", + "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", + "dev": true + }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -8581,12 +9450,6 @@ "node": ">= 8" } }, - "node_modules/lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", - "dev": true - }, "node_modules/linkify-it": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.2.tgz", @@ -8669,6 +9532,12 @@ "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", "dev": true }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, "node_modules/lodash.memoize": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", @@ -8703,6 +9572,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/make-iterator": { @@ -8718,12 +9590,12 @@ } }, "node_modules/makeerror": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", - "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", "dev": true, "dependencies": { - "tmpl": "1.0.x" + "tmpl": "1.0.5" } }, "node_modules/map-cache": { @@ -8735,18 +9607,6 @@ "node": ">=0.10.0" } }, - "node_modules/map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "dependencies": { - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/markdown-it": { "version": "12.2.0", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.2.0.tgz", @@ -8825,21 +9685,21 @@ "dev": true }, "node_modules/mime-db": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", - "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==", + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { - "version": "2.1.30", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", - "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", "dev": true, "dependencies": { - "mime-db": "1.47.0" + "mime-db": "1.51.0" }, "engines": { "node": ">= 0.6" @@ -8884,31 +9744,6 @@ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, - "node_modules/mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "dependencies": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mixin-deep/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -8978,61 +9813,89 @@ "node": ">=8" } }, - "node_modules/nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/nise": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/nise/-/nise-4.1.0.tgz", + "integrity": "sha512-eQMEmGN/8arp0xsvGoQ+B1qvSkR73B1nWSCh7nOt5neMCtwcQVYQGdzQMhcNscktTsWB54xnlSQFzOAPJD8nXA==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0", + "@sinonjs/fake-timers": "^6.0.0", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "path-to-regexp": "^1.7.0" + } + }, + "node_modules/nise/node_modules/@sinonjs/fake-timers": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", "dev": true, "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" }, "engines": { - "node": ">=0.10.0" + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } } }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "node_modules/node-fetch/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", "dev": true }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "node_modules/node-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", "dev": true }, + "node_modules/node-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", "dev": true }, - "node_modules/node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/node-notifier": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.2.tgz", - "integrity": "sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-9.0.0.tgz", + "integrity": "sha512-SkwNwGnMMlSPrcoeH4CSo9XyWe72acAHEJGDdPdB+CyBVHsIYaTQ4U/1wk3URsyzC75xZLg2vzU2YaALlqDF1Q==", "dev": true, "optional": true, + "peer": true, "dependencies": { "growly": "^1.3.0", "is-wsl": "^2.2.0", @@ -9048,6 +9911,7 @@ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, "optional": true, + "peer": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -9059,9 +9923,9 @@ } }, "node_modules/node-releases": { - "version": "1.1.71", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", - "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", + "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==", "dev": true }, "node_modules/nopt": { @@ -9107,24 +9971,15 @@ } }, "node_modules/npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, "dependencies": { - "path-key": "^2.0.0" + "path-key": "^3.0.0" }, "engines": { - "node": ">=4" - } - }, - "node_modules/npm-run-path/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true, - "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/nwsapi": { @@ -9151,44 +10006,6 @@ "node": ">=0.10.0" } }, - "node_modules/object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "dependencies": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object-inspect": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.2.tgz", @@ -9204,18 +10021,6 @@ "node": ">= 0.4" } }, - "node_modules/object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "dependencies": { - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object.assign": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", @@ -9305,6 +10110,9 @@ }, "engines": { "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/optionator": { @@ -9367,24 +10175,6 @@ "shell-quote": "^1.4.2" } }, - "node_modules/p-each-series": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz", - "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/p-limit": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", @@ -9499,15 +10289,6 @@ "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", "dev": true }, - "node_modules/pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/path-browserify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", @@ -9577,6 +10358,21 @@ "node": ">=0.10.0" } }, + "node_modules/path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dev": true, + "dependencies": { + "isarray": "0.0.1" + } + }, + "node_modules/path-to-regexp/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, "node_modules/path-type": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", @@ -9605,12 +10401,24 @@ "node": ">=0.12" } }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, "node_modules/picomatch": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", @@ -9630,13 +10438,10 @@ } }, "node_modules/pirates": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", - "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.4.tgz", + "integrity": "sha512-ZIrVPH+A52Dw84R0L3/VS9Op04PuQ2SEoJL6bkshmiTic/HldyW9Tf7oH5mhJZBK7NmDx27vSMrYEXPXclpDKw==", "dev": true, - "dependencies": { - "node-modules-regexp": "^1.0.0" - }, "engines": { "node": ">= 6" } @@ -9723,15 +10528,6 @@ "node": ">=6" } }, - "node_modules/posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -9742,50 +10538,31 @@ } }, "node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.6.tgz", + "integrity": "sha512-NblstegA1y/RJW2VyML+3LlpFjzx62cUrtBIKIWDXEDkjNeleA7Od7nrzcs/VLQvAeV4CgSYhrN39DRN88Qi/g==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", "react-is": "^17.0.1" }, "engines": { - "node": ">= 10" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, "engines": { - "node": ">=8" - } - }, - "node_modules/pretty-format/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" + "node": ">=10" }, - "engines": { - "node": ">=7.0.0" + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/pretty-format/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -9807,65 +10584,208 @@ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true, "engines": { - "node": ">=0.4.0" + "node": ">=0.4.0" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, + "node_modules/psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "node_modules/public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/public-encrypt/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/puppeteer": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-13.1.2.tgz", + "integrity": "sha512-ozVM8Tdg0patMtm/xAr3Uh7rQ28vBpbTHLP+ECmoAxG/s4PKrVLN764H/poLux7Ln77jHThOd8OBJj5mTuA6Iw==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "debug": "4.3.2", + "devtools-protocol": "0.0.948846", + "extract-zip": "2.0.1", + "https-proxy-agent": "5.0.0", + "node-fetch": "2.6.7", + "pkg-dir": "4.2.0", + "progress": "2.0.3", + "proxy-from-env": "1.1.0", + "rimraf": "3.0.2", + "tar-fs": "2.1.1", + "unbzip2-stream": "1.4.3", + "ws": "8.2.3" + }, + "engines": { + "node": ">=10.18.1" + } + }, + "node_modules/puppeteer/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/puppeteer/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/puppeteer/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/puppeteer/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/puppeteer/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" } }, - "node_modules/prompts": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.1.tgz", - "integrity": "sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ==", + "node_modules/puppeteer/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, "engines": { - "node": ">= 6" + "node": ">=8" } }, - "node_modules/psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true - }, - "node_modules/public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "node_modules/puppeteer/node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, "dependencies": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/public-encrypt/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "node_modules/puppeteer/node_modules/ws": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", + "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, - "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "node_modules/pure-rand": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-5.0.0.tgz", + "integrity": "sha512-lD2/y78q+7HqBx2SaT6OT4UcwtvXNRfEpzYEzl0EQ+9gZq2Qi3fa0HDnYPeqQwhlHJFBUhT7AO3mLU3+8bynHA==", "dev": true, - "engines": { - "node": ">=6" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" } }, "node_modules/qs": { @@ -10039,21 +10959,21 @@ "dev": true }, "node_modules/regenerate-unicode-properties": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz", - "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz", + "integrity": "sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw==", "dev": true, "dependencies": { - "regenerate": "^1.4.0" + "regenerate": "^1.4.2" }, "engines": { "node": ">=4" } }, "node_modules/regenerator-runtime": { - "version": "0.13.7", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", - "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", "dev": true }, "node_modules/regenerator-transform": { @@ -10065,55 +10985,45 @@ "@babel/runtime": "^7.8.4" } }, - "node_modules/regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "dependencies": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" } }, "node_modules/regexpu-core": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.1.tgz", - "integrity": "sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.0.1.tgz", + "integrity": "sha512-CriEZlrKK9VJw/xQGJpQM5rY88BtuL8DM+AEwvcThHilbxiTAy8vq4iJnd2tqq8wLmjbGZzP7ZcKFjbGkmEFrw==", "dev": true, "dependencies": { - "regenerate": "^1.4.0", - "regenerate-unicode-properties": "^8.2.0", - "regjsgen": "^0.5.1", - "regjsparser": "^0.6.4", - "unicode-match-property-ecmascript": "^1.0.4", - "unicode-match-property-value-ecmascript": "^1.2.0" + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.0.1", + "regjsgen": "^0.6.0", + "regjsparser": "^0.8.2", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.0.0" }, "engines": { "node": ">=4" } }, "node_modules/regjsgen": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", - "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.6.0.tgz", + "integrity": "sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA==", "dev": true }, "node_modules/regjsparser": { - "version": "0.6.9", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.9.tgz", - "integrity": "sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ==", + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.8.4.tgz", + "integrity": "sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA==", "dev": true, "dependencies": { "jsesc": "~0.5.0" @@ -10131,30 +11041,6 @@ "jsesc": "bin/jsesc" } }, - "node_modules/remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "node_modules/repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, "node_modules/request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", @@ -10186,45 +11072,6 @@ "node": ">= 6" } }, - "node_modules/request-promise-core": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", - "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", - "dev": true, - "dependencies": { - "lodash": "^4.17.19" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/request-promise-native": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", - "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", - "dev": true, - "dependencies": { - "request-promise-core": "1.1.4", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - }, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/request-promise-native/node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/request/node_modules/qs": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", @@ -10274,12 +11121,6 @@ "node": ">=0.10.0" } }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, "node_modules/resolve": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", @@ -10302,297 +11143,107 @@ "node": ">=8" } }, - "node_modules/resolve-cwd/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", - "dev": true, - "dependencies": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg/-/resolve-pkg-2.0.0.tgz", - "integrity": "sha512-+1lzwXehGCXSeryaISr6WujZzowloigEofRB+dj75y9RRa/obVcYgbHJd53tdYw8pvZj8GojXaaENws8Ktw/hQ==", - "dev": true, - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-pkg/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "node_modules/ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "node_modules/rsvp": { - "version": "4.8.5", - "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", - "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", - "dev": true, - "engines": { - "node": "6.* || >= 7.*" - } - }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/safe-json-parse": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-1.0.1.tgz", - "integrity": "sha1-PnZyPjjf3aE8mx0poeB//uSzC1c=", - "dev": true - }, - "node_modules/safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "dependencies": { - "ret": "~0.1.10" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "node_modules/sane": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", - "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", - "dev": true, - "dependencies": { - "@cnakazawa/watch": "^1.0.3", - "anymatch": "^2.0.0", - "capture-exit": "^2.0.0", - "exec-sh": "^0.3.2", - "execa": "^1.0.0", - "fb-watchman": "^2.0.0", - "micromatch": "^3.1.4", - "minimist": "^1.1.1", - "walker": "~1.0.5" - }, - "bin": { - "sane": "src/cli.js" - }, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/sane/node_modules/anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "dependencies": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "node_modules/sane/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/sane/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "node_modules/resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", "dev": true, "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/sane/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/sane/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "node_modules/resolve-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg/-/resolve-pkg-2.0.0.tgz", + "integrity": "sha512-+1lzwXehGCXSeryaISr6WujZzowloigEofRB+dj75y9RRa/obVcYgbHJd53tdYw8pvZj8GojXaaENws8Ktw/hQ==", "dev": true, "dependencies": { - "kind-of": "^3.0.2" + "resolve-from": "^5.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/sane/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "node_modules/resolve-pkg/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/sane/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "node_modules/resolve.exports": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", + "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, - "node_modules/sane/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "dependencies": { - "remove-trailing-separator": "^1.0.1" + "glob": "^7.1.3" }, - "engines": { - "node": ">=0.10.0" + "bin": { + "rimraf": "bin.js" } }, - "node_modules/sane/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", "dev": true, "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" + "hash-base": "^3.0.0", + "inherits": "^2.0.1" } }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/safe-json-parse": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-1.0.1.tgz", + "integrity": "sha1-PnZyPjjf3aE8mx0poeB//uSzC1c=", + "dev": true + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, "node_modules/saxes": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", @@ -10605,6 +11256,11 @@ "node": ">=10" } }, + "node_modules/seedrandom": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", + "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==" + }, "node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -10614,39 +11270,6 @@ "semver": "bin/semver.js" } }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "node_modules/set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/set-value/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/sha.js": { "version": "2.4.11", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", @@ -10691,9 +11314,9 @@ } }, "node_modules/shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz", + "integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==", "dev": true }, "node_modules/shellwords": { @@ -10701,7 +11324,8 @@ "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", "dev": true, - "optional": true + "optional": true, + "peer": true }, "node_modules/side-channel": { "version": "1.0.4", @@ -10715,9 +11339,9 @@ } }, "node_modules/signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", + "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", "dev": true }, "node_modules/simple-concat": { @@ -10726,12 +11350,68 @@ "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", "dev": true }, + "node_modules/sinon": { + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", + "integrity": "sha512-zljcULZQsJxVra28qIAL6ow1Z9tpattkCTEJR4RBP3TGc00FcttsP5pK284Nas5WjMZU5Yzy3kAIp3B3KRf5Yg==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.8.1", + "@sinonjs/fake-timers": "^6.0.1", + "@sinonjs/samsam": "^5.3.1", + "diff": "^4.0.2", + "nise": "^4.0.4", + "supports-color": "^7.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/sinon" + } + }, + "node_modules/sinon/node_modules/@sinonjs/fake-timers": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/sinon/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/sinon/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", "dev": true }, + "node_modules/sjcl": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/sjcl/-/sjcl-1.0.8.tgz", + "integrity": "sha512-LzIjEQ0S0DpIgnxMEayM1rq9aGwGRG4OnZhCdjx7glTaJtf4zRfpg87ImfjSJjoW9vKpagd82McDOwbRT5kQKQ==", + "engines": { + "node": "*" + } + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -10785,152 +11465,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "dependencies": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "dependencies": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "dependencies": { - "kind-of": "^3.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/snapdragon/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, "node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -10940,23 +11474,10 @@ "node": ">=0.10.0" } }, - "node_modules/source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, "node_modules/source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, "dependencies": { "buffer-from": "^1.0.0", @@ -10972,12 +11493,6 @@ "node": ">=0.10.0" } }, - "node_modules/source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "dev": true - }, "node_modules/spdx-correct": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", @@ -11010,18 +11525,6 @@ "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==", "dev": true }, - "node_modules/split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "dependencies": { - "extend-shallow": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -11054,9 +11557,9 @@ } }, "node_modules/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", + "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" @@ -11074,40 +11577,6 @@ "node": ">=8" } }, - "node_modules/static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "dependencies": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/stream-browserify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", @@ -11213,14 +11682,14 @@ "dev": true }, "node_modules/string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" + "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8" @@ -11247,12 +11716,12 @@ } }, "node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "dependencies": { - "ansi-regex": "^5.0.0" + "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" @@ -11267,15 +11736,6 @@ "node": ">=4" } }, - "node_modules/strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", @@ -11382,23 +11842,47 @@ "node": ">=10.0.0" } }, - "node_modules/table/node_modules/ajv": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.2.0.tgz", - "integrity": "sha512-WSNGFuyWd//XO8n/m/EaOlNLtO0yL8EXT/74LqT4khdhpZjP7lkj/kT5uwRmGitKEVp/Oj7ZUHeGfPtgHhQ5CA==", + "node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", "dev": true, "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" } }, - "node_modules/table/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar-stream/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } }, "node_modules/terminal-link": { "version": "2.1.1", @@ -11411,6 +11895,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/test-exclude": { @@ -11434,9 +11921,9 @@ "dev": true }, "node_modules/throat": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", - "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", + "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", "dev": true }, "node_modules/through": { @@ -11491,9 +11978,9 @@ } }, "node_modules/tmpl": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", - "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", "dev": true }, "node_modules/to-fast-properties": { @@ -11505,45 +11992,6 @@ "node": ">=4" } }, - "node_modules/to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-object-path/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "dependencies": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -11571,9 +12019,9 @@ } }, "node_modules/tr46": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz", - "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", "dev": true, "dependencies": { "punycode": "^2.1.1" @@ -11675,6 +12123,19 @@ "is-typedarray": "^1.0.0" } }, + "node_modules/typescript": { + "version": "4.5.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz", + "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, "node_modules/uc.micro": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", @@ -11702,6 +12163,16 @@ "which-boxed-primitive": "^1.0.2" } }, + "node_modules/unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "dev": true, + "dependencies": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, "node_modules/unc-path-regex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", @@ -11741,60 +12212,45 @@ } }, "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", - "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", "dev": true, "engines": { "node": ">=4" } }, "node_modules/unicode-match-property-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", - "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", "dev": true, "dependencies": { - "unicode-canonical-property-names-ecmascript": "^1.0.4", - "unicode-property-aliases-ecmascript": "^1.0.4" + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" }, "engines": { "node": ">=4" } }, "node_modules/unicode-match-property-value-ecmascript": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz", - "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", + "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==", "dev": true, "engines": { "node": ">=4" } }, "node_modules/unicode-property-aliases-ecmascript": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz", - "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz", + "integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==", "dev": true, "engines": { "node": ">=4" } }, - "node_modules/union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "dependencies": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -11804,54 +12260,6 @@ "node": ">= 4.0.0" } }, - "node_modules/unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "dependencies": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "dependencies": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "dependencies": { - "isarray": "1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -11861,12 +12269,6 @@ "punycode": "^2.1.0" } }, - "node_modules/urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, "node_modules/url": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", @@ -11883,15 +12285,6 @@ "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", "dev": true }, - "node_modules/use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/util": { "version": "0.12.3", "resolved": "https://registry.npmjs.org/util/-/util-0.12.3.tgz", @@ -11918,6 +12311,7 @@ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true, "optional": true, + "peer": true, "bin": { "uuid": "dist/bin/uuid" } @@ -11929,9 +12323,9 @@ "dev": true }, "node_modules/v8-to-istanbul": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.2.tgz", - "integrity": "sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", + "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.1", @@ -11939,7 +12333,7 @@ "source-map": "^0.7.3" }, "engines": { - "node": ">=10.10.0" + "node": ">=10.12.0" } }, "node_modules/v8-to-istanbul/node_modules/source-map": { @@ -12015,12 +12409,12 @@ } }, "node_modules/walker": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", - "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", "dev": true, "dependencies": { - "makeerror": "1.0.x" + "makeerror": "1.0.12" } }, "node_modules/watchify": { @@ -12115,13 +12509,13 @@ "dev": true }, "node_modules/whatwg-url": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.5.0.tgz", - "integrity": "sha512-fy+R77xWv0AiqfLl4nuGUlQ3/6b5uNfQ4WAbGQVMYshCTCCPK9psC1nWh3XHuxGVCtlcDDQPQW1csmmIQo+fwg==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", "dev": true, "dependencies": { "lodash": "^4.7.0", - "tr46": "^2.0.2", + "tr46": "^2.1.0", "webidl-conversions": "^6.1.0" }, "engines": { @@ -12156,12 +12550,6 @@ "is-symbol": "^1.0.3" } }, - "node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, "node_modules/which-typed-array": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz", @@ -12190,9 +12578,9 @@ } }, "node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "dependencies": { "ansi-styles": "^4.0.0", @@ -12200,7 +12588,10 @@ "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/wrap-ansi/node_modules/ansi-styles": { @@ -12213,6 +12604,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/wrap-ansi/node_modules/color-convert": { @@ -12252,12 +12646,24 @@ } }, "node_modules/ws": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", - "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==", + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz", + "integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==", "dev": true, "engines": { "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, "node_modules/xml-name-validator": { @@ -12266,6 +12672,15 @@ "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", "dev": true }, + "node_modules/xmlbuilder": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.0.0.tgz", + "integrity": "sha512-KLu/G0DoWhkncQ9eHSI6s0/w+T4TM7rQaLhtCaL6tORv8jFlJPlnGumsgTcGfYeS1qZ/IHqrvDG7zJZ4d7e+nw==", + "dev": true, + "engines": { + "node": ">=8.0" + } + }, "node_modules/xmlchars": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", @@ -12282,10 +12697,13 @@ } }, "node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } }, "node_modules/yallist": { "version": "4.0.0", @@ -12294,227 +12712,181 @@ "dev": true }, "node_modules/yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" }, "engines": { - "node": ">=8" + "node": ">=10" } }, "node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, "engines": { - "node": ">=6" + "node": ">=10" } }, - "node_modules/yargs/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", "dev": true, "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" } } }, "dependencies": { + "@ampproject/remapping": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.2.tgz", + "integrity": "sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.0" + } + }, "@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", "dev": true, "requires": { - "@babel/highlight": "^7.12.13" + "@babel/highlight": "^7.16.7" } }, "@babel/compat-data": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.13.15.tgz", - "integrity": "sha512-ltnibHKR1VnrU4ymHyQ/CXtNXI6yZC0oJThyW78Hft8XndANwi+9H+UIklBDraIjFEJzw8wmcM427oDd9KS5wA==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.0.tgz", + "integrity": "sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng==", "dev": true }, "@babel/core": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.16.tgz", - "integrity": "sha512-sXHpixBiWWFti0AV2Zq7avpTasr6sIAu7Y396c608541qAU2ui4a193m0KSQmfPSKFZLnQ3cvlKDOm3XkuXm3Q==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.16", - "@babel/helper-compilation-targets": "^7.13.16", - "@babel/helper-module-transforms": "^7.13.14", - "@babel/helpers": "^7.13.16", - "@babel/parser": "^7.13.16", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.15", - "@babel/types": "^7.13.16", + "version": "7.17.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.5.tgz", + "integrity": "sha512-/BBMw4EvjmyquN5O+t5eh0+YqB3XXJkYD2cjKpYtWOfFy4lQ4UozNSmxAcWT8r2XtZs0ewG+zrfsqeR15i1ajA==", + "dev": true, + "requires": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.3", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helpers": "^7.17.2", + "@babel/parser": "^7.17.3", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.3", + "@babel/types": "^7.17.0", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.1.2", - "semver": "^6.3.0", - "source-map": "^0.5.0" + "semver": "^6.3.0" } }, "@babel/eslint-parser": { - "version": "7.13.14", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.13.14.tgz", - "integrity": "sha512-I0HweR36D73Ibn/FfrRDMKlMqJHFwidIUgYdMpH+aXYuQC+waq59YaJ6t9e9N36axJ82v1jR041wwqDrDXEwRA==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.17.0.tgz", + "integrity": "sha512-PUEJ7ZBXbRkbq3qqM/jZ2nIuakUBqCYc7Qf52Lj7dlZ6zERnqisdHioL0l4wwQZnmskMeasqUNzLBFKs3nylXA==", "dev": true, "requires": { - "eslint-scope": "^5.1.0", - "eslint-visitor-keys": "^1.3.0", + "eslint-scope": "^5.1.1", + "eslint-visitor-keys": "^2.1.0", "semver": "^6.3.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + } } }, "@babel/generator": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.16.tgz", - "integrity": "sha512-grBBR75UnKOcUWMp8WoDxNsWCFl//XCK6HWTrBQKTr5SV9f5g0pNOjdyzi/DTBv12S9GnYPInIXQBTky7OXEMg==", + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.3.tgz", + "integrity": "sha512-+R6Dctil/MgUsZsZAkYgK+ADNSZzJRRy0TvY65T71z/CR854xHQ1EweBYXdfT+HNeN7w0cSJJEzgxZMv40pxsg==", "dev": true, "requires": { - "@babel/types": "^7.13.16", + "@babel/types": "^7.17.0", "jsesc": "^2.5.1", "source-map": "^0.5.0" } }, "@babel/helper-annotate-as-pure": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz", - "integrity": "sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz", + "integrity": "sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==", "dev": true, "requires": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.16.7" } }, "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.12.13.tgz", - "integrity": "sha512-CZOv9tGphhDRlVjVkAgm8Nhklm9RzSmWpX2my+t7Ua/KT616pEzXsQCjinzvkRvHWJ9itO4f296efroX23XCMA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.7.tgz", + "integrity": "sha512-C6FdbRaxYjwVu/geKW4ZeQ0Q31AftgRcdSnZ5/jsH6BzCJbtvXvhpfkbkThYSuutZA7nCXpPR6AD9zd1dprMkA==", "dev": true, "requires": { - "@babel/helper-explode-assignable-expression": "^7.12.13", - "@babel/types": "^7.12.13" + "@babel/helper-explode-assignable-expression": "^7.16.7", + "@babel/types": "^7.16.7" } }, "@babel/helper-compilation-targets": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz", - "integrity": "sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", + "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==", "dev": true, "requires": { - "@babel/compat-data": "^7.13.15", - "@babel/helper-validator-option": "^7.12.17", - "browserslist": "^4.14.5", + "@babel/compat-data": "^7.16.4", + "@babel/helper-validator-option": "^7.16.7", + "browserslist": "^4.17.5", "semver": "^6.3.0" } }, "@babel/helper-create-class-features-plugin": { - "version": "7.13.11", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.13.11.tgz", - "integrity": "sha512-ays0I7XYq9xbjCSvT+EvysLgfc3tOkwCULHjrnscGT3A9qD4sk3wXnJ3of0MAWsWGjdinFvajHU2smYuqXKMrw==", + "version": "7.17.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.6.tgz", + "integrity": "sha512-SogLLSxXm2OkBbSsHZMM4tUi8fUzjs63AT/d0YQIzr6GSd8Hxsbk2KYDX0k0DweAzGMj/YWeiCsorIdtdcW8Eg==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.12.13", - "@babel/helper-member-expression-to-functions": "^7.13.0", - "@babel/helper-optimise-call-expression": "^7.12.13", - "@babel/helper-replace-supers": "^7.13.0", - "@babel/helper-split-export-declaration": "^7.12.13" + "@babel/helper-annotate-as-pure": "^7.16.7", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-member-expression-to-functions": "^7.16.7", + "@babel/helper-optimise-call-expression": "^7.16.7", + "@babel/helper-replace-supers": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7" } }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.12.17", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.17.tgz", - "integrity": "sha512-p2VGmBu9oefLZ2nQpgnEnG0ZlRPvL8gAGvPUMQwUdaE8k49rOMuZpOwdQoy5qJf6K8jL3bcAMhVUlHAjIgJHUg==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.17.0.tgz", + "integrity": "sha512-awO2So99wG6KnlE+TPs6rn83gCz5WlEePJDTnLEqbchMVrBeAujURVphRdigsk094VhvZehFoNOihSlcBjwsXA==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.12.13", - "regexpu-core": "^4.7.1" + "@babel/helper-annotate-as-pure": "^7.16.7", + "regexpu-core": "^5.0.1" } }, "@babel/helper-define-polyfill-provider": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.0.tgz", - "integrity": "sha512-JT8tHuFjKBo8NnaUbblz7mIu1nnvUDiHVjXXkulZULyidvo/7P6TY7+YqpV37IfF+KUFxmlK04elKtGKXaiVgw==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz", + "integrity": "sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA==", "dev": true, "requires": { "@babel/helper-compilation-targets": "^7.13.0", @@ -12527,340 +12899,381 @@ "semver": "^6.1.2" } }, + "@babel/helper-environment-visitor": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", + "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, "@babel/helper-explode-assignable-expression": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.13.0.tgz", - "integrity": "sha512-qS0peLTDP8kOisG1blKbaoBg/o9OSa1qoumMjTK5pM+KDTtpxpsiubnCGP34vK8BXGcb2M9eigwgvoJryrzwWA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.7.tgz", + "integrity": "sha512-KyUenhWMC8VrxzkGP0Jizjo4/Zx+1nNZhgocs+gLzyZyB8SHidhoq9KK/8Ato4anhwsivfkBLftky7gvzbZMtQ==", "dev": true, "requires": { - "@babel/types": "^7.13.0" + "@babel/types": "^7.16.7" } }, "@babel/helper-function-name": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", - "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", + "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.12.13", - "@babel/template": "^7.12.13", - "@babel/types": "^7.12.13" + "@babel/helper-get-function-arity": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/types": "^7.16.7" } }, "@babel/helper-get-function-arity": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", - "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", + "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", "dev": true, "requires": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.16.7" } }, "@babel/helper-hoist-variables": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.13.16.tgz", - "integrity": "sha512-1eMtTrXtrwscjcAeO4BVK+vvkxaLJSPFz1w1KLawz6HLNi9bPFGBNwwDyVfiu1Tv/vRRFYfoGaKhmAQPGPn5Wg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", + "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", "dev": true, "requires": { - "@babel/traverse": "^7.13.15", - "@babel/types": "^7.13.16" + "@babel/types": "^7.16.7" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz", - "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.7.tgz", + "integrity": "sha512-VtJ/65tYiU/6AbMTDwyoXGPKHgTsfRarivm+YbB5uAzKUyuPjgZSgAFeG87FCigc7KNHu2Pegh1XIT3lXjvz3Q==", "dev": true, "requires": { - "@babel/types": "^7.13.12" + "@babel/types": "^7.16.7" } }, "@babel/helper-module-imports": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz", - "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", + "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", "dev": true, "requires": { - "@babel/types": "^7.13.12" + "@babel/types": "^7.16.7" } }, "@babel/helper-module-transforms": { - "version": "7.13.14", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.13.14.tgz", - "integrity": "sha512-QuU/OJ0iAOSIatyVZmfqB0lbkVP0kDRiKj34xy+QNsnVZi/PA6BoSoreeqnxxa9EHFAIL0R9XOaAR/G9WlIy5g==", + "version": "7.17.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.17.6.tgz", + "integrity": "sha512-2ULmRdqoOMpdvkbT8jONrZML/XALfzxlb052bldftkicAUy8AxSCkD5trDPQcwHNmolcl7wP6ehNqMlyUw6AaA==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.13.12", - "@babel/helper-replace-supers": "^7.13.12", - "@babel/helper-simple-access": "^7.13.12", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/helper-validator-identifier": "^7.12.11", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.13", - "@babel/types": "^7.13.14" + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-simple-access": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.3", + "@babel/types": "^7.17.0" } }, "@babel/helper-optimise-call-expression": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", - "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz", + "integrity": "sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w==", "dev": true, "requires": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.16.7" } }, "@babel/helper-plugin-utils": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", - "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", + "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", "dev": true }, "@babel/helper-remap-async-to-generator": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.13.0.tgz", - "integrity": "sha512-pUQpFBE9JvC9lrQbpX0TmeNIy5s7GnZjna2lhhcHC7DzgBs6fWn722Y5cfwgrtrqc7NAJwMvOa0mKhq6XaE4jg==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.8.tgz", + "integrity": "sha512-fm0gH7Flb8H51LqJHy3HJ3wnE1+qtYR2A99K06ahwrawLdOFsCEWjZOrYricXJHoPSudNKxrMBUPEIPxiIIvBw==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.12.13", - "@babel/helper-wrap-function": "^7.13.0", - "@babel/types": "^7.13.0" + "@babel/helper-annotate-as-pure": "^7.16.7", + "@babel/helper-wrap-function": "^7.16.8", + "@babel/types": "^7.16.8" } }, "@babel/helper-replace-supers": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz", - "integrity": "sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz", + "integrity": "sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.13.12", - "@babel/helper-optimise-call-expression": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.12" + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-member-expression-to-functions": "^7.16.7", + "@babel/helper-optimise-call-expression": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" } }, "@babel/helper-simple-access": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz", - "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", + "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==", "dev": true, "requires": { - "@babel/types": "^7.13.12" + "@babel/types": "^7.16.7" } }, "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz", - "integrity": "sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz", + "integrity": "sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw==", "dev": true, "requires": { - "@babel/types": "^7.12.1" + "@babel/types": "^7.16.0" } }, "@babel/helper-split-export-declaration": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", - "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", + "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", "dev": true, "requires": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.16.7" } }, "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", "dev": true }, "@babel/helper-validator-option": { - "version": "7.12.17", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", - "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", + "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", "dev": true }, "@babel/helper-wrap-function": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.13.0.tgz", - "integrity": "sha512-1UX9F7K3BS42fI6qd2A4BjKzgGjToscyZTdp1DjknHLCIvpgne6918io+aL5LXFcER/8QWiwpoY902pVEqgTXA==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.16.8.tgz", + "integrity": "sha512-8RpyRVIAW1RcDDGTA+GpPAwV22wXCfKOoM9bet6TLkGIFTkRQSkH1nMQ5Yet4MpoXe1ZwHPVtNasc2w0uZMqnw==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.12.13", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.0" + "@babel/helper-function-name": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.8", + "@babel/types": "^7.16.8" } }, "@babel/helpers": { - "version": "7.13.17", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.13.17.tgz", - "integrity": "sha512-Eal4Gce4kGijo1/TGJdqp3WuhllaMLSrW6XcL0ulyUAQOuxHcCafZE8KHg9857gcTehsm/v7RcOx2+jp0Ryjsg==", + "version": "7.17.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.2.tgz", + "integrity": "sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ==", "dev": true, "requires": { - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.17", - "@babel/types": "^7.13.17" + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.0", + "@babel/types": "^7.17.0" } }, "@babel/highlight": { - "version": "7.13.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.10.tgz", - "integrity": "sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==", + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.12.11", + "@babel/helper-validator-identifier": "^7.16.7", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.16.tgz", - "integrity": "sha512-6bAg36mCwuqLO0hbR+z7PHuqWiCeP7Dzg73OpQwsAB1Eb8HnGEz5xYBzCfbu+YjoaJsJs+qheDxVAuqbt3ILEw==", + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.3.tgz", + "integrity": "sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA==", "dev": true }, + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.7.tgz", + "integrity": "sha512-anv/DObl7waiGEnC24O9zqL0pSuI9hljihqiDuFHC8d7/bjr/4RLGPWuc8rYOff/QPzbEPSkzG8wGG9aDuhHRg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.7" + } + }, "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.13.12.tgz", - "integrity": "sha512-d0u3zWKcoZf379fOeJdr1a5WPDny4aOFZ6hlfKivgK0LY7ZxNfoaHL2fWwdGtHyVvra38FC+HVYkO+byfSA8AQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.7.tgz", + "integrity": "sha512-di8vUHRdf+4aJ7ltXhaDbPoszdkh59AQtJM5soLsuHpQJdFQZOA4uGj0V2u/CZ8bJ/u8ULDL5yq6FO/bCXnKHw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1", - "@babel/plugin-proposal-optional-chaining": "^7.13.12" + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", + "@babel/plugin-proposal-optional-chaining": "^7.16.7" } }, "@babel/plugin-proposal-async-generator-functions": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.13.15.tgz", - "integrity": "sha512-VapibkWzFeoa6ubXy/NgV5U2U4MVnUlvnx6wo1XhlsaTrLYWE0UFpDQsVrmn22q5CzeloqJ8gEMHSKxuee6ZdA==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.8.tgz", + "integrity": "sha512-71YHIvMuiuqWJQkebWJtdhQTfd4Q4mF76q2IX37uZPkG9+olBxsX+rH1vkhFto4UeJZ9dPY2s+mDvhDm1u2BGQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-remap-async-to-generator": "^7.13.0", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-remap-async-to-generator": "^7.16.8", "@babel/plugin-syntax-async-generators": "^7.8.4" } }, "@babel/plugin-proposal-class-properties": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.13.0.tgz", - "integrity": "sha512-KnTDjFNC1g+45ka0myZNvSBFLhNCLN+GeGYLDEA8Oq7MZ6yMgfLoIRh86GRT0FjtJhZw8JyUskP9uvj5pHM9Zg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz", + "integrity": "sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" + } + }, + "@babel/plugin-proposal-class-static-block": { + "version": "7.17.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.17.6.tgz", + "integrity": "sha512-X/tididvL2zbs7jZCeeRJ8167U/+Ac135AM6jCAx6gYXDUviZV5Ku9UDvWS2NCuWlFjIRXklYhwo6HhAC7ETnA==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.13.0", - "@babel/helper-plugin-utils": "^7.13.0" + "@babel/helper-create-class-features-plugin": "^7.17.6", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-class-static-block": "^7.14.5" } }, "@babel/plugin-proposal-dynamic-import": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.13.8.tgz", - "integrity": "sha512-ONWKj0H6+wIRCkZi9zSbZtE/r73uOhMVHh256ys0UzfM7I3d4n+spZNWjOnJv2gzopumP2Wxi186vI8N0Y2JyQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.7.tgz", + "integrity": "sha512-I8SW9Ho3/8DRSdmDdH3gORdyUuYnk1m4cMxUAdu5oy4n3OfN8flDEH+d60iG7dUfi0KkYwSvoalHzzdRzpWHTg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-dynamic-import": "^7.8.3" } }, "@babel/plugin-proposal-export-namespace-from": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.13.tgz", - "integrity": "sha512-INAgtFo4OnLN3Y/j0VwAgw3HDXcDtX+C/erMvWzuV9v71r7urb6iyMXu7eM9IgLr1ElLlOkaHjJ0SbCmdOQ3Iw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.7.tgz", + "integrity": "sha512-ZxdtqDXLRGBL64ocZcs7ovt71L3jhC1RGSyR996svrCi3PYqHNkb3SwPJCs8RIzD86s+WPpt2S73+EHCGO+NUA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.12.13", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" } }, "@babel/plugin-proposal-json-strings": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.13.8.tgz", - "integrity": "sha512-w4zOPKUFPX1mgvTmL/fcEqy34hrQ1CRcGxdphBc6snDnnqJ47EZDIyop6IwXzAC8G916hsIuXB2ZMBCExC5k7Q==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.7.tgz", + "integrity": "sha512-lNZ3EEggsGY78JavgbHsK9u5P3pQaW7k4axlgFLYkMd7UBsiNahCITShLjNQschPyjtO6dADrL24757IdhBrsQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-json-strings": "^7.8.3" } }, "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.13.8.tgz", - "integrity": "sha512-aul6znYB4N4HGweImqKn59Su9RS8lbUIqxtXTOcAGtNIDczoEFv+l1EhmX8rUBp3G1jMjKJm8m0jXVp63ZpS4A==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.7.tgz", + "integrity": "sha512-K3XzyZJGQCr00+EtYtrDjmwX7o7PLK6U9bi1nCwkQioRFVUv6dJoxbQjtWVtP+bCPy82bONBKG8NPyQ4+i6yjg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" } }, "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.13.8.tgz", - "integrity": "sha512-iePlDPBn//UhxExyS9KyeYU7RM9WScAG+D3Hhno0PLJebAEpDZMocbDe64eqynhNAnwz/vZoL/q/QB2T1OH39A==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.7.tgz", + "integrity": "sha512-aUOrYU3EVtjf62jQrCj63pYZ7k6vns2h/DQvHPWGmsJRYzWXZ6/AsfgpiRy6XiuIDADhJzP2Q9MwSMKauBQ+UQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" } }, "@babel/plugin-proposal-numeric-separator": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.13.tgz", - "integrity": "sha512-O1jFia9R8BUCl3ZGB7eitaAPu62TXJRHn7rh+ojNERCFyqRwJMTmhz+tJ+k0CwI6CLjX/ee4qW74FSqlq9I35w==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.7.tgz", + "integrity": "sha512-vQgPMknOIgiuVqbokToyXbkY/OmmjAzr/0lhSIbG/KmnzXPGwW/AdhdKpi+O4X/VkWiWjnkKOBiqJrTaC98VKw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.12.13", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-numeric-separator": "^7.10.4" } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.13.8.tgz", - "integrity": "sha512-DhB2EuB1Ih7S3/IRX5AFVgZ16k3EzfRbq97CxAVI1KSYcW+lexV8VZb7G7L8zuPVSdQMRn0kiBpf/Yzu9ZKH0g==", + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.17.3.tgz", + "integrity": "sha512-yuL5iQA/TbZn+RGAfxQXfi7CNLmKi1f8zInn4IgobuCWcAb7i+zj4TYzQ9l8cEzVyJ89PDGuqxK1xZpUDISesw==", "dev": true, "requires": { - "@babel/compat-data": "^7.13.8", - "@babel/helper-compilation-targets": "^7.13.8", - "@babel/helper-plugin-utils": "^7.13.0", + "@babel/compat-data": "^7.17.0", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.13.0" + "@babel/plugin-transform-parameters": "^7.16.7" } }, "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.13.8.tgz", - "integrity": "sha512-0wS/4DUF1CuTmGo+NiaHfHcVSeSLj5S3e6RivPTg/2k3wOv3jO35tZ6/ZWsQhQMvdgI7CwphjQa/ccarLymHVA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.7.tgz", + "integrity": "sha512-eMOH/L4OvWSZAE1VkHbr1vckLG1WUcHGJSLqqQwl2GaUqG6QjddvrOaTUMNYiv77H5IKPMZ9U9P7EaHwvAShfA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" } }, "@babel/plugin-proposal-optional-chaining": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.13.12.tgz", - "integrity": "sha512-fcEdKOkIB7Tf4IxrgEVeFC4zeJSTr78no9wTdBuZZbqF64kzllU0ybo2zrzm7gUQfxGhBgq4E39oRs8Zx/RMYQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz", + "integrity": "sha512-eC3xy+ZrUcBtP7x+sq62Q/HYd674pPTb/77XZMb5wbDPGWIdUbSr4Agr052+zaUPSb+gGRnjxXfKFvx5iMJ+DA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", "@babel/plugin-syntax-optional-chaining": "^7.8.3" } }, "@babel/plugin-proposal-private-methods": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.13.0.tgz", - "integrity": "sha512-MXyyKQd9inhx1kDYPkFRVOBXQ20ES8Pto3T7UZ92xj2mY0EVD8oAVzeyYuVfy/mxAdTSIayOvg+aVzcHV2bn6Q==", + "version": "7.16.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.11.tgz", + "integrity": "sha512-F/2uAkPlXDr8+BHpZvo19w3hLFKge+k75XUprE6jaqKxjGkSYcK+4c+bup5PdW/7W/Rpjwql7FTVEDW+fRAQsw==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.16.10", + "@babel/helper-plugin-utils": "^7.16.7" + } + }, + "@babel/plugin-proposal-private-property-in-object": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.7.tgz", + "integrity": "sha512-rMQkjcOFbm+ufe3bTZLyOfsOUOxyvLXZJCTARhJr+8UMSoZmqTe1K1BgkFcrW37rAchWg57yI69ORxiWvUINuQ==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.13.0", - "@babel/helper-plugin-utils": "^7.13.0" + "@babel/helper-annotate-as-pure": "^7.16.7", + "@babel/helper-create-class-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" } }, "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.13.tgz", - "integrity": "sha512-XyJmZidNfofEkqFV5VC/bLabGmO5QzenPO/YOfGuEbgU+2sSwMmio3YLb4WtBgcmmdwZHyVyv8on77IUjQ5Gvg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.7.tgz", + "integrity": "sha512-QRK0YI/40VLhNVGIjRNAAQkEHws0cswSdFFjpFyt943YmJIU1da9uW63Iu6NFV6CxTZW5eTDCrwZUstBWgp/Rg==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.12.13", - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-create-regexp-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-syntax-async-generators": { @@ -12890,6 +13303,15 @@ "@babel/helper-plugin-utils": "^7.12.13" } }, + "@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, "@babel/plugin-syntax-dynamic-import": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", @@ -12980,353 +13402,388 @@ "@babel/helper-plugin-utils": "^7.8.0" } }, + "@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, "@babel/plugin-syntax-top-level-await": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz", - "integrity": "sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-typescript": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz", + "integrity": "sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-arrow-functions": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.13.0.tgz", - "integrity": "sha512-96lgJagobeVmazXFaDrbmCLQxBysKu7U6Do3mLsx27gf5Dk85ezysrs2BZUpXD703U/Su1xTBDxxar2oa4jAGg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.7.tgz", + "integrity": "sha512-9ffkFFMbvzTvv+7dTp/66xvZAWASuPD5Tl9LK3Z9vhOmANo6j94rik+5YMBt4CwHVMWLWpMsriIc2zsa3WW3xQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.13.0" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-async-to-generator": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.13.0.tgz", - "integrity": "sha512-3j6E004Dx0K3eGmhxVJxwwI89CTJrce7lg3UrtFuDAVQ/2+SJ/h/aSFOeE6/n0WB1GsOffsJp6MnPQNQ8nmwhg==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.8.tgz", + "integrity": "sha512-MtmUmTJQHCnyJVrScNzNlofQJ3dLFuobYn3mwOTKHnSCMtbNsqvF71GQmJfFjdrXSsAA7iysFmYWw4bXZ20hOg==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.12.13", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-remap-async-to-generator": "^7.13.0" + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-remap-async-to-generator": "^7.16.8" } }, "@babel/plugin-transform-block-scoped-functions": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.13.tgz", - "integrity": "sha512-zNyFqbc3kI/fVpqwfqkg6RvBgFpC4J18aKKMmv7KdQ/1GgREapSJAykLMVNwfRGO3BtHj3YQZl8kxCXPcVMVeg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.7.tgz", + "integrity": "sha512-JUuzlzmF40Z9cXyytcbZEZKckgrQzChbQJw/5PuEHYeqzCsvebDx0K0jWnIIVcmmDOAVctCgnYs0pMcrYj2zJg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-block-scoping": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.13.16.tgz", - "integrity": "sha512-ad3PHUxGnfWF4Efd3qFuznEtZKoBp0spS+DgqzVzRPV7urEBvPLue3y2j80w4Jf2YLzZHj8TOv/Lmvdmh3b2xg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.7.tgz", + "integrity": "sha512-ObZev2nxVAYA4bhyusELdo9hb3H+A56bxH3FZMbEImZFiEDYVHXQSJ1hQKFlDnlt8G9bBrCZ5ZpURZUrV4G5qQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.13.0" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-classes": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.13.0.tgz", - "integrity": "sha512-9BtHCPUARyVH1oXGcSJD3YpsqRLROJx5ZNP6tN5vnk17N0SVf9WCtf8Nuh1CFmgByKKAIMstitKduoCmsaDK5g==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.12.13", - "@babel/helper-function-name": "^7.12.13", - "@babel/helper-optimise-call-expression": "^7.12.13", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-replace-supers": "^7.13.0", - "@babel/helper-split-export-declaration": "^7.12.13", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.7.tgz", + "integrity": "sha512-WY7og38SFAGYRe64BrjKf8OrE6ulEHtr5jEYaZMwox9KebgqPi67Zqz8K53EKk1fFEJgm96r32rkKZ3qA2nCWQ==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.16.7", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-optimise-call-expression": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-replace-supers": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", "globals": "^11.1.0" } }, "@babel/plugin-transform-computed-properties": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.13.0.tgz", - "integrity": "sha512-RRqTYTeZkZAz8WbieLTvKUEUxZlUTdmL5KGMyZj7FnMfLNKV4+r5549aORG/mgojRmFlQMJDUupwAMiF2Q7OUg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.7.tgz", + "integrity": "sha512-gN72G9bcmenVILj//sv1zLNaPyYcOzUho2lIJBMh/iakJ9ygCo/hEF9cpGb61SCMEDxbbyBoVQxrt+bWKu5KGw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.13.0" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-destructuring": { - "version": "7.13.17", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.13.17.tgz", - "integrity": "sha512-UAUqiLv+uRLO+xuBKKMEpC+t7YRNVRqBsWWq1yKXbBZBje/t3IXCiSinZhjn/DC3qzBfICeYd2EFGEbHsh5RLA==", + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.17.3.tgz", + "integrity": "sha512-dDFzegDYKlPqa72xIlbmSkly5MluLoaC1JswABGktyt6NTXSBcUuse/kWE/wvKFWJHPETpi158qJZFS3JmykJg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.13.0" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-dotall-regex": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.13.tgz", - "integrity": "sha512-foDrozE65ZFdUC2OfgeOCrEPTxdB3yjqxpXh8CH+ipd9CHd4s/iq81kcUpyH8ACGNEPdFqbtzfgzbT/ZGlbDeQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.7.tgz", + "integrity": "sha512-Lyttaao2SjZF6Pf4vk1dVKv8YypMpomAbygW+mU5cYP3S5cWTfCJjG8xV6CFdzGFlfWK81IjL9viiTvpb6G7gQ==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.12.13", - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-create-regexp-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-duplicate-keys": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.13.tgz", - "integrity": "sha512-NfADJiiHdhLBW3pulJlJI2NB0t4cci4WTZ8FtdIuNc2+8pslXdPtRRAEWqUY+m9kNOk2eRYbTAOipAxlrOcwwQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.7.tgz", + "integrity": "sha512-03DvpbRfvWIXyK0/6QiR1KMTWeT6OcQ7tbhjrXyFS02kjuX/mu5Bvnh5SDSWHxyawit2g5aWhKwI86EE7GUnTw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-exponentiation-operator": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.13.tgz", - "integrity": "sha512-fbUelkM1apvqez/yYx1/oICVnGo2KM5s63mhGylrmXUxK/IAXSIf87QIxVfZldWf4QsOafY6vV3bX8aMHSvNrA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.7.tgz", + "integrity": "sha512-8UYLSlyLgRixQvlYH3J2ekXFHDFLQutdy7FfFAMm3CPZ6q9wHCwnUyiXpQCe3gVVnQlHc5nsuiEVziteRNTXEA==", "dev": true, "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.12.13", - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-for-of": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.13.0.tgz", - "integrity": "sha512-IHKT00mwUVYE0zzbkDgNRP6SRzvfGCYsOxIRz8KsiaaHCcT9BWIkO+H9QRJseHBLOGBZkHUdHiqj6r0POsdytg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.7.tgz", + "integrity": "sha512-/QZm9W92Ptpw7sjI9Nx1mbcsWz33+l8kuMIQnDwgQBG5s3fAfQvkRjQ7NqXhtNcKOnPkdICmUHyCaWW06HCsqg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.13.0" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-function-name": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.13.tgz", - "integrity": "sha512-6K7gZycG0cmIwwF7uMK/ZqeCikCGVBdyP2J5SKNCXO5EOHcqi+z7Jwf8AmyDNcBgxET8DrEtCt/mPKPyAzXyqQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.7.tgz", + "integrity": "sha512-SU/C68YVwTRxqWj5kgsbKINakGag0KTgq9f2iZEXdStoAbOzLHEBRYzImmA6yFo8YZhJVflvXmIHUO7GWHmxxA==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.12.13", - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-literals": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.13.tgz", - "integrity": "sha512-FW+WPjSR7hiUxMcKqyNjP05tQ2kmBCdpEpZHY1ARm96tGQCCBvXKnpjILtDplUnJ/eHZ0lALLM+d2lMFSpYJrQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.7.tgz", + "integrity": "sha512-6tH8RTpTWI0s2sV6uq3e/C9wPo4PTqqZps4uF0kzQ9/xPLFQtipynvmT1g/dOfEJ+0EQsHhkQ/zyRId8J2b8zQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-member-expression-literals": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.13.tgz", - "integrity": "sha512-kxLkOsg8yir4YeEPHLuO2tXP9R/gTjpuTOjshqSpELUN3ZAg2jfDnKUvzzJxObun38sw3wm4Uu69sX/zA7iRvg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.7.tgz", + "integrity": "sha512-mBruRMbktKQwbxaJof32LT9KLy2f3gH+27a5XSuXo6h7R3vqltl0PgZ80C8ZMKw98Bf8bqt6BEVi3svOh2PzMw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-modules-amd": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.13.0.tgz", - "integrity": "sha512-EKy/E2NHhY/6Vw5d1k3rgoobftcNUmp9fGjb9XZwQLtTctsRBOTRO7RHHxfIky1ogMN5BxN7p9uMA3SzPfotMQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.7.tgz", + "integrity": "sha512-KaaEtgBL7FKYwjJ/teH63oAmE3lP34N3kshz8mm4VMAw7U3PxjVwwUmxEFksbgsNUaO3wId9R2AVQYSEGRa2+g==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.13.0", - "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.13.8.tgz", - "integrity": "sha512-9QiOx4MEGglfYZ4XOnU79OHr6vIWUakIj9b4mioN8eQIoEh+pf5p/zEB36JpDFWA12nNMiRf7bfoRvl9Rn79Bw==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.8.tgz", + "integrity": "sha512-oflKPvsLT2+uKQopesJt3ApiaIS2HW+hzHFcwRNtyDGieAeC/dIHZX8buJQ2J2X1rxGPy4eRcUijm3qcSPjYcA==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.13.0", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-simple-access": "^7.12.13", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-simple-access": "^7.16.7", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.13.8.tgz", - "integrity": "sha512-hwqctPYjhM6cWvVIlOIe27jCIBgHCsdH2xCJVAYQm7V5yTMoilbVMi9f6wKg0rpQAOn6ZG4AOyvCqFF/hUh6+A==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.7.tgz", + "integrity": "sha512-DuK5E3k+QQmnOqBR9UkusByy5WZWGRxfzV529s9nPra1GE7olmxfqO2FHobEOYSPIjPBTr4p66YDcjQnt8cBmw==", "dev": true, "requires": { - "@babel/helper-hoist-variables": "^7.13.0", - "@babel/helper-module-transforms": "^7.13.0", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-validator-identifier": "^7.12.11", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-umd": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.13.0.tgz", - "integrity": "sha512-D/ILzAh6uyvkWjKKyFE/W0FzWwasv6vPTSqPcjxFqn6QpX3u8DjRVliq4F2BamO2Wee/om06Vyy+vPkNrd4wxw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.7.tgz", + "integrity": "sha512-EMh7uolsC8O4xhudF2F6wedbSHm1HHZ0C6aJ7K67zcDNidMzVcxWdGr+htW9n21klm+bOn+Rx4CBsAntZd3rEQ==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.13.0", - "@babel/helper-plugin-utils": "^7.13.0" + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.13.tgz", - "integrity": "sha512-Xsm8P2hr5hAxyYblrfACXpQKdQbx4m2df9/ZZSQ8MAhsadw06+jW7s9zsSw6he+mJZXRlVMyEnVktJo4zjk1WA==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.8.tgz", + "integrity": "sha512-j3Jw+n5PvpmhRR+mrgIh04puSANCk/T/UA3m3P1MjJkhlK906+ApHhDIqBQDdOgL/r1UYpz4GNclTXxyZrYGSw==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.12.13" + "@babel/helper-create-regexp-features-plugin": "^7.16.7" } }, "@babel/plugin-transform-new-target": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.13.tgz", - "integrity": "sha512-/KY2hbLxrG5GTQ9zzZSc3xWiOy379pIETEhbtzwZcw9rvuaVV4Fqy7BYGYOWZnaoXIQYbbJ0ziXLa/sKcGCYEQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.7.tgz", + "integrity": "sha512-xiLDzWNMfKoGOpc6t3U+etCE2yRnn3SM09BXqWPIZOBpL2gvVrBWUKnsJx0K/ADi5F5YC5f8APFfWrz25TdlGg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-object-super": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.13.tgz", - "integrity": "sha512-JzYIcj3XtYspZDV8j9ulnoMPZZnF/Cj0LUxPOjR89BdBVx+zYJI9MdMIlUZjbXDX+6YVeS6I3e8op+qQ3BYBoQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.7.tgz", + "integrity": "sha512-14J1feiQVWaGvRxj2WjyMuXS2jsBkgB3MdSN5HuC2G5nRspa5RK9COcs82Pwy5BuGcjb+fYaUj94mYcOj7rCvw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.12.13", - "@babel/helper-replace-supers": "^7.12.13" + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-replace-supers": "^7.16.7" } }, "@babel/plugin-transform-parameters": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.13.0.tgz", - "integrity": "sha512-Jt8k/h/mIwE2JFEOb3lURoY5C85ETcYPnbuAJ96zRBzh1XHtQZfs62ChZ6EP22QlC8c7Xqr9q+e1SU5qttwwjw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.7.tgz", + "integrity": "sha512-AT3MufQ7zZEhU2hwOA11axBnExW0Lszu4RL/tAlUJBuNoRak+wehQW8h6KcXOcgjY42fHtDxswuMhMjFEuv/aw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.13.0" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-property-literals": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.13.tgz", - "integrity": "sha512-nqVigwVan+lR+g8Fj8Exl0UQX2kymtjcWfMOYM1vTYEKujeyv2SkMgazf2qNcK7l4SDiKyTA/nHCPqL4e2zo1A==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.7.tgz", + "integrity": "sha512-z4FGr9NMGdoIl1RqavCqGG+ZuYjfZ/hkCIeuH6Do7tXmSm0ls11nYVSJqFEUOSJbDab5wC6lRE/w6YjVcr6Hqw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-regenerator": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.13.15.tgz", - "integrity": "sha512-Bk9cOLSz8DiurcMETZ8E2YtIVJbFCPGW28DJWUakmyVWtQSm6Wsf0p4B4BfEr/eL2Nkhe/CICiUiMOCi1TPhuQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.7.tgz", + "integrity": "sha512-mF7jOgGYCkSJagJ6XCujSQg+6xC1M77/03K2oBmVJWoFGNUtnVJO4WHKJk3dnPC8HCcj4xBQP1Egm8DWh3Pb3Q==", "dev": true, "requires": { "regenerator-transform": "^0.14.2" } }, "@babel/plugin-transform-reserved-words": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.13.tgz", - "integrity": "sha512-xhUPzDXxZN1QfiOy/I5tyye+TRz6lA7z6xaT4CLOjPRMVg1ldRf0LHw0TDBpYL4vG78556WuHdyO9oi5UmzZBg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.7.tgz", + "integrity": "sha512-KQzzDnZ9hWQBjwi5lpY5v9shmm6IVG0U9pB18zvMu2i4H90xpT4gmqwPYsn8rObiadYe2M0gmgsiOIF5A/2rtg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-shorthand-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.13.tgz", - "integrity": "sha512-xpL49pqPnLtf0tVluuqvzWIgLEhuPpZzvs2yabUHSKRNlN7ScYU7aMlmavOeyXJZKgZKQRBlh8rHbKiJDraTSw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.7.tgz", + "integrity": "sha512-hah2+FEnoRoATdIb05IOXf+4GzXYTq75TVhIn1PewihbpyrNWUt2JbudKQOETWw6QpLe+AIUpJ5MVLYTQbeeUg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-spread": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.13.0.tgz", - "integrity": "sha512-V6vkiXijjzYeFmQTr3dBxPtZYLPcUfY34DebOU27jIl2M/Y8Egm52Hw82CSjjPqd54GTlJs5x+CR7HeNr24ckg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.7.tgz", + "integrity": "sha512-+pjJpgAngb53L0iaA5gU/1MLXJIfXcYepLgXB3esVRf4fqmj8f2cxM3/FKaHsZms08hFQJkFccEWuIpm429TXg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1" + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0" } }, "@babel/plugin-transform-sticky-regex": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.13.tgz", - "integrity": "sha512-Jc3JSaaWT8+fr7GRvQP02fKDsYk4K/lYwWq38r/UGfaxo89ajud321NH28KRQ7xy1Ybc0VUE5Pz8psjNNDUglg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.7.tgz", + "integrity": "sha512-NJa0Bd/87QV5NZZzTuZG5BPJjLYadeSZ9fO6oOUoL4iQx+9EEuw/eEM92SrsT19Yc2jgB1u1hsjqDtH02c3Drw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-template-literals": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.13.0.tgz", - "integrity": "sha512-d67umW6nlfmr1iehCcBv69eSUSySk1EsIS8aTDX4Xo9qajAh6mYtcl4kJrBkGXuxZPEgVr7RVfAvNW6YQkd4Mw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.7.tgz", + "integrity": "sha512-VwbkDDUeenlIjmfNeDX/V0aWrQH2QiVyJtwymVQSzItFDTpxfyJh3EVaQiS0rIN/CqbLGr0VcGmuwyTdZtdIsA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.13.0" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-typeof-symbol": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.13.tgz", - "integrity": "sha512-eKv/LmUJpMnu4npgfvs3LiHhJua5fo/CysENxa45YCQXZwKnGCQKAg87bvoqSW1fFT+HA32l03Qxsm8ouTY3ZQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.7.tgz", + "integrity": "sha512-p2rOixCKRJzpg9JB4gjnG4gjWkWa89ZoYUnl9snJ1cWIcTH/hvxZqfO+WjG6T8DRBpctEol5jw1O5rA8gkCokQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-plugin-utils": "^7.16.7" + } + }, + "@babel/plugin-transform-typescript": { + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.8.tgz", + "integrity": "sha512-bHdQ9k7YpBDO2d0NVfkj51DpQcvwIzIusJ7mEUaMlbZq3Kt/U47j24inXZHQ5MDiYpCs+oZiwnXyKedE8+q7AQ==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-typescript": "^7.16.7" } }, "@babel/plugin-transform-unicode-escapes": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.13.tgz", - "integrity": "sha512-0bHEkdwJ/sN/ikBHfSmOXPypN/beiGqjo+o4/5K+vxEFNPRPdImhviPakMKG4x96l85emoa0Z6cDflsdBusZbw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.7.tgz", + "integrity": "sha512-TAV5IGahIz3yZ9/Hfv35TV2xEm+kaBDaZQCn2S/hG9/CZ0DktxJv9eKfPc7yYCvOYR4JGx1h8C+jcSOvgaaI/Q==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-unicode-regex": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.13.tgz", - "integrity": "sha512-mDRzSNY7/zopwisPZ5kM9XKCfhchqIYwAKRERtEnhYscZB79VRekuRSoYbN0+KVe3y8+q1h6A4svXtP7N+UoCA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.7.tgz", + "integrity": "sha512-oC5tYYKw56HO75KZVLQ+R/Nl3Hro9kf8iG0hXoaHP7tjAyCpvqBiSNe6vGrZni1Z6MggmUOC6A7VP7AVmw225Q==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.12.13", - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-create-regexp-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/preset-env": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.13.15.tgz", - "integrity": "sha512-D4JAPMXcxk69PKe81jRJ21/fP/uYdcTZ3hJDF5QX2HSI9bBxxYw/dumdR6dGumhjxlprHPE4XWoPaqzZUVy2MA==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.13.15", - "@babel/helper-compilation-targets": "^7.13.13", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-validator-option": "^7.12.17", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.13.12", - "@babel/plugin-proposal-async-generator-functions": "^7.13.15", - "@babel/plugin-proposal-class-properties": "^7.13.0", - "@babel/plugin-proposal-dynamic-import": "^7.13.8", - "@babel/plugin-proposal-export-namespace-from": "^7.12.13", - "@babel/plugin-proposal-json-strings": "^7.13.8", - "@babel/plugin-proposal-logical-assignment-operators": "^7.13.8", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.13.8", - "@babel/plugin-proposal-numeric-separator": "^7.12.13", - "@babel/plugin-proposal-object-rest-spread": "^7.13.8", - "@babel/plugin-proposal-optional-catch-binding": "^7.13.8", - "@babel/plugin-proposal-optional-chaining": "^7.13.12", - "@babel/plugin-proposal-private-methods": "^7.13.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.12.13", + "version": "7.16.11", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.16.11.tgz", + "integrity": "sha512-qcmWG8R7ZW6WBRPZK//y+E3Cli151B20W1Rv7ln27vuPaXU/8TKms6jFdiJtF7UDTxcrb7mZd88tAeK9LjdT8g==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.16.8", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-validator-option": "^7.16.7", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.16.7", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.16.7", + "@babel/plugin-proposal-async-generator-functions": "^7.16.8", + "@babel/plugin-proposal-class-properties": "^7.16.7", + "@babel/plugin-proposal-class-static-block": "^7.16.7", + "@babel/plugin-proposal-dynamic-import": "^7.16.7", + "@babel/plugin-proposal-export-namespace-from": "^7.16.7", + "@babel/plugin-proposal-json-strings": "^7.16.7", + "@babel/plugin-proposal-logical-assignment-operators": "^7.16.7", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.7", + "@babel/plugin-proposal-numeric-separator": "^7.16.7", + "@babel/plugin-proposal-object-rest-spread": "^7.16.7", + "@babel/plugin-proposal-optional-catch-binding": "^7.16.7", + "@babel/plugin-proposal-optional-chaining": "^7.16.7", + "@babel/plugin-proposal-private-methods": "^7.16.11", + "@babel/plugin-proposal-private-property-in-object": "^7.16.7", + "@babel/plugin-proposal-unicode-property-regex": "^7.16.7", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", "@babel/plugin-syntax-json-strings": "^7.8.3", @@ -13336,52 +13793,53 @@ "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.12.13", - "@babel/plugin-transform-arrow-functions": "^7.13.0", - "@babel/plugin-transform-async-to-generator": "^7.13.0", - "@babel/plugin-transform-block-scoped-functions": "^7.12.13", - "@babel/plugin-transform-block-scoping": "^7.12.13", - "@babel/plugin-transform-classes": "^7.13.0", - "@babel/plugin-transform-computed-properties": "^7.13.0", - "@babel/plugin-transform-destructuring": "^7.13.0", - "@babel/plugin-transform-dotall-regex": "^7.12.13", - "@babel/plugin-transform-duplicate-keys": "^7.12.13", - "@babel/plugin-transform-exponentiation-operator": "^7.12.13", - "@babel/plugin-transform-for-of": "^7.13.0", - "@babel/plugin-transform-function-name": "^7.12.13", - "@babel/plugin-transform-literals": "^7.12.13", - "@babel/plugin-transform-member-expression-literals": "^7.12.13", - "@babel/plugin-transform-modules-amd": "^7.13.0", - "@babel/plugin-transform-modules-commonjs": "^7.13.8", - "@babel/plugin-transform-modules-systemjs": "^7.13.8", - "@babel/plugin-transform-modules-umd": "^7.13.0", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.12.13", - "@babel/plugin-transform-new-target": "^7.12.13", - "@babel/plugin-transform-object-super": "^7.12.13", - "@babel/plugin-transform-parameters": "^7.13.0", - "@babel/plugin-transform-property-literals": "^7.12.13", - "@babel/plugin-transform-regenerator": "^7.13.15", - "@babel/plugin-transform-reserved-words": "^7.12.13", - "@babel/plugin-transform-shorthand-properties": "^7.12.13", - "@babel/plugin-transform-spread": "^7.13.0", - "@babel/plugin-transform-sticky-regex": "^7.12.13", - "@babel/plugin-transform-template-literals": "^7.13.0", - "@babel/plugin-transform-typeof-symbol": "^7.12.13", - "@babel/plugin-transform-unicode-escapes": "^7.12.13", - "@babel/plugin-transform-unicode-regex": "^7.12.13", - "@babel/preset-modules": "^0.1.4", - "@babel/types": "^7.13.14", - "babel-plugin-polyfill-corejs2": "^0.2.0", - "babel-plugin-polyfill-corejs3": "^0.2.0", - "babel-plugin-polyfill-regenerator": "^0.2.0", - "core-js-compat": "^3.9.0", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-transform-arrow-functions": "^7.16.7", + "@babel/plugin-transform-async-to-generator": "^7.16.8", + "@babel/plugin-transform-block-scoped-functions": "^7.16.7", + "@babel/plugin-transform-block-scoping": "^7.16.7", + "@babel/plugin-transform-classes": "^7.16.7", + "@babel/plugin-transform-computed-properties": "^7.16.7", + "@babel/plugin-transform-destructuring": "^7.16.7", + "@babel/plugin-transform-dotall-regex": "^7.16.7", + "@babel/plugin-transform-duplicate-keys": "^7.16.7", + "@babel/plugin-transform-exponentiation-operator": "^7.16.7", + "@babel/plugin-transform-for-of": "^7.16.7", + "@babel/plugin-transform-function-name": "^7.16.7", + "@babel/plugin-transform-literals": "^7.16.7", + "@babel/plugin-transform-member-expression-literals": "^7.16.7", + "@babel/plugin-transform-modules-amd": "^7.16.7", + "@babel/plugin-transform-modules-commonjs": "^7.16.8", + "@babel/plugin-transform-modules-systemjs": "^7.16.7", + "@babel/plugin-transform-modules-umd": "^7.16.7", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.16.8", + "@babel/plugin-transform-new-target": "^7.16.7", + "@babel/plugin-transform-object-super": "^7.16.7", + "@babel/plugin-transform-parameters": "^7.16.7", + "@babel/plugin-transform-property-literals": "^7.16.7", + "@babel/plugin-transform-regenerator": "^7.16.7", + "@babel/plugin-transform-reserved-words": "^7.16.7", + "@babel/plugin-transform-shorthand-properties": "^7.16.7", + "@babel/plugin-transform-spread": "^7.16.7", + "@babel/plugin-transform-sticky-regex": "^7.16.7", + "@babel/plugin-transform-template-literals": "^7.16.7", + "@babel/plugin-transform-typeof-symbol": "^7.16.7", + "@babel/plugin-transform-unicode-escapes": "^7.16.7", + "@babel/plugin-transform-unicode-regex": "^7.16.7", + "@babel/preset-modules": "^0.1.5", + "@babel/types": "^7.16.8", + "babel-plugin-polyfill-corejs2": "^0.3.0", + "babel-plugin-polyfill-corejs3": "^0.5.0", + "babel-plugin-polyfill-regenerator": "^0.3.0", + "core-js-compat": "^3.20.2", "semver": "^6.3.0" } }, "@babel/preset-modules": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz", - "integrity": "sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==", + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", + "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", @@ -13391,49 +13849,62 @@ "esutils": "^2.0.2" } }, + "@babel/preset-typescript": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.16.7.tgz", + "integrity": "sha512-WbVEmgXdIyvzB77AQjGBEyYPZx+8tTsO50XtfozQrkW8QB2rLJpH2lgx0TRw5EJrBxOZQ+wCcyPVQvS8tjEHpQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-validator-option": "^7.16.7", + "@babel/plugin-transform-typescript": "^7.16.7" + } + }, "@babel/runtime": { - "version": "7.13.17", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.17.tgz", - "integrity": "sha512-NCdgJEelPTSh+FEFylhnP1ylq848l1z9t9N0j1Lfbcw0+KXGjsTvUmkxy+voLLXB5SOKMbLLx4jxYliGrYQseA==", + "version": "7.17.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.2.tgz", + "integrity": "sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==", "dev": true, "requires": { "regenerator-runtime": "^0.13.4" } }, "@babel/template": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", - "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", + "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", "dev": true, "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/parser": "^7.12.13", - "@babel/types": "^7.12.13" + "@babel/code-frame": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" } }, "@babel/traverse": { - "version": "7.13.17", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.17.tgz", - "integrity": "sha512-BMnZn0R+X6ayqm3C3To7o1j7Q020gWdqdyP50KEoVqaCO2c/Im7sYZSmVgvefp8TTMQ+9CtwuBp0Z1CZ8V3Pvg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.16", - "@babel/helper-function-name": "^7.12.13", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.13.16", - "@babel/types": "^7.13.17", + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.3.tgz", + "integrity": "sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.3", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/parser": "^7.17.3", + "@babel/types": "^7.17.0", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.13.17", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.17.tgz", - "integrity": "sha512-RawydLgxbOPDlTLJNtoIypwdmAy//uQIzlKt2+iBiJaRlVuI6QLUxVAyWGNfOzp8Yu4L4lLIacoCyTNtpb4wiA==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.12.11", + "@babel/helper-validator-identifier": "^7.16.7", "to-fast-properties": "^2.0.0" } }, @@ -13443,14 +13914,12 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "@cnakazawa/watch": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", - "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", - "dev": true, + "@duckduckgo/content-scope-scripts": { + "version": "git+ssh://git@github.com/duckduckgo/content-scope-scripts.git#943d9ca3d3f32e57eaa918b46fb6b1954b7c3319", + "from": "@duckduckgo/content-scope-scripts@github:duckduckgo/content-scope-scripts", "requires": { - "exec-sh": "^0.3.2", - "minimist": "^1.2.0" + "seedrandom": "^3.0.5", + "sjcl": "^1.0.8" } }, "@eslint/eslintrc": { @@ -13470,6 +13939,18 @@ "strip-json-comments": "^3.1.1" }, "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, "globals": { "version": "12.4.0", "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", @@ -13478,6 +13959,11 @@ "requires": { "type-fest": "^0.8.1" } + }, + "json-schema-traverse": { + "version": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true } } }, @@ -13558,16 +14044,16 @@ "dev": true }, "@jest/console": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", - "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.4.6.tgz", + "integrity": "sha512-jauXyacQD33n47A44KrlOVeiXHEXDqapSdfb9kTekOchH/Pd18kBIO1+xxJQRLuG+LUuljFCwTG92ra4NW7SpA==", "dev": true, "requires": { - "@jest/types": "^26.6.2", + "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.6.2", - "jest-util": "^26.6.2", + "jest-message-util": "^27.4.6", + "jest-util": "^27.4.2", "slash": "^3.0.0" }, "dependencies": { @@ -13581,9 +14067,9 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -13623,36 +14109,36 @@ } }, "@jest/core": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.6.3.tgz", - "integrity": "sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==", + "version": "27.4.7", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.4.7.tgz", + "integrity": "sha512-n181PurSJkVMS+kClIFSX/LLvw9ExSb+4IMtD6YnfxZVerw9ANYtW0bPrm0MJu2pfe9SY9FJ9FtQ+MdZkrZwjg==", "dev": true, "requires": { - "@jest/console": "^26.6.2", - "@jest/reporters": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/console": "^27.4.6", + "@jest/reporters": "^27.4.6", + "@jest/test-result": "^27.4.6", + "@jest/transform": "^27.4.6", + "@jest/types": "^27.4.2", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", + "emittery": "^0.8.1", "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "jest-changed-files": "^26.6.2", - "jest-config": "^26.6.3", - "jest-haste-map": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-resolve-dependencies": "^26.6.3", - "jest-runner": "^26.6.3", - "jest-runtime": "^26.6.3", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "jest-watcher": "^26.6.2", - "micromatch": "^4.0.2", - "p-each-series": "^2.1.0", + "jest-changed-files": "^27.4.2", + "jest-config": "^27.4.7", + "jest-haste-map": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-regex-util": "^27.4.0", + "jest-resolve": "^27.4.6", + "jest-resolve-dependencies": "^27.4.6", + "jest-runner": "^27.4.6", + "jest-runtime": "^27.4.6", + "jest-snapshot": "^27.4.6", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.6", + "jest-watcher": "^27.4.6", + "micromatch": "^4.0.4", "rimraf": "^3.0.0", "slash": "^3.0.0", "strip-ansi": "^6.0.0" @@ -13668,9 +14154,9 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -13710,73 +14196,73 @@ } }, "@jest/environment": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", - "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.4.6.tgz", + "integrity": "sha512-E6t+RXPfATEEGVidr84WngLNWZ8ffCPky8RqqRK6u1Bn0LK92INe0MDttyPl/JOzaq92BmDzOeuqk09TvM22Sg==", "dev": true, "requires": { - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/fake-timers": "^27.4.6", + "@jest/types": "^27.4.2", "@types/node": "*", - "jest-mock": "^26.6.2" + "jest-mock": "^27.4.6" } }, "@jest/fake-timers": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", - "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.4.6.tgz", + "integrity": "sha512-mfaethuYF8scV8ntPpiVGIHQgS0XIALbpY2jt2l7wb/bvq4Q5pDLk4EP4D7SAvYT1QrPOPVZAtbdGAOOyIgs7A==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "@sinonjs/fake-timers": "^6.0.1", + "@jest/types": "^27.4.2", + "@sinonjs/fake-timers": "^8.0.1", "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" + "jest-message-util": "^27.4.6", + "jest-mock": "^27.4.6", + "jest-util": "^27.4.2" } }, "@jest/globals": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz", - "integrity": "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.4.6.tgz", + "integrity": "sha512-kAiwMGZ7UxrgPzu8Yv9uvWmXXxsy0GciNejlHvfPIfWkSxChzv6bgTS3YqBkGuHcis+ouMFI2696n2t+XYIeFw==", "dev": true, "requires": { - "@jest/environment": "^26.6.2", - "@jest/types": "^26.6.2", - "expect": "^26.6.2" + "@jest/environment": "^27.4.6", + "@jest/types": "^27.4.2", + "expect": "^27.4.6" } }, "@jest/reporters": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz", - "integrity": "sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.4.6.tgz", + "integrity": "sha512-+Zo9gV81R14+PSq4wzee4GC2mhAN9i9a7qgJWL90Gpx7fHYkWpTBvwWNZUXvJByYR9tAVBdc8VxDWqfJyIUrIQ==", "dev": true, "requires": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/console": "^27.4.6", + "@jest/test-result": "^27.4.6", + "@jest/transform": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/node": "*", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", "glob": "^7.1.2", "graceful-fs": "^4.2.4", "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-instrument": "^5.1.0", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "jest-haste-map": "^26.6.2", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "node-notifier": "^8.0.0", + "istanbul-reports": "^3.1.3", + "jest-haste-map": "^27.4.6", + "jest-resolve": "^27.4.6", + "jest-util": "^27.4.2", + "jest-worker": "^27.4.6", "slash": "^3.0.0", "source-map": "^0.6.0", "string-length": "^4.0.1", "terminal-link": "^2.0.0", - "v8-to-istanbul": "^7.0.0" + "v8-to-istanbul": "^8.1.0" }, "dependencies": { "ansi-styles": { @@ -13789,9 +14275,9 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -13837,9 +14323,9 @@ } }, "@jest/source-map": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz", - "integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.4.0.tgz", + "integrity": "sha512-Ntjx9jzP26Bvhbm93z/AKcPRj/9wrkI88/gK60glXDx1q+IeI0rf7Lw2c89Ch6ofonB0On/iRDreQuQ6te9pgQ==", "dev": true, "requires": { "callsites": "^3.0.0", @@ -13856,48 +14342,47 @@ } }, "@jest/test-result": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", - "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.4.6.tgz", + "integrity": "sha512-fi9IGj3fkOrlMmhQqa/t9xum8jaJOOAi/lZlm6JXSc55rJMXKHxNDN1oCP39B0/DhNOa2OMupF9BcKZnNtXMOQ==", "dev": true, "requires": { - "@jest/console": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/console": "^27.4.6", + "@jest/types": "^27.4.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/test-sequencer": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz", - "integrity": "sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.4.6.tgz", + "integrity": "sha512-3GL+nsf6E1PsyNsJuvPyIz+DwFuCtBdtvPpm/LMXVkBJbdFvQYCDpccYT56qq5BGniXWlE81n2qk1sdXfZebnw==", "dev": true, "requires": { - "@jest/test-result": "^26.6.2", + "@jest/test-result": "^27.4.6", "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.6.2", - "jest-runner": "^26.6.3", - "jest-runtime": "^26.6.3" + "jest-haste-map": "^27.4.6", + "jest-runtime": "^27.4.6" } }, "@jest/transform": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz", - "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.4.6.tgz", + "integrity": "sha512-9MsufmJC8t5JTpWEQJ0OcOOAXaH5ioaIX6uHVBLBMoCZPfKKQF+EqP8kACAvCZ0Y1h2Zr3uOccg8re+Dr5jxyw==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/types": "^26.6.2", - "babel-plugin-istanbul": "^6.0.0", + "@jest/types": "^27.4.2", + "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-util": "^26.6.2", - "micromatch": "^4.0.2", - "pirates": "^4.0.1", + "jest-haste-map": "^27.4.6", + "jest-regex-util": "^27.4.0", + "jest-util": "^27.4.2", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", "slash": "^3.0.0", "source-map": "^0.6.1", "write-file-atomic": "^3.0.0" @@ -13913,9 +14398,9 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -13961,15 +14446,15 @@ } }, "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.4.2.tgz", + "integrity": "sha512-j35yw0PMTPpZsUoOBiuHzr1zTYoad1cVIE0ajEjcrJONxxrko/IRGKkXx3os0Nsi4Hu3+5VmDbVfq5WhG/pWAg==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", - "@types/yargs": "^15.0.0", + "@types/yargs": "^16.0.0", "chalk": "^4.0.0" }, "dependencies": { @@ -13983,9 +14468,9 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -14024,6 +14509,28 @@ } } }, + "@jridgewell/resolve-uri": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", + "integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", + "integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", + "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "@sinonjs/commons": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", @@ -14034,18 +14541,41 @@ } }, "@sinonjs/fake-timers": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", - "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", + "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", "dev": true, "requires": { "@sinonjs/commons": "^1.7.0" } }, + "@sinonjs/samsam": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.3.1.tgz", + "integrity": "sha512-1Hc0b1TtyfBu8ixF/tpfSHTVWKwCBLY4QJbkgnE7HcwyvT2xArDxb4K7dMgqRm3szI+LJbzmW/s4xxEhv6hwDg==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.6.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + } + }, + "@sinonjs/text-encoding": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", + "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "dev": true + }, + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true + }, "@types/babel__core": { - "version": "7.1.14", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.14.tgz", - "integrity": "sha512-zGZJzzBUVDo/eV6KgbE0f0ZI7dInEYvo12Rb70uNQDshC3SkRMb67ja0GgRHZgAX3Za6rhaWlvbDO8rrGyAb1g==", + "version": "7.1.18", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.18.tgz", + "integrity": "sha512-S7unDjm/C7z2A2R9NzfKCK1I+BAALDtxEmsJBwlB3EzNfb929ykjL++1CK9LO++EIp2fQrC8O+BwjKvz6UeDyQ==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -14056,18 +14586,18 @@ } }, "@types/babel__generator": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.2.tgz", - "integrity": "sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", "dev": true, "requires": { "@babel/types": "^7.0.0" } }, "@types/babel__template": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.0.tgz", - "integrity": "sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A==", + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -14075,9 +14605,9 @@ } }, "@types/babel__traverse": { - "version": "7.11.1", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.11.1.tgz", - "integrity": "sha512-Vs0hm0vPahPMYi9tDjtP66llufgO3ST16WXaSTtDGEl9cewAl3AibmxWw6TINOqHPT9z0uABKAYjT9jNSg4npw==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", + "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", "dev": true, "requires": { "@babel/types": "^7.3.0" @@ -14093,6 +14623,12 @@ "@types/har-format": "*" } }, + "@types/dateformat": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/dateformat/-/dateformat-3.0.1.tgz", + "integrity": "sha512-KlPPdikagvL6ELjWsljbyDIPzNCeliYkqRpI+zea99vBBbCIA5JNshZAwQKTON139c87y9qvTFVgkFd14rtS4g==", + "dev": true + }, "@types/filesystem": { "version": "0.0.30", "resolved": "https://registry.npmjs.org/@types/filesystem/-/filesystem-0.0.30.tgz", @@ -14124,9 +14660,9 @@ "dev": true }, "@types/istanbul-lib-coverage": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", "dev": true }, "@types/istanbul-lib-report": { @@ -14139,14 +14675,24 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "requires": { "@types/istanbul-lib-report": "*" } }, + "@types/jest": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.0.tgz", + "integrity": "sha512-gHl8XuC1RZ8H2j5sHv/JqsaxXkDDM9iDOgu0Wp8sjs4u/snb2PVehyWXJPr+ORA0RPpgw231mnutWI1+0hgjIQ==", + "dev": true, + "requires": { + "jest-diff": "^27.0.0", + "pretty-format": "^27.0.0" + } + }, "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -14159,45 +14705,64 @@ "integrity": "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA==", "dev": true }, + "@types/mkdirp": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-1.0.2.tgz", + "integrity": "sha512-o0K1tSO0Dx5X6xlU5F1D6625FawhC3dU3iqr25lluNv/+/QIVH8RLNEiVokgIZo+mz+87w/3Mkg/VvQS+J51fQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/node": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-15.3.0.tgz", - "integrity": "sha512-8/bnjSZD86ZfpBsDlCIkNXIvm+h6wi9g7IqL+kmFkQ+Wvu3JrasgLElfiPgoo8V8vVfnEi0QVS12gbl94h9YsQ==", + "version": "16.11.25", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.25.tgz", + "integrity": "sha512-NrTwfD7L1RTc2qrHQD4RTTy4p0CO2LatKBEKEds3CaVuhoM/+DJzmWZl5f+ikR8cm8F5mfJxK+9rQq07gRiSjQ==", "dev": true }, - "@types/normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "@types/prettier": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.3.tgz", + "integrity": "sha512-QzSuZMBuG5u8HqYz01qtMdg/Jfctlnvj1z/lYnIDXs/golxw0fxtRAHd9KrzjR7Yxz1qVeI00o0kiO3PmVdJ9w==", "dev": true }, - "@types/prettier": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz", - "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==", + "@types/sinon": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-7.5.2.tgz", + "integrity": "sha512-T+m89VdXj/eidZyejvmoP9jivXgBDdkOSBVQjU9kF349NEx10QdPNGxHeZUaj1IlJ32/ewdyXJjnJxyxJroYwg==", "dev": true }, "@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, "@types/yargs": { - "version": "15.0.13", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.13.tgz", - "integrity": "sha512-kQ5JNTrbDv3Rp5X2n/iUu37IJBDU2gsZ5R/g1/KHOOEc5IKfUFjXT6DENPGduh08I/pamwtEq4oul7gUqKTQDQ==", + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", "dev": true, "requires": { "@types/yargs-parser": "*" } }, "@types/yargs-parser": { - "version": "20.2.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz", - "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==", + "version": "20.2.1", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", + "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", "dev": true }, + "@types/yauzl": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz", + "integrity": "sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==", + "dev": true, + "optional": true, + "requires": { + "@types/node": "*" + } + }, "abab": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", @@ -14249,15 +14814,24 @@ "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", "dev": true }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "requires": { + "debug": "4" + } + }, "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.10.0.tgz", + "integrity": "sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", "uri-js": "^4.2.2" } }, @@ -14285,9 +14859,9 @@ } }, "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, "ansi-styles": { @@ -14318,24 +14892,6 @@ "sprintf-js": "~1.0.2" } }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, "array-differ": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", @@ -14379,12 +14935,6 @@ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, "array.prototype.flat": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", @@ -14474,13 +15024,7 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true }, "astral-regex": { @@ -14501,12 +15045,6 @@ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "dev": true }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, "available-typed-arrays": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz", @@ -14529,16 +15067,16 @@ "dev": true }, "babel-jest": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.6.3.tgz", - "integrity": "sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.4.6.tgz", + "integrity": "sha512-qZL0JT0HS1L+lOuH+xC2DVASR3nunZi/ozGhpgauJHgmI7f8rudxf6hUjEHympdQ/J64CdKmPkgfJ+A3U6QCrg==", "dev": true, "requires": { - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/babel__core": "^7.1.7", - "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^26.6.2", + "@jest/transform": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^27.4.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "slash": "^3.0.0" @@ -14554,9 +15092,9 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -14605,22 +15143,22 @@ } }, "babel-plugin-istanbul": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", - "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@istanbuljs/load-nyc-config": "^1.0.0", "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-instrument": "^5.0.4", "test-exclude": "^6.0.0" } }, "babel-plugin-jest-hoist": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz", - "integrity": "sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.4.0.tgz", + "integrity": "sha512-Jcu7qS4OX5kTWBc45Hz7BMmgXuJqRnhatqpUhnzGC3OBYpOmf2tv6jFNwZpwM7wU7MUuv2r9IPS/ZlYOuburVw==", "dev": true, "requires": { "@babel/template": "^7.3.3", @@ -14630,33 +15168,33 @@ } }, "babel-plugin-polyfill-corejs2": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.0.tgz", - "integrity": "sha512-9bNwiR0dS881c5SHnzCmmGlMkJLl0OUZvxrxHo9w/iNoRuqaPjqlvBf4HrovXtQs/au5yKkpcdgfT1cC5PAZwg==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz", + "integrity": "sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w==", "dev": true, "requires": { "@babel/compat-data": "^7.13.11", - "@babel/helper-define-polyfill-provider": "^0.2.0", + "@babel/helper-define-polyfill-provider": "^0.3.1", "semver": "^6.1.1" } }, "babel-plugin-polyfill-corejs3": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.0.tgz", - "integrity": "sha512-zZyi7p3BCUyzNxLx8KV61zTINkkV65zVkDAFNZmrTCRVhjo1jAS+YLvDJ9Jgd/w2tsAviCwFHReYfxO3Iql8Yg==", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.2.tgz", + "integrity": "sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ==", "dev": true, "requires": { - "@babel/helper-define-polyfill-provider": "^0.2.0", - "core-js-compat": "^3.9.1" + "@babel/helper-define-polyfill-provider": "^0.3.1", + "core-js-compat": "^3.21.0" } }, "babel-plugin-polyfill-regenerator": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.0.tgz", - "integrity": "sha512-J7vKbCuD2Xi/eEHxquHN14bXAW9CXtecwuLrOIDJtcZzTaPzV1VdEfoUf9AzcRBMolKUQKM9/GVojeh0hFiqMg==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz", + "integrity": "sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A==", "dev": true, "requires": { - "@babel/helper-define-polyfill-provider": "^0.2.0" + "@babel/helper-define-polyfill-provider": "^0.3.1" } }, "babel-preset-current-node-syntax": { @@ -14680,12 +15218,12 @@ } }, "babel-preset-jest": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz", - "integrity": "sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.4.0.tgz", + "integrity": "sha512-NK4jGYpnBvNxcGo7/ZpZJr51jCGT+3bwwpVIDY2oNfTxJJldRtB4VAcYdgp1loDE50ODuTu+yBjpMAswv5tlpg==", "dev": true, "requires": { - "babel-plugin-jest-hoist": "^26.6.2", + "babel-plugin-jest-hoist": "^27.4.0", "babel-preset-current-node-syntax": "^1.0.0" } }, @@ -14701,61 +15239,6 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -14777,6 +15260,40 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + }, + "dependencies": { + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -15067,16 +15584,16 @@ } }, "browserslist": { - "version": "4.16.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.5.tgz", - "integrity": "sha512-C2HAjrM1AI/djrpAUU/tr4pml1DqLIzJKSLDBXBrNErl9ZCCTXdhwxdJjYc16953+mBWf7Lw+uUJgpgb8cN71A==", + "version": "4.19.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.3.tgz", + "integrity": "sha512-XK3X4xtKJ+Txj8G5c30B4gsm71s69lqXlkYui4s6EkKxuv49qjYlY6oVd+IFJ73d4YymtM3+djvvt/R/iJwwDg==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001214", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.719", + "caniuse-lite": "^1.0.30001312", + "electron-to-chromium": "^1.4.71", "escalade": "^3.1.1", - "node-releases": "^1.1.71" + "node-releases": "^2.0.2", + "picocolors": "^1.0.0" } }, "bser": { @@ -15098,6 +15615,12 @@ "ieee754": "^1.1.4" } }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", @@ -15122,23 +15645,6 @@ "integrity": "sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=", "dev": true }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, "cached-path-relative": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.2.tgz", @@ -15168,20 +15674,11 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001219", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001219.tgz", - "integrity": "sha512-c0yixVG4v9KBc/tQ2rlbB3A/bgBFRvl8h8M4IeUbqCca4gsiCfvtaheUssbnux/Mb66Vjz7x8yYjDgYcNQOhyQ==", + "version": "1.0.30001312", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz", + "integrity": "sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ==", "dev": true }, - "capture-exit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", - "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", - "dev": true, - "requires": { - "rsvp": "^4.8.4" - } - }, "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", @@ -15221,10 +15718,16 @@ "readdirp": "~3.5.0" } }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", + "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==", "dev": true }, "cipher-base": { @@ -15238,43 +15741,20 @@ } }, "cjs-module-lexer": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz", - "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", "dev": true }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" + "wrap-ansi": "^7.0.0" } }, "co": { @@ -15289,16 +15769,6 @@ "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", "dev": true }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -15314,12 +15784,6 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, - "colorette": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", - "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", - "dev": true - }, "colors": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", @@ -15355,12 +15819,6 @@ "delayed-stream": "~1.0.0" } }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -15412,19 +15870,13 @@ "safe-buffer": "~5.1.1" } }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, "core-js-compat": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.11.0.tgz", - "integrity": "sha512-3wsN9YZJohOSDCjVB0GequOyHax8zFiogSX3XWLE28M1Ew7dTU57tgHjIylSBKSIouwmLBp3g61sKMz/q3xEGA==", + "version": "3.21.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.21.1.tgz", + "integrity": "sha512-gbgX5AUvMb8gwxC7FLVWYT7Kkgu/y7+h/h1X43yJkNqhlK2fuYyQimqvKGNZFAY6CKii/GFKJ2cp/1/42TN36g==", "dev": true, "requires": { - "browserslist": "^4.16.4", + "browserslist": "^4.19.1", "semver": "7.0.0" }, "dependencies": { @@ -15573,30 +16025,24 @@ "dev": true }, "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "requires": { "ms": "2.1.2" } }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, "decimal.js": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz", - "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==", + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", + "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", "dev": true }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", "dev": true }, "deep-is": { @@ -15620,47 +16066,6 @@ "object-keys": "^1.0.12" } }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, "defined": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", @@ -15718,10 +16123,22 @@ "minimist": "^1.1.1" } }, + "devtools-protocol": { + "version": "0.0.948846", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.948846.tgz", + "integrity": "sha512-5fGyt9xmMqUl2VI7+rnUkKCiAQIpLns8sfQtTENy5L70ktbNw0Z3TFJ1JoFNYdx/jffz4YXU45VF75wKZD7sZQ==", + "dev": true + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, "diff-sequences": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", - "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.4.0.tgz", + "integrity": "sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww==", "dev": true }, "diffie-hellman": { @@ -15795,9 +16212,9 @@ } }, "electron-to-chromium": { - "version": "1.3.723", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.723.tgz", - "integrity": "sha512-L+WXyXI7c7+G1V8ANzRsPI5giiimLAUDC6Zs1ojHHPhYXb3k/iTABFmWjivEtsWrRQymjnO66/rO2ZTABGdmWg==", + "version": "1.4.71", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.71.tgz", + "integrity": "sha512-Hk61vXXKRb2cd3znPE9F+2pLWdIOmP7GjiTj45y6L3W/lO+hSnUSUhq+6lEaERWBdZOHbk2s3YV5c9xVl3boVw==", "dev": true }, "elliptic": { @@ -15824,9 +16241,9 @@ } }, "emittery": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", - "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==", + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", + "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", "dev": true }, "emoji-regex": { @@ -15938,9 +16355,9 @@ }, "dependencies": { "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true }, "levn": { @@ -16045,6 +16462,18 @@ "@babel/highlight": "^7.10.4" } }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -16100,6 +16529,12 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", @@ -16388,76 +16823,21 @@ "safe-buffer": "^5.1.1" } }, - "exec-sh": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.6.tgz", - "integrity": "sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w==", - "dev": true - }, "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "dependencies": { - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" } }, "exit": { @@ -16466,103 +16846,25 @@ "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", "dev": true }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, "expand-tilde": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", "dev": true, "requires": { - "homedir-polyfill": "^1.0.1" - } - }, - "expect": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", - "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "ansi-styles": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - } + "homedir-polyfill": "^1.0.1" + } + }, + "expect": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.4.6.tgz", + "integrity": "sha512-1M/0kAALIaj5LaG66sFJTbRsWTADnylly82cu4bspI0nl+pgP4E6Bh/aqdHlTUjul06K7xQnnrAoqfxVU0+/ag==", + "dev": true, + "requires": { + "@jest/types": "^27.4.2", + "jest-get-type": "^27.4.0", + "jest-matcher-utils": "^27.4.6", + "jest-message-util": "^27.4.6" } }, "extend": { @@ -16571,88 +16873,25 @@ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", "dev": true, "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "@types/yauzl": "^2.9.1", + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" }, "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "pump": "^3.0.0" } } } @@ -16663,6 +16902,15 @@ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", "dev": true }, + "fast-check": { + "version": "2.22.0", + "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-2.22.0.tgz", + "integrity": "sha512-Yrx1E8fZk6tfSqYaNkwnxj/lOk+vj2KTbbpHDtYoK9MrrL/D204N/rCtcaVSz5bE29g6gW4xj0byresjlFyybg==", + "dev": true, + "requires": { + "pure-rand": "^5.0.0" + } + }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -16705,6 +16953,15 @@ "bser": "2.1.1" } }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, "file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -16829,14 +17086,11 @@ "mime-types": "^2.1.12" } }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true }, "fs.realpath": { "version": "1.0.0", @@ -16908,18 +17162,9 @@ "dev": true }, "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true }, "getobject": { @@ -17023,7 +17268,8 @@ "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", "dev": true, - "optional": true + "optional": true, + "peer": true }, "grunt": { "version": "1.4.0", @@ -17305,6 +17551,26 @@ "requires": { "ajv": "^6.12.3", "har-schema": "^2.0.0" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + } } }, "has": { @@ -17334,58 +17600,6 @@ "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", "dev": true }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "hash-base": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", @@ -17485,6 +17699,17 @@ "integrity": "sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg==", "dev": true }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + } + }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -17502,10 +17727,20 @@ "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", "dev": true }, + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, "human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true }, "iconv-lite": { @@ -17540,9 +17775,9 @@ } }, "import-local": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", - "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", "dev": true, "requires": { "pkg-dir": "^4.2.0", @@ -17680,26 +17915,6 @@ "is-windows": "^1.0.1" } }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "is-arguments": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", @@ -17758,6 +17973,14 @@ "dev": true, "requires": { "ci-info": "^2.0.0" + }, + "dependencies": { + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + } } }, "is-core-module": { @@ -17769,63 +17992,19 @@ "has": "^1.0.3" } }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "is-date-object": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", "dev": true }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, "is-docker": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "dev": true, - "optional": true - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true + "optional": true, + "peer": true }, "is-extglob": { "version": "2.1.1", @@ -17852,9 +18031,9 @@ "dev": true }, "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "requires": { "is-extglob": "^2.1.1" @@ -17913,9 +18092,9 @@ } }, "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true }, "is-string": { @@ -17973,6 +18152,7 @@ "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "dev": true, "optional": true, + "peer": true, "requires": { "is-docker": "^2.0.0" } @@ -18002,20 +18182,21 @@ "dev": true }, "istanbul-lib-coverage": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", "dev": true }, "istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz", + "integrity": "sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==", "dev": true, "requires": { - "@babel/core": "^7.7.5", + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-coverage": "^3.2.0", "semver": "^6.3.0" } }, @@ -18047,44 +18228,259 @@ } } }, - "istanbul-lib-source-maps": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", - "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "istanbul-reports": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.3.tgz", + "integrity": "sha512-x9LtDVtfm/t1GFiLl3NffC7hz+I1ragvgX1P/Lg1NlIagifZDKUkuuaAxH/qpwj2IuEfD8G2Bs/UKp+sZ/pKkg==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jasmine": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-4.0.2.tgz", + "integrity": "sha512-YsrgxJQEggxzByYe4j68eQLOiQeSrPDYGv4sHhGBp3c6HHdq+uPXeAQ73kOAQpdLZ3/0zN7x/TZTloqeE1/qIA==", + "dev": true, + "requires": { + "glob": "^7.1.6", + "jasmine-core": "^4.0.0" + } + }, + "jasmine-core": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.0.0.tgz", + "integrity": "sha512-tq24OCqHElgU9KDpb/8O21r1IfotgjIzalfW9eCmRR40LZpvwXT68iariIyayMwi0m98RDt16aljdbwK0sBMmQ==", + "dev": true + }, + "jest": { + "version": "27.4.7", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.4.7.tgz", + "integrity": "sha512-8heYvsx7nV/m8m24Vk26Y87g73Ba6ueUd0MWed/NXMhSZIm62U/llVbS0PJe1SHunbyXjJ/BqG1z9bFjGUIvTg==", + "dev": true, + "requires": { + "@jest/core": "^27.4.7", + "import-local": "^3.0.2", + "jest-cli": "^27.4.7" + } + }, + "jest-changed-files": { + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.4.2.tgz", + "integrity": "sha512-/9x8MjekuzUQoPjDHbBiXbNEBauhrPU2ct7m8TfCg69ywt1y/N+yYwGh3gCpnqUS3klYWDU/lSNgv+JhoD2k1A==", + "dev": true, + "requires": { + "@jest/types": "^27.4.2", + "execa": "^5.0.0", + "throat": "^6.0.1" + } + }, + "jest-chrome": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/jest-chrome/-/jest-chrome-0.7.1.tgz", + "integrity": "sha512-rUsDoOIxvZr4JpzyYWepE5/l0xM5VO6010g93jhbaeYwJaJGpazYIClbLtbeWg+zUxMJvLdN3iDMvT6m8wNMwA==", + "dev": true, + "requires": { + "@types/chrome": "^0.0.114" + } + }, + "jest-circus": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.4.6.tgz", + "integrity": "sha512-UA7AI5HZrW4wRM72Ro80uRR2Fg+7nR0GESbSI/2M+ambbzVuA63mn5T1p3Z/wlhntzGpIG1xx78GP2YIkf6PhQ==", + "dev": true, + "requires": { + "@jest/environment": "^27.4.6", + "@jest/test-result": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "expect": "^27.4.6", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.4.6", + "jest-matcher-utils": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-runtime": "^27.4.6", + "jest-snapshot": "^27.4.6", + "jest-util": "^27.4.2", + "pretty-format": "^27.4.6", + "slash": "^3.0.0", + "stack-utils": "^2.0.3", + "throat": "^6.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-cli": { + "version": "27.4.7", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.4.7.tgz", + "integrity": "sha512-zREYhvjjqe1KsGV15mdnxjThKNDgza1fhDT+iUsXWLCq3sxe9w5xnvyctcYVT5PcdLSjv7Y5dCwTS3FCF1tiuw==", "dev": true, "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" + "@jest/core": "^27.4.7", + "@jest/test-result": "^27.4.6", + "@jest/types": "^27.4.2", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "jest-config": "^27.4.7", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.6", + "prompts": "^2.0.1", + "yargs": "^16.2.0" }, "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } } } }, - "istanbul-reports": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", - "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", - "dev": true, - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "jest": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest/-/jest-26.6.3.tgz", - "integrity": "sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==", + "jest-config": { + "version": "27.4.7", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.4.7.tgz", + "integrity": "sha512-xz/o/KJJEedHMrIY9v2ParIoYSrSVY6IVeE4z5Z3i101GoA5XgfbJz+1C8EYPsv7u7f39dS8F9v46BHDhn0vlw==", "dev": true, "requires": { - "@jest/core": "^26.6.3", - "import-local": "^3.0.2", - "jest-cli": "^26.6.3" + "@babel/core": "^7.8.0", + "@jest/test-sequencer": "^27.4.6", + "@jest/types": "^27.4.2", + "babel-jest": "^27.4.6", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-circus": "^27.4.6", + "jest-environment-jsdom": "^27.4.6", + "jest-environment-node": "^27.4.6", + "jest-get-type": "^27.4.0", + "jest-jasmine2": "^27.4.6", + "jest-regex-util": "^27.4.0", + "jest-resolve": "^27.4.6", + "jest-runner": "^27.4.6", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.6", + "micromatch": "^4.0.4", + "pretty-format": "^27.4.6", + "slash": "^3.0.0" }, "dependencies": { "ansi-styles": { @@ -18097,9 +18493,9 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -18127,27 +18523,6 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "jest-cli": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz", - "integrity": "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==", - "dev": true, - "requires": { - "@jest/core": "^26.6.3", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "import-local": "^3.0.2", - "is-ci": "^2.0.0", - "jest-config": "^26.6.3", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "prompts": "^2.0.1", - "yargs": "^15.4.1" - } - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -18159,93 +18534,89 @@ } } }, - "jest-changed-files": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.6.2.tgz", - "integrity": "sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ==", + "jest-diff": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.4.6.tgz", + "integrity": "sha512-zjaB0sh0Lb13VyPsd92V7HkqF6yKRH9vm33rwBt7rPYrpQvS1nCvlIy2pICbKta+ZjWngYLNn4cCK4nyZkjS/w==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "execa": "^4.0.0", - "throat": "^5.0.0" + "chalk": "^4.0.0", + "diff-sequences": "^27.4.0", + "jest-get-type": "^27.4.0", + "pretty-format": "^27.4.6" }, "dependencies": { - "execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" + "color-convert": "^2.0.1" } }, - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { - "pump": "^3.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { - "path-key": "^3.0.0" + "has-flag": "^4.0.0" } } } }, - "jest-chrome": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/jest-chrome/-/jest-chrome-0.7.1.tgz", - "integrity": "sha512-rUsDoOIxvZr4JpzyYWepE5/l0xM5VO6010g93jhbaeYwJaJGpazYIClbLtbeWg+zUxMJvLdN3iDMvT6m8wNMwA==", + "jest-docblock": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.4.0.tgz", + "integrity": "sha512-7TBazUdCKGV7svZ+gh7C8esAnweJoG+SvcF6Cjqj4l17zA2q1cMwx2JObSioubk317H+cjcHgP+7fTs60paulg==", "dev": true, "requires": { - "@types/chrome": "^0.0.114" + "detect-newline": "^3.0.0" } }, - "jest-config": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", - "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", + "jest-each": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.4.6.tgz", + "integrity": "sha512-n6QDq8y2Hsmn22tRkgAk+z6MCX7MeVlAzxmZDshfS2jLcaBlyhpF3tZSJLR+kXmh23GEvS0ojMR8i6ZeRvpQcA==", "dev": true, "requires": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.6.3", - "@jest/types": "^26.6.2", - "babel-jest": "^26.6.3", + "@jest/types": "^27.4.2", "chalk": "^4.0.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.6.2", - "jest-environment-node": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-jasmine2": "^26.6.3", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2" + "jest-get-type": "^27.4.0", + "jest-util": "^27.4.2", + "pretty-format": "^27.4.6" }, "dependencies": { "ansi-styles": { @@ -18258,59 +18629,256 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-environment-jsdom": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.4.6.tgz", + "integrity": "sha512-o3dx5p/kHPbUlRvSNjypEcEtgs6LmvESMzgRFQE6c+Prwl2JLA4RZ7qAnxc5VM8kutsGRTB15jXeeSbJsKN9iA==", + "dev": true, + "requires": { + "@jest/environment": "^27.4.6", + "@jest/fake-timers": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/node": "*", + "jest-mock": "^27.4.6", + "jest-util": "^27.4.2", + "jsdom": "^16.6.0" + } + }, + "jest-environment-node": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.4.6.tgz", + "integrity": "sha512-yfHlZ9m+kzTKZV0hVfhVu6GuDxKAYeFHrfulmy7Jxwsq4V7+ZK7f+c0XP/tbVDMQW7E4neG2u147hFkuVz0MlQ==", + "dev": true, + "requires": { + "@jest/environment": "^27.4.6", + "@jest/fake-timers": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/node": "*", + "jest-mock": "^27.4.6", + "jest-util": "^27.4.2" + } + }, + "jest-get-type": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.4.0.tgz", + "integrity": "sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ==", + "dev": true + }, + "jest-haste-map": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.4.6.tgz", + "integrity": "sha512-0tNpgxg7BKurZeFkIOvGCkbmOHbLFf4LUQOxrQSMjvrQaQe3l6E8x6jYC1NuWkGo5WDdbr8FEzUxV2+LWNawKQ==", + "dev": true, + "requires": { + "@jest/types": "^27.4.2", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.3.2", + "graceful-fs": "^4.2.4", + "jest-regex-util": "^27.4.0", + "jest-serializer": "^27.4.0", + "jest-util": "^27.4.2", + "jest-worker": "^27.4.6", + "micromatch": "^4.0.4", + "walker": "^1.0.7" + } + }, + "jest-html-reporter": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/jest-html-reporter/-/jest-html-reporter-3.4.2.tgz", + "integrity": "sha512-2dA4oJdLP2+rewakwLdBhBCdk50zqzgD6Wk0fvsbdS0C9WwpuePwd0kQWRRdfLzNJM5CgC4O98wkK1lBFqJVrw==", + "dev": true, + "requires": { + "@babel/core": "^7.9.0", + "@babel/preset-env": "^7.8.7", + "@babel/preset-typescript": "^7.8.3", + "@jest/console": "^25.1.0", + "@jest/test-result": "^25.1.0", + "@jest/types": "^26.0.23", + "@types/dateformat": "^3.0.1", + "@types/jest": "^25.1.4", + "@types/mkdirp": "^1.0.0", + "@types/node": "^12.12.7", + "@types/sinon": "^7.5.2", + "dateformat": "3.0.2", + "mkdirp": "^1.0.3", + "sinon": "^9.0.1", + "strip-ansi": "6.0.1", + "xmlbuilder": "15.0.0" + }, + "dependencies": { + "@jest/console": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", + "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "jest-message-util": "^25.5.0", + "jest-util": "^25.5.0", + "slash": "^3.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, + "@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + } + } + }, + "@jest/test-result": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", + "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", + "dev": true, + "requires": { + "@jest/console": "^25.5.0", + "@jest/types": "^25.5.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, + "@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + } + } + }, + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "dependencies": { + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "@types/jest": { + "version": "25.2.3", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-25.2.3.tgz", + "integrity": "sha512-JXc1nK/tXHiDhV55dvfzqtmP4S3sy3T3ouV2tkViZgxY/zeUkcpQcQPGRlgF4KmWzWW5oiWYSZwtCB+2RsE4Fw==", "dev": true, "requires": { - "color-name": "~1.1.4" + "jest-diff": "^25.2.1", + "pretty-format": "^25.2.1" } }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "@types/node": { + "version": "12.20.46", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.46.tgz", + "integrity": "sha512-cPjLXj8d6anFPzFvOPxS3fvly3Shm5nTfl6g8X5smexixbuGUf7hfr21J5tX9JW+UPStp/5P5R8qrKL5IyVJ+A==", "dev": true }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", "dev": true }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "@types/yargs": { + "version": "15.0.14", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", + "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", "dev": true, "requires": { - "has-flag": "^4.0.0" + "@types/yargs-parser": "*" } - } - } - }, - "jest-diff": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", - "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - }, - "dependencies": { + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -18321,9 +18889,9 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -18345,84 +18913,175 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "dateformat": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.2.tgz", + "integrity": "sha1-mk30v/FYrC80vGN6vbFUcWB+Flk=", + "dev": true + }, + "diff-sequences": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", + "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", + "dev": true + }, + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "jest-diff": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", "dev": true, "requires": { - "has-flag": "^4.0.0" + "chalk": "^3.0.0", + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" } - } - } - }, - "jest-docblock": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", - "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", - "dev": true, - "requires": { - "detect-newline": "^3.0.0" - } - }, - "jest-each": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", - "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + }, + "jest-get-type": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "dev": true + }, + "jest-message-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", "dev": true, "requires": { - "color-convert": "^2.0.1" + "@babel/code-frame": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^1.0.1" + }, + "dependencies": { + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, + "@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + } } }, - "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "jest-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, + "@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + } } }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "pretty-format": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", "dev": true, "requires": { - "color-name": "~1.1.4" + "@jest/types": "^25.5.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + }, + "dependencies": { + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, + "@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + } } }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "dev": true }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "stack-utils": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.5.tgz", + "integrity": "sha512-KZiTzuV3CnSnSvgMRrARVCj+Ht7rMbauGDK0LdVFRGyenwdylpajAp4Q0i6SX8rEmbTpMMf6ryq2gb8pPq2WgQ==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + } }, "supports-color": { "version": "7.2.0", @@ -18435,87 +19094,29 @@ } } }, - "jest-environment-jsdom": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz", - "integrity": "sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==", - "dev": true, - "requires": { - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2", - "jsdom": "^16.4.0" - } - }, - "jest-environment-node": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.2.tgz", - "integrity": "sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==", - "dev": true, - "requires": { - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" - } - }, - "jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true - }, - "jest-haste-map": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", - "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.1.2", - "graceful-fs": "^4.2.4", - "jest-regex-util": "^26.0.0", - "jest-serializer": "^26.6.2", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "micromatch": "^4.0.2", - "sane": "^4.0.3", - "walker": "^1.0.7" - } - }, "jest-jasmine2": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz", - "integrity": "sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.4.6.tgz", + "integrity": "sha512-uAGNXF644I/whzhsf7/qf74gqy9OuhvJ0XYp8SDecX2ooGeaPnmJMjXjKt0mqh1Rl5dtRGxJgNrHlBQIBfS5Nw==", "dev": true, "requires": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^26.6.2", - "@jest/source-map": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/environment": "^27.4.6", + "@jest/source-map": "^27.4.0", + "@jest/test-result": "^27.4.6", + "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "expect": "^26.6.2", + "expect": "^27.4.6", "is-generator-fn": "^2.0.0", - "jest-each": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-runtime": "^26.6.3", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2", - "throat": "^5.0.0" + "jest-each": "^27.4.6", + "jest-matcher-utils": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-runtime": "^27.4.6", + "jest-snapshot": "^27.4.6", + "jest-util": "^27.4.2", + "pretty-format": "^27.4.6", + "throat": "^6.0.1" }, "dependencies": { "ansi-styles": { @@ -18528,9 +19129,9 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -18570,25 +19171,25 @@ } }, "jest-leak-detector": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz", - "integrity": "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.4.6.tgz", + "integrity": "sha512-kkaGixDf9R7CjHm2pOzfTxZTQQQ2gHTIWKY/JZSiYTc90bZp8kSZnUMS3uLAfwTZwc0tcMRoEX74e14LG1WapA==", "dev": true, "requires": { - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" + "jest-get-type": "^27.4.0", + "pretty-format": "^27.4.6" } }, "jest-matcher-utils": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", - "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.4.6.tgz", + "integrity": "sha512-XD4PKT3Wn1LQnRAq7ZsTI0VRuEc9OrCPFiO1XL7bftTGmfNF0DcEwMHRgqiu7NGf8ZoZDREpGrCniDkjt79WbA==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" + "jest-diff": "^27.4.6", + "jest-get-type": "^27.4.0", + "pretty-format": "^27.4.6" }, "dependencies": { "ansi-styles": { @@ -18601,9 +19202,9 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -18643,20 +19244,20 @@ } }, "jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.4.6.tgz", + "integrity": "sha512-0p5szriFU0U74czRSFjH6RyS7UYIAkn/ntwMuOwTGWrQIOh5NzXXrq72LOqIkJKKvFbPq+byZKuBz78fjBERBA==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.4.2", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", + "micromatch": "^4.0.4", + "pretty-format": "^27.4.6", "slash": "^3.0.0", - "stack-utils": "^2.0.2" + "stack-utils": "^2.0.3" }, "dependencies": { "ansi-styles": { @@ -18669,9 +19270,9 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -18711,12 +19312,12 @@ } }, "jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.4.6.tgz", + "integrity": "sha512-kvojdYRkst8iVSZ1EJ+vc1RRD9llueBjKzXzeCytH3dMM7zvPV/ULcfI2nr0v0VUgm3Bjt3hBCQvOeaBz+ZTHw==", "dev": true, "requires": { - "@jest/types": "^26.6.2", + "@jest/types": "^27.4.2", "@types/node": "*" } }, @@ -18724,27 +19325,30 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true + "dev": true, + "requires": {} }, "jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.4.0.tgz", + "integrity": "sha512-WeCpMpNnqJYMQoOjm1nTtsgbR4XHAk1u00qDoNBQoykM280+/TmgA5Qh5giC1ecy6a5d4hbSsHzpBtu5yvlbEg==", "dev": true }, "jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.4.6.tgz", + "integrity": "sha512-SFfITVApqtirbITKFAO7jOVN45UgFzcRdQanOFzjnbd+CACDoyeX7206JyU92l4cRr73+Qy/TlW51+4vHGt+zw==", "dev": true, "requires": { - "@jest/types": "^26.6.2", + "@jest/types": "^27.4.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.4.6", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.6", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", "slash": "^3.0.0" }, "dependencies": { @@ -18758,9 +19362,9 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -18782,103 +19386,11 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } - } - }, - "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - } + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true }, "supports-color": { "version": "7.2.0", @@ -18892,42 +19404,44 @@ } }, "jest-resolve-dependencies": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz", - "integrity": "sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.4.6.tgz", + "integrity": "sha512-W85uJZcFXEVZ7+MZqIPCscdjuctruNGXUZ3OHSXOfXR9ITgbUKeHj+uGcies+0SsvI5GtUfTw4dY7u9qjTvQOw==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-snapshot": "^26.6.2" + "@jest/types": "^27.4.2", + "jest-regex-util": "^27.4.0", + "jest-snapshot": "^27.4.6" } }, "jest-runner": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz", - "integrity": "sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.4.6.tgz", + "integrity": "sha512-IDeFt2SG4DzqalYBZRgbbPmpwV3X0DcntjezPBERvnhwKGWTW7C5pbbA5lVkmvgteeNfdd/23gwqv3aiilpYPg==", "dev": true, "requires": { - "@jest/console": "^26.6.2", - "@jest/environment": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/console": "^27.4.6", + "@jest/environment": "^27.4.6", + "@jest/test-result": "^27.4.6", + "@jest/transform": "^27.4.6", + "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", - "emittery": "^0.7.1", + "emittery": "^0.8.1", "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "jest-config": "^26.6.3", - "jest-docblock": "^26.0.0", - "jest-haste-map": "^26.6.2", - "jest-leak-detector": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "jest-runtime": "^26.6.3", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", + "jest-docblock": "^27.4.0", + "jest-environment-jsdom": "^27.4.6", + "jest-environment-node": "^27.4.6", + "jest-haste-map": "^27.4.6", + "jest-leak-detector": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-resolve": "^27.4.6", + "jest-runtime": "^27.4.6", + "jest-util": "^27.4.2", + "jest-worker": "^27.4.6", "source-map-support": "^0.5.6", - "throat": "^5.0.0" + "throat": "^6.0.1" }, "dependencies": { "ansi-styles": { @@ -18940,9 +19454,9 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -18982,38 +19496,33 @@ } }, "jest-runtime": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz", - "integrity": "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==", - "dev": true, - "requires": { - "@jest/console": "^26.6.2", - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/globals": "^26.6.2", - "@jest/source-map": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/yargs": "^15.0.0", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.4.6.tgz", + "integrity": "sha512-eXYeoR/MbIpVDrjqy5d6cGCFOYBFFDeKaNWqTp0h6E74dK0zLHzASQXJpl5a2/40euBmKnprNLJ0Kh0LCndnWQ==", + "dev": true, + "requires": { + "@jest/environment": "^27.4.6", + "@jest/fake-timers": "^27.4.6", + "@jest/globals": "^27.4.6", + "@jest/source-map": "^27.4.0", + "@jest/test-result": "^27.4.6", + "@jest/transform": "^27.4.6", + "@jest/types": "^27.4.2", "chalk": "^4.0.0", - "cjs-module-lexer": "^0.6.0", + "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", + "execa": "^5.0.0", "glob": "^7.1.3", "graceful-fs": "^4.2.4", - "jest-config": "^26.6.3", - "jest-haste-map": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", + "jest-haste-map": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-mock": "^27.4.6", + "jest-regex-util": "^27.4.0", + "jest-resolve": "^27.4.6", + "jest-snapshot": "^27.4.6", + "jest-util": "^27.4.2", "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^15.4.1" + "strip-bom": "^4.0.0" }, "dependencies": { "ansi-styles": { @@ -19026,9 +19535,9 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -19074,9 +19583,9 @@ } }, "jest-serializer": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", - "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.4.0.tgz", + "integrity": "sha512-RDhpcn5f1JYTX2pvJAGDcnsNTnsV9bjYPU8xcV+xPwOXnUPOQwf4ZEuiU6G9H1UztH+OapMgu/ckEVwO87PwnQ==", "dev": true, "requires": { "@types/node": "*", @@ -19084,26 +19593,32 @@ } }, "jest-snapshot": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", - "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.4.6.tgz", + "integrity": "sha512-fafUCDLQfzuNP9IRcEqaFAMzEe7u5BF7mude51wyWv7VRex60WznZIC7DfKTgSIlJa8aFzYmXclmN328aqSDmQ==", "dev": true, "requires": { + "@babel/core": "^7.7.2", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", "@babel/types": "^7.0.0", - "@jest/types": "^26.6.2", + "@jest/transform": "^27.4.6", + "@jest/types": "^27.4.2", "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.0.0", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^26.6.2", + "expect": "^27.4.6", "graceful-fs": "^4.2.4", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-haste-map": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", + "jest-diff": "^27.4.6", + "jest-get-type": "^27.4.0", + "jest-haste-map": "^27.4.6", + "jest-matcher-utils": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-util": "^27.4.2", "natural-compare": "^1.4.0", - "pretty-format": "^26.6.2", + "pretty-format": "^27.4.6", "semver": "^7.3.2" }, "dependencies": { @@ -19117,9 +19632,9 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -19168,17 +19683,17 @@ } }, "jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.4.2.tgz", + "integrity": "sha512-YuxxpXU6nlMan9qyLuxHaMMOzXAl5aGZWCSzben5DhLHemYQxCc4YK+4L3ZrCutT8GPQ+ui9k5D8rUJoDioMnA==", "dev": true, "requires": { - "@jest/types": "^26.6.2", + "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", + "ci-info": "^3.2.0", "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" + "picomatch": "^2.2.3" }, "dependencies": { "ansi-styles": { @@ -19191,9 +19706,9 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -19233,17 +19748,17 @@ } }, "jest-validate": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", - "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.4.6.tgz", + "integrity": "sha512-872mEmCPVlBqbA5dToC57vA3yJaMRfIdpCoD3cyHWJOMx+SJwLNw0I71EkWs41oza/Er9Zno9XuTkRYCPDUJXQ==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "camelcase": "^6.0.0", + "@jest/types": "^27.4.2", + "camelcase": "^6.2.0", "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", + "jest-get-type": "^27.4.0", "leven": "^3.1.0", - "pretty-format": "^26.6.2" + "pretty-format": "^27.4.6" }, "dependencies": { "ansi-styles": { @@ -19256,15 +19771,15 @@ } }, "camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -19304,17 +19819,17 @@ } }, "jest-watcher": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz", - "integrity": "sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.4.6.tgz", + "integrity": "sha512-yKQ20OMBiCDigbD0quhQKLkBO+ObGN79MO4nT7YaCuQ5SM+dkBNWE8cZX0FjU6czwMvWw6StWbe+Wv4jJPJ+fw==", "dev": true, "requires": { - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/test-result": "^27.4.6", + "@jest/types": "^27.4.2", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "jest-util": "^26.6.2", + "jest-util": "^27.4.2", "string-length": "^4.0.1" }, "dependencies": { @@ -19328,9 +19843,9 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -19370,14 +19885,14 @@ } }, "jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.6.tgz", + "integrity": "sha512-gHWJF/6Xi5CTG5QCvROr6GcmpIqNYpDJyc8A1h/DyXqH1tD6SnRCM0d3U5msV31D2LB/U+E0M+W4oyvKV44oNw==", "dev": true, "requires": { "@types/node": "*", "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" + "supports-color": "^8.0.0" }, "dependencies": { "has-flag": { @@ -19387,9 +19902,9 @@ "dev": true }, "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -19420,13 +19935,13 @@ "dev": true }, "jsdom": { - "version": "16.5.3", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.5.3.tgz", - "integrity": "sha512-Qj1H+PEvUsOtdPJ056ewXM4UJPCi4hhLA8wpiz9F2YvsRBhuFsXxtrIFAgGBDynQA9isAMGE91PfUYbdMPXuTA==", + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", "dev": true, "requires": { "abab": "^2.0.5", - "acorn": "^8.1.0", + "acorn": "^8.2.4", "acorn-globals": "^6.0.0", "cssom": "^0.4.4", "cssstyle": "^2.3.0", @@ -19434,12 +19949,13 @@ "decimal.js": "^10.2.1", "domexception": "^2.0.1", "escodegen": "^2.0.0", + "form-data": "^3.0.0", "html-encoding-sniffer": "^2.0.1", - "is-potential-custom-element-name": "^1.0.0", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", "nwsapi": "^2.2.0", "parse5": "6.0.1", - "request": "^2.88.2", - "request-promise-native": "^1.0.9", "saxes": "^5.0.1", "symbol-tree": "^3.2.4", "tough-cookie": "^4.0.0", @@ -19449,15 +19965,26 @@ "whatwg-encoding": "^1.0.5", "whatwg-mimetype": "^2.3.0", "whatwg-url": "^8.5.0", - "ws": "^7.4.4", + "ws": "^7.4.6", "xml-name-validator": "^3.0.0" }, "dependencies": { "acorn": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.2.4.tgz", - "integrity": "sha512-Ibt84YwBDDA890eDiDCEqcbwvHlBvzzDkU2cGBBDDI1QWT12jTiXIOn2CIw5KK4i6N5Z2HUxwYjzriDyqaqqZg==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", "dev": true + }, + "form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } } } }, @@ -19467,12 +19994,6 @@ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", @@ -19480,9 +20001,9 @@ "dev": true }, "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, "json-stable-stringify-without-jsonify": { @@ -19534,6 +20055,12 @@ "verror": "1.10.0" } }, + "just-extend": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", + "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", + "dev": true + }, "kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -19602,12 +20129,6 @@ } } }, - "lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", - "dev": true - }, "linkify-it": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.2.tgz", @@ -19681,6 +20202,12 @@ "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", "dev": true }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, "lodash.memoize": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", @@ -19721,12 +20248,12 @@ } }, "makeerror": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", - "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", "dev": true, "requires": { - "tmpl": "1.0.x" + "tmpl": "1.0.5" } }, "map-cache": { @@ -19735,15 +20262,6 @@ "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", "dev": true }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, "markdown-it": { "version": "12.2.0", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.2.0.tgz", @@ -19817,18 +20335,18 @@ } }, "mime-db": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", - "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==", + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", "dev": true }, "mime-types": { - "version": "2.1.30", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", - "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", "dev": true, "requires": { - "mime-db": "1.47.0" + "mime-db": "1.51.0" } }, "mimic-fn": { @@ -19864,27 +20382,6 @@ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -19939,36 +20436,68 @@ "minimatch": "^3.0.4" } }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - } - }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true + "nise": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/nise/-/nise-4.1.0.tgz", + "integrity": "sha512-eQMEmGN/8arp0xsvGoQ+B1qvSkR73B1nWSCh7nOt5neMCtwcQVYQGdzQMhcNscktTsWB54xnlSQFzOAPJD8nXA==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0", + "@sinonjs/fake-timers": "^6.0.0", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "path-to-regexp": "^1.7.0" + }, + "dependencies": { + "@sinonjs/fake-timers": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + } + } + }, + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "requires": { + "whatwg-url": "^5.0.0" + }, + "dependencies": { + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "dev": true + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "dev": true + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "dev": true, + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + } + } }, "node-int64": { "version": "0.4.0", @@ -19976,18 +20505,13 @@ "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", "dev": true }, - "node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", - "dev": true - }, "node-notifier": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.2.tgz", - "integrity": "sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-9.0.0.tgz", + "integrity": "sha512-SkwNwGnMMlSPrcoeH4CSo9XyWe72acAHEJGDdPdB+CyBVHsIYaTQ4U/1wk3URsyzC75xZLg2vzU2YaALlqDF1Q==", "dev": true, "optional": true, + "peer": true, "requires": { "growly": "^1.3.0", "is-wsl": "^2.2.0", @@ -20003,6 +20527,7 @@ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, "optional": true, + "peer": true, "requires": { "lru-cache": "^6.0.0" } @@ -20010,9 +20535,9 @@ } }, "node-releases": { - "version": "1.1.71", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", - "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", + "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==", "dev": true }, "nopt": { @@ -20051,20 +20576,12 @@ "dev": true }, "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, "requires": { - "path-key": "^2.0.0" - }, - "dependencies": { - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - } + "path-key": "^3.0.0" } }, "nwsapi": { @@ -20085,37 +20602,6 @@ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "object-inspect": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.2.tgz", @@ -20128,15 +20614,6 @@ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - } - }, "object.assign": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", @@ -20261,18 +20738,6 @@ "shell-quote": "^1.4.2" } }, - "p-each-series": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz", - "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==", - "dev": true - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, "p-limit": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", @@ -20366,12 +20831,6 @@ "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", "dev": true }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, "path-browserify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", @@ -20423,6 +20882,23 @@ "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", "dev": true }, + "path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dev": true, + "requires": { + "isarray": "0.0.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + } + } + }, "path-type": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", @@ -20445,12 +20921,24 @@ "sha.js": "^2.4.8" } }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, "picomatch": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", @@ -20464,13 +20952,10 @@ "dev": true }, "pirates": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", - "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", - "dev": true, - "requires": { - "node-modules-regexp": "^1.0.0" - } + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.4.tgz", + "integrity": "sha512-ZIrVPH+A52Dw84R0L3/VS9Op04PuQ2SEoJL6bkshmiTic/HldyW9Tf7oH5mhJZBK7NmDx27vSMrYEXPXclpDKw==", + "dev": true }, "pkg-dir": { "version": "2.0.0", @@ -20535,12 +21020,6 @@ } } }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -20548,39 +21027,20 @@ "dev": true }, "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.6.tgz", + "integrity": "sha512-NblstegA1y/RJW2VyML+3LlpFjzx62cUrtBIKIWDXEDkjNeleA7Od7nrzcs/VLQvAeV4CgSYhrN39DRN88Qi/g==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", "react-is": "^17.0.1" }, "dependencies": { "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true } } @@ -20604,15 +21064,21 @@ "dev": true }, "prompts": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.1.tgz", - "integrity": "sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", "dev": true, "requires": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" } }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, "psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -20641,20 +21107,113 @@ } } }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "puppeteer": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-13.1.2.tgz", + "integrity": "sha512-ozVM8Tdg0patMtm/xAr3Uh7rQ28vBpbTHLP+ECmoAxG/s4PKrVLN764H/poLux7Ln77jHThOd8OBJj5mTuA6Iw==", + "dev": true, + "requires": { + "debug": "4.3.2", + "devtools-protocol": "0.0.948846", + "extract-zip": "2.0.1", + "https-proxy-agent": "5.0.0", + "node-fetch": "2.6.7", + "pkg-dir": "4.2.0", + "progress": "2.0.3", + "proxy-from-env": "1.1.0", + "rimraf": "3.0.2", + "tar-fs": "2.1.1", + "unbzip2-stream": "1.4.3", + "ws": "8.2.3" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "ws": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", + "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "dev": true, + "requires": {} + } + } + }, + "pure-rand": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-5.0.0.tgz", + "integrity": "sha512-lD2/y78q+7HqBx2SaT6OT4UcwtvXNRfEpzYEzl0EQ+9gZq2Qi3fa0HDnYPeqQwhlHJFBUhT7AO3mLU3+8bynHA==", "dev": true }, "qs": { @@ -20808,18 +21367,18 @@ "dev": true }, "regenerate-unicode-properties": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz", - "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz", + "integrity": "sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw==", "dev": true, "requires": { - "regenerate": "^1.4.0" + "regenerate": "^1.4.2" } }, "regenerator-runtime": { - "version": "0.13.7", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", - "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", "dev": true }, "regenerator-transform": { @@ -20831,46 +21390,36 @@ "@babel/runtime": "^7.8.4" } }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, "regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true }, "regexpu-core": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.1.tgz", - "integrity": "sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.0.1.tgz", + "integrity": "sha512-CriEZlrKK9VJw/xQGJpQM5rY88BtuL8DM+AEwvcThHilbxiTAy8vq4iJnd2tqq8wLmjbGZzP7ZcKFjbGkmEFrw==", "dev": true, "requires": { - "regenerate": "^1.4.0", - "regenerate-unicode-properties": "^8.2.0", - "regjsgen": "^0.5.1", - "regjsparser": "^0.6.4", - "unicode-match-property-ecmascript": "^1.0.4", - "unicode-match-property-value-ecmascript": "^1.2.0" + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.0.1", + "regjsgen": "^0.6.0", + "regjsparser": "^0.8.2", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.0.0" } }, "regjsgen": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", - "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.6.0.tgz", + "integrity": "sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA==", "dev": true }, "regjsparser": { - "version": "0.6.9", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.9.tgz", - "integrity": "sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ==", + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.8.4.tgz", + "integrity": "sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA==", "dev": true, "requires": { "jsesc": "~0.5.0" @@ -20884,24 +21433,6 @@ } } }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, "request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", @@ -20954,38 +21485,6 @@ } } }, - "request-promise-core": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", - "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", - "dev": true, - "requires": { - "lodash": "^4.17.19" - } - }, - "request-promise-native": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", - "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", - "dev": true, - "requires": { - "request-promise-core": "1.1.4", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - }, - "dependencies": { - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - } - } - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -20998,12 +21497,6 @@ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, "resolve": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", @@ -21064,16 +21557,10 @@ } } }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "resolve.exports": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", + "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", "dev": true }, "rimraf": { @@ -21095,12 +21582,6 @@ "inherits": "^2.0.1" } }, - "rsvp": { - "version": "4.8.5", - "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", - "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", - "dev": true - }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -21113,162 +21594,12 @@ "integrity": "sha1-PnZyPjjf3aE8mx0poeB//uSzC1c=", "dev": true }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, - "sane": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", - "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", - "dev": true, - "requires": { - "@cnakazawa/watch": "^1.0.3", - "anymatch": "^2.0.0", - "capture-exit": "^2.0.0", - "exec-sh": "^0.3.2", - "execa": "^1.0.0", - "fb-watchman": "^2.0.0", - "micromatch": "^3.1.4", - "minimist": "^1.1.1", - "walker": "~1.0.5" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - } - } - }, "saxes": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", @@ -21278,41 +21609,17 @@ "xmlchars": "^2.2.0" } }, + "seedrandom": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", + "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==" + }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, "sha.js": { "version": "2.4.11", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", @@ -21348,9 +21655,9 @@ "dev": true }, "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz", + "integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==", "dev": true }, "shellwords": { @@ -21358,7 +21665,8 @@ "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", "dev": true, - "optional": true + "optional": true, + "peer": true }, "side-channel": { "version": "1.0.4", @@ -21372,9 +21680,9 @@ } }, "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", + "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", "dev": true }, "simple-concat": { @@ -21383,174 +21691,97 @@ "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", "dev": true }, - "sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - } - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "sinon": { + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", + "integrity": "sha512-zljcULZQsJxVra28qIAL6ow1Z9tpattkCTEJR4RBP3TGc00FcttsP5pK284Nas5WjMZU5Yzy3kAIp3B3KRf5Yg==", "dev": true, "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" + "@sinonjs/commons": "^1.8.1", + "@sinonjs/fake-timers": "^6.0.1", + "@sinonjs/samsam": "^5.3.1", + "diff": "^4.0.2", + "nise": "^4.0.4", + "supports-color": "^7.1.0" }, "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "@sinonjs/fake-timers": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", "dev": true, "requires": { - "is-descriptor": "^1.0.0" + "@sinonjs/commons": "^1.7.0" } }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "has-flag": "^4.0.0" } } } }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "sjcl": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/sjcl/-/sjcl-1.0.8.tgz", + "integrity": "sha512-LzIjEQ0S0DpIgnxMEayM1rq9aGwGRG4OnZhCdjx7glTaJtf4zRfpg87ImfjSJjoW9vKpagd82McDOwbRT5kQKQ==" + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, "requires": { - "kind-of": "^3.2.0" + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" }, "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "color-name": "~1.1.4" } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true } } }, @@ -21560,23 +21791,10 @@ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, "requires": { "buffer-from": "^1.0.0", @@ -21591,12 +21809,6 @@ } } }, - "source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "dev": true - }, "spdx-correct": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", @@ -21629,15 +21841,6 @@ "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==", "dev": true }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -21662,9 +21865,9 @@ } }, "stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", + "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -21678,33 +21881,6 @@ } } }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", - "dev": true - }, "stream-browserify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", @@ -21807,14 +21983,14 @@ "dev": true }, "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" + "strip-ansi": "^6.0.1" } }, "string.prototype.trimend": { @@ -21838,12 +22014,12 @@ } }, "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "ansi-regex": "^5.0.0" + "ansi-regex": "^5.0.1" } }, "strip-bom": { @@ -21852,12 +22028,6 @@ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, "strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", @@ -21943,25 +22113,43 @@ "slice-ansi": "^4.0.0", "string-width": "^4.2.0", "strip-ansi": "^6.0.0" + } + }, + "tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" }, "dependencies": { - "ajv": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.2.0.tgz", - "integrity": "sha512-WSNGFuyWd//XO8n/m/EaOlNLtO0yL8EXT/74LqT4khdhpZjP7lkj/kT5uwRmGitKEVp/Oj7ZUHeGfPtgHhQ5CA==", + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true } } }, @@ -21993,9 +22181,9 @@ "dev": true }, "throat": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", - "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", + "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", "dev": true }, "through": { @@ -22049,9 +22237,9 @@ } }, "tmpl": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", - "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", "dev": true }, "to-fast-properties": { @@ -22060,38 +22248,6 @@ "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", "dev": true }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -22113,9 +22269,9 @@ } }, "tr46": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz", - "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", "dev": true, "requires": { "punycode": "^2.1.1" @@ -22201,6 +22357,12 @@ "is-typedarray": "^1.0.0" } }, + "typescript": { + "version": "4.5.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz", + "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==", + "dev": true + }, "uc.micro": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", @@ -22225,6 +22387,16 @@ "which-boxed-primitive": "^1.0.2" } }, + "unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "dev": true, + "requires": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, "unc-path-regex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", @@ -22255,91 +22427,39 @@ } }, "unicode-canonical-property-names-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", - "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", "dev": true }, "unicode-match-property-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", - "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", "dev": true, "requires": { - "unicode-canonical-property-names-ecmascript": "^1.0.4", - "unicode-property-aliases-ecmascript": "^1.0.4" + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" } }, "unicode-match-property-value-ecmascript": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz", - "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", + "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==", "dev": true }, "unicode-property-aliases-ecmascript": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz", - "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz", + "integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==", "dev": true }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - } - } - }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -22349,12 +22469,6 @@ "punycode": "^2.1.0" } }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, "url": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", @@ -22373,12 +22487,6 @@ } } }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, "util": { "version": "0.12.3", "resolved": "https://registry.npmjs.org/util/-/util-0.12.3.tgz", @@ -22404,7 +22512,8 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true, - "optional": true + "optional": true, + "peer": true }, "v8-compile-cache": { "version": "2.3.0", @@ -22413,9 +22522,9 @@ "dev": true }, "v8-to-istanbul": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.2.tgz", - "integrity": "sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", + "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.1", @@ -22486,12 +22595,12 @@ } }, "walker": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", - "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", "dev": true, "requires": { - "makeerror": "1.0.x" + "makeerror": "1.0.12" } }, "watchify": { @@ -22570,13 +22679,13 @@ "dev": true }, "whatwg-url": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.5.0.tgz", - "integrity": "sha512-fy+R77xWv0AiqfLl4nuGUlQ3/6b5uNfQ4WAbGQVMYshCTCCPK9psC1nWh3XHuxGVCtlcDDQPQW1csmmIQo+fwg==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", "dev": true, "requires": { "lodash": "^4.7.0", - "tr46": "^2.0.2", + "tr46": "^2.1.0", "webidl-conversions": "^6.1.0" } }, @@ -22602,12 +22711,6 @@ "is-symbol": "^1.0.3" } }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, "which-typed-array": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz", @@ -22630,9 +22733,9 @@ "dev": true }, "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { "ansi-styles": "^4.0.0", @@ -22685,10 +22788,11 @@ } }, "ws": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", - "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==", - "dev": true + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz", + "integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==", + "dev": true, + "requires": {} }, "xml-name-validator": { "version": "3.0.0", @@ -22696,6 +22800,12 @@ "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", "dev": true }, + "xmlbuilder": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.0.0.tgz", + "integrity": "sha512-KLu/G0DoWhkncQ9eHSI6s0/w+T4TM7rQaLhtCaL6tORv8jFlJPlnGumsgTcGfYeS1qZ/IHqrvDG7zJZ4d7e+nw==", + "dev": true + }, "xmlchars": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", @@ -22709,9 +22819,9 @@ "dev": true }, "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, "yallist": { @@ -22721,83 +22831,34 @@ "dev": true }, "yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - } + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" } }, "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true + }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", "dev": true, "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" } } } diff --git a/package.json b/package.json index 5e2e240d3..d117aa5c5 100644 --- a/package.json +++ b/package.json @@ -2,20 +2,37 @@ "name": "@duckduckgo/autofill", "main": "dist/autofill.js", "browserslist": [ - "> 0.25%", + "defaults", "not dead", "not ie 11" ], "scripts": { + "postinstall": "cd packages/password && npm install", "start": "grunt dev", "build": "grunt", - "test": "jest" + "lint": "eslint .", + "lint:fix": "npm run lint -- --fix", + "copy-assets": "node scripts/copy-assets.js", + "open-test-extension": "web-ext run -t chromium -u https://privacy-test-pages.glitch.me/ -s integration-test/extension", + "test": "npm run test:unit && npm run lint && tsc", + "test:clean-tree": "npm run build && sh scripts/check-for-changes.sh", + "test:passwords": "PASSWORD_STRESS_TEST=true jest generate.test.js", + "test:unit": "jest", + "test:integration": "npm run build && npm run copy-assets && jasmine --config=integration-test/config.js", + "test:integration:ci": "npm run copy-assets && jasmine --config=integration-test/config.js", + "test-int-x": "xvfb-run --server-args='-screen 0 1024x768x24' npm run test:integration:ci", + "test:report": "jest --testResultsProcessor='./node_modules/jest-html-reporter' --no-colors --verbose=false", + "test:watch": "jest --watch --verbose=false", + "tsc": "tsc", + "tsc:watch": "tsc --watch" }, "license": "Apache-2.0", "devDependencies": { - "@babel/core": "^7.13.16", - "@babel/eslint-parser": "^7.13.14", - "@babel/preset-env": "^7.13.15", + "@babel/core": "^7.17.5", + "@babel/eslint-parser": "^7.17.0", + "@babel/preset-env": "^7.16.11", + "@types/jest": "^27.4.0", + "@types/node": "^16.11.7", "asana": "^0.18.6", "babelify": "^10.0.0", "eslint": "^7.25.0", @@ -24,15 +41,23 @@ "eslint-plugin-node": "^11.1.0", "eslint-plugin-promise": "^4.3.1", "eslint-plugin-standard": "^5.0.0", + "fast-check": "^2.21.0", "grunt": "^1.4.0", "grunt-babel": "^8.0.0", "grunt-browserify": "^6.0.0", "grunt-contrib-watch": "^1.1.0", "grunt-eslint": "^23.0.0", "grunt-exec": "^3.0.0", - "jest": "^26.6.3", + "jasmine": "^4.0.2", + "jest": "^27.4.7", "jest-chrome": "^0.7.1", + "jest-html-reporter": "^3.4.2", "load-grunt-tasks": "^5.1.0", - "markdown-it": "^12.2.0" + "markdown-it": "^12.2.0", + "puppeteer": "^13.0.1", + "typescript": "^4.5.5" + }, + "dependencies": { + "@duckduckgo/content-scope-scripts": "github:duckduckgo/content-scope-scripts" } } diff --git a/packages/password/docs/password.md b/packages/password/docs/password.md new file mode 100644 index 000000000..57ece9565 --- /dev/null +++ b/packages/password/docs/password.md @@ -0,0 +1,147 @@ +## DDG Password API + +This module exposes a single `generate()` method. + +You can do the following with it + +1: Generate a password based on DuckDuckGo's default settings +2: Generate a password from a 'passwordrules' attribute string +3: Lookup known password rules from the [resources provided by Apple](https://github.com/apple/password-manager-resources) + + +```javascript +const password = require("@duckduckgo/autofill/packages/password"); +const rules = require("@duckduckgo/autofill/packages/password/rules.json"); + +// generate a password with default settings +const pw = password.generate() + +// generate a password with a given input, falling back to default +const pw = password.generate({ input: "minlength: 30; required: lower, upper;"}) + +// generate a password with rules from a known domain, +// if it exists in the given rules, falling back to default +const pw = password.generate({ domain: "example.com", rules }) +``` + +The API is designed to **never** throw an exception, it will always fall back to the default ruleset if there's +anything wrong with the `input` or `domain`. + +## Password rules + +This library includes a snapshot of [this file](https://github.com/apple/password-manager-resources/blob/main/quirks/password-rules.json) that you are free to include in your calls to `generate`. You'll need to require the file (in whichever way your bundler needs it) and pass it along with the `domain`. + +```javascript +const pw = password.generate({ + domain: "example.com", + rules: require("@duckduckgo/autofill/packages/password/rules.json"), +}) +``` + +This gives you the flexibility to add/remove rules for each domain as you see fit - if this file was automatically included, then calls to `generate` would be bound to whatever was in that file. + +**Example:** Here's how you could merge the base rules with some of your own + +```javascript +const customRules = { + "example.com": { "password-rules": "min-length: 30; required: upper, lower, digit" }, + "example.eu": { "password-rules": "min-length: 40; required: upper, lower, digit" } +} + +// use the base rules, overriding/adding customRules. +const pw = password.generate({ + domain: "example.com", + rules: { + ...require("@duckduckgo/autofill/packages/password/rules.json"), + ...customRules + }, +}) +``` + +Or, to remove rules for a given domain (where rules may have changed due to a backend update), you can do the following: + +```javascript +const { + ['autify.com']: _autify, + ['axa.de']: _axa, + ...rules } = require("@duckduckgo/autofill/packages/password/rules.json"); + +// this will fallback to default, since `autify.com` was removed from the ruleset +const pw = password.generate({ + domain: "autify.com", + rules, +}) +``` + +## Error handling + +This public API will never throw an exception - it's designed to *always* produce a password. During development however, you may want more feedback about an input that might be incorrect - for +that you can provide an `onError` callback to observe any thrown exceptions. + +```javascript +const pw = password.generate({ + domain: "localhost:8080", + rules: require("@duckduckgo/autofill/packages/password/rules.json"), + onError: (e) => { + console.error(e) + } +}) +``` + +# DDG Default Rules + +With no parameters, the generate function will use the following character set + +``` +abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789 +``` + +Along with the following password rules + +``` +minlength: 20; maxlength: 30; +``` + +Which currently produces passwords in this format: + +``` +N3xeFEQf3yiXy3V1msa2 +iHjs07Xj64nWfiNrm1nB +pN14zIYhSE0Q6iFuAhcd +QEu6bhPA0MhZ0BhrkaWI +iKub0kcgzrUFdfWdGKdg +jnhChxEtZ7tU4dhUTaHw +DDXNhKaSv7ufabwKfeLP +VmJ1IdUmvqERkdEY2I7A +8xKpY2NsLf4dn1zUMinB +I08cqi3ZyQz3mQHevfNU +``` + +These passwords have roughly 119 bits of entropy (`Math.log2(62**20)`), which is very secure. + +When password rules dictate a max-length, this becomes drastically reduced. For example if a site dictates that it only allows a maxlength of 8 chars, then we only get about 47 bits of entropy with the character set above. + +Note, these are all 20 characters because the generation continues until it finds a password that suits +the rule - in this case the rule is the basic character set so is always matched. + +For example, the following rules + +``` +minlength: 10; maxlength: 30; required: [$]; required: upper,lower,digit; +``` + +Would return results like this, all about 12 chars long, because it took an extra 2 cycles to +find a matching password with the required `$` + +``` +XZJZUt$8cBp2 +6$7WwRcg9GkJ +PKJFCe$j0UYZ +eZLE$bHMoh50 +9vPyhM$QS1D9 +km99pG$GJJXR +sPMpe$AP7svJ +YY$7Dymsi26f +qg$WaLvfGeVh +mGW9m2D97Z$x +``` diff --git a/packages/password/docs/updating-rules.md b/packages/password/docs/updating-rules.md new file mode 100644 index 000000000..a511e0c22 --- /dev/null +++ b/packages/password/docs/updating-rules.md @@ -0,0 +1,26 @@ +## Rules + +We include the following [file](https://raw.githubusercontent.com/apple/password-manager-resources/main/quirks/password-rules.json) within this +package, which allows password generation to respect known rules for the websites listed. + +## Update the rules + +Inside this packages folder, `packages/password`, run the following + +```shell +npm run rules:update +``` + +## Github Action + +We use a Github action to notify new PR's with a comment when our ruleset has +become out of sync with Apple's. + +It's in the following file: +- `.github/workflows/password-rules.yml` + +It uses scripts from +- `packages/password/scripts/rules.js` + +The script itself does not update anything, it's just there as a notice to prompt +anyone watching the repo that an update may be required. diff --git a/packages/password/html-testing/generate.js b/packages/password/html-testing/generate.js new file mode 100644 index 000000000..1d7923299 --- /dev/null +++ b/packages/password/html-testing/generate.js @@ -0,0 +1,99 @@ +/** + * + * This file is used to generate the table of inputs inside `index.html` + * + * You can run this any time that `../rules.json` has changed, or after + * adding any manual entries to `manualEntries` below. + * + */ +const {readFileSync, writeFileSync} = require('fs') +const {join} = require('path') +const rules = require('../rules.json') +const filePath = join(__dirname, 'index.html') +const html = readFileSync(filePath, 'utf8') +const {Password} = require('../lib/apple.password') + +let s = '' + +const manualEntries = { + // this is just to test the use of chars that need escaping + '" test': { 'password-rules': `minlength: 6; required: lower, upper; required: digit; required: ["]` } +} + +const joined = [...Object.entries(manualEntries), ...Object.entries(rules)] +const outputs = [] +const password = new Password({ + getRandomValues: (v) => require('crypto').randomFillSync(v) +}) + +for (let [domain, value] of joined) { + const rulesString = value['password-rules'] + if (domain && rulesString) { + const {parameters, generate, entropy} = password.parse(rulesString) + let charsetLength = parameters.PasswordAllowedCharacters.length + let passwords = new Array(5).fill(0).map((_, i) => i) + .map(() => { + const pw = generate() + return { pw, length: pw.length } + }) + const averageLength = passwords.reduce((acc, a) => acc + a.length, 0) / 5 + + outputs.push({ + domain, + rules: rulesString, + charsetLength, + averageLength, + entropy, + passwords, + charset: parameters.PasswordAllowedCharacters + }) + } +} + +outputs.sort((a, b) => a.entropy - b.entropy) + +for (let output of outputs) { + const {averageLength, entropy, passwords, charsetLength, rules, domain, charset} = output + let entropyScore = 'Very Strong' + if (entropy >= 60 && entropy <= 127) { + entropyScore = 'Strong' + } else if (entropy >= 36 && entropy < 60) { + entropyScore = 'Reasonable' + } else if (entropy >= 28 && entropy < 36) { + entropyScore = 'Weak' + } else if (entropy < 28) { + entropyScore = 'Very Weak' + } + s += ` + + + + + +
Rules: ${escapeXML(rules)}
+
charset: ${escapeXML(charset)}
+
charset size: ${charsetLength}, length: ${averageLength}
+
entropy: ${entropyScore} ${entropy.toFixed(2)}
+
${escapeXML(passwords.map(pw => `${pw.pw} (${pw.length})`).join('\n'))}
+ + + ` +} + +const markerStart = '' +const start = html.indexOf(markerStart) + markerStart.length +const end = html.indexOf('
') + +const newHtml = html.slice(0, start) + s + html.slice(end) + +writeFileSync(filePath, newHtml) + +/** + * Escapes any occurrences of &, ", <, > or / with XML entities. + * @param {string} str The string to escape. + * @return {string} The escaped string. + */ +function escapeXML (str) { + const replacements = { '&': '&', '"': '"', "'": ''', '<': '<', '>': '>', '/': '/' } + return String(str).replace(/[&"'<>/]/g, m => replacements[m]) +} diff --git a/packages/password/html-testing/index.html b/packages/password/html-testing/index.html new file mode 100644 index 000000000..ca7169ab5 --- /dev/null +++ b/packages/password/html-testing/index.html @@ -0,0 +1,4432 @@ + + + + + + + Document + + + + +

Sign up

+

Login

+
+

Current rules:

+
+        
+    
+
+
+ + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
Rules: minlength: 4; maxlength: 4; allowed: digit;
+
charset: 0123456789
+
charset size: 10, length: 4
+
entropy: Very Weak 13.29
+
7957 (4)
+1704 (4)
+3080 (4)
+6012 (4)
+9643 (4)
+
+ + +
Rules: maxlength: 6; max-consecutive: 3; allowed: digit;
+
charset: 0123456789
+
charset size: 10, length: 6
+
entropy: Very Weak 19.93
+
062560 (6)
+043212 (6)
+761309 (6)
+201708 (6)
+550136 (6)
+
+ + +
Rules: minlength: 4; maxlength: 4;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 4
+
entropy: Very Weak 23.63
+
1VkH (4)
+6bU3 (4)
+7dqP (4)
+E5Lg (4)
+Cs4n (4)
+
+ + +
Rules: minlength: 4; maxlength: 8; required: digit;
+
charset: 0123456789
+
charset size: 10, length: 8
+
entropy: Very Weak 26.58
+
24128928 (8)
+41446032 (8)
+61990382 (8)
+48627778 (8)
+41440331 (8)
+
+ + +
Rules: minlength: 5; maxlength: 5; required: lower, upper, digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 5
+
entropy: Weak 29.77
+
cSkkI (5)
+3x0sq (5)
+sPfud (5)
+L0q1Y (5)
+JIcHQ (5)
+
+ + +
Rules: minlength: 5; maxlength: 5; required: lower, upper, digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 5
+
entropy: Weak 29.77
+
I7a9S (5)
+2YrWY (5)
+eElzK (5)
+eWELs (5)
+NZcjM (5)
+
+ + +
Rules: minlength: 6; maxlength: 6;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 6
+
entropy: Weak 35.44
+
mRrSE5 (6)
+Bzf1vh (6)
+JV8GmX (6)
+4L82Fe (6)
+BQiSM9 (6)
+
+ + +
Rules: minlength: 6; maxlength: 8;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 8
+
entropy: Reasonable 47.26
+
QuLX8Jyw (8)
+DN7RDLeC (8)
+20WtBicK (8)
+2vjbdBXT (8)
+zn3sTgXw (8)
+
+ + +
Rules: minlength: 8; maxlength: 8; required: lower; required: upper; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 8
+
entropy: Reasonable 47.63
+
YcL6PTsF (8)
+BgCd3r4Z (8)
+BS12ogn1 (8)
+3lnmZWSY (8)
+W6KcsQjo (8)
+
+ + +
Rules: minlength: 5; maxlength: 8; required: lower, upper; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 8
+
entropy: Reasonable 47.63
+
1S1clNZH (8)
+cjuoq9eE (8)
+3oggafKM (8)
+ls92F7ho (8)
+21eZftwL (8)
+
+ + +
Rules: minlength: 6; maxlength: 8; allowed: lower, upper, digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 8
+
entropy: Reasonable 47.63
+
ElgO4vZD (8)
+0zAaMjSl (8)
+4iTKPEuS (8)
+tr5IRXi3 (8)
+yM2xGnl3 (8)
+
+ + +
Rules: minlength: 6; maxlength: 8; required: lower, upper; required: [-!#%&(){}*+;%/<=>?_];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-!#%&*_+=(){};<>?/
+
charset size: 70, length: 8
+
entropy: Reasonable 49.03
+
vdY?>_TA (8)
++%G!bwCH (8)
+JCyLNC+k (8)
+h-on)mPV (8)
+{FhbaRX? (8)
+
+ + +
Rules: minlength: 8; maxlength: 10; required: digit; required: lower, upper;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 10
+
entropy: Reasonable 59.54
+
FuMEDyvt92 (10)
+ViQn82YBhK (10)
+W8sCCZzIl9 (10)
+3fXgeehHeg (10)
+xwB9QqK6Wl (10)
+
+ + +
Rules: minlength: 8; maxlength: 10; required: lower; required: upper; required: digit; required: [!#&*+/=@_];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#&*_+=/
+
charset size: 71, length: 10
+
entropy: Strong 61.50
+
IvA2X8V/!+ (10)
+t@pr#_+W6= (10)
+!SO9hb4ydJ (10)
+&g#pAG36wL (10)
+D99jjLMV=J (10)
+
+ + +
Rules: minlength: 6; maxlength: 10; required: lower, upper, digit; allowed: [!"#$%&()*+:;<=>?@[{}~]];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~!@#$%&*+=(){}[:;"<>?]
+
charset size: 84, length: 10
+
entropy: Strong 63.92
+
~tq2diA2PI (10)
+w&1x+jUunl (10)
+b*TxnIIfnS (10)
+h9rKM:RT;= (10)
+1j+k1f})fz (10)
+
+ + +
Rules: minlength: 6; maxlength: 12;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 12
+
entropy: Strong 70.88
+
b8eWhbcP5aHz (12)
+BM9bxewmdi6Y (12)
+w9Lv1AozinWd (12)
+sdAjGQyMApp3 (12)
+6zEwXTIxFVLE (12)
+
+ + +
Rules: minlength: 6; maxlength: 12;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 12
+
entropy: Strong 70.88
+
CdUg5hjZmMqg (12)
+8hectzvQmnkM (12)
+EAB6tnQGtQz8 (12)
+pngjSRvyy4TT (12)
+xXxSSceBz33Z (12)
+
+ + +
Rules: minlength: 8; maxlength: 12;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 12
+
entropy: Strong 70.88
+
G5WYZastPMhb (12)
+p3D9B416E8QM (12)
+pqCzXfGCU9su (12)
+fYdk9sJuPcsV (12)
+ebjJT5HpgarF (12)
+
+ + +
Rules: minlength: 6; maxlength: 12;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 12
+
entropy: Strong 70.88
+
AuBhWQSwMg6R (12)
+U8D4GamMQFnu (12)
+X3rNqSYksg6P (12)
+3jBmcbz1QZjh (12)
+CYGhhcqfx6na (12)
+
+ + +
Rules: minlength: 8; maxlength: 12; required: lower; required: upper; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 12
+
entropy: Strong 71.45
+
g41L16J92zJY (12)
+qOf0hwEZYuZT (12)
+wS4F8IyVHeF8 (12)
+UY9wagkTb66t (12)
+CsX0nWBCCdT5 (12)
+
+ + +
Rules: minlength: 8; maxlength: 12; required: lower; required: upper; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 12
+
entropy: Strong 71.45
+
nrcd1J7lzf4L (12)
+UedfLfZrHFB8 (12)
+ZO0gBN5q8ZDb (12)
+z8IB4XhI5QNH (12)
+Rlqrjhw35FRE (12)
+
+ + +
Rules: minlength: 8; maxlength: 12; required: lower, upper; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 12
+
entropy: Strong 71.45
+
5hDfGBL0z24P (12)
+yoaCRXy5O7x6 (12)
+eWZML3ycoIxp (12)
+cSFJTOgowJ3o (12)
+qIjwAPb6AVsK (12)
+
+ + +
Rules: minlength: 8; maxlength: 12; required: upper; required: digit; required: [_!.&@]; allowed: lower;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@&_.
+
charset size: 67, length: 12
+
entropy: Strong 72.79
+
bA4J_nz1NQ75 (12)
+K&@mVx7Yn1CO (12)
+8EtmEsdOda_z (12)
+n5zzwse!EG9e (12)
+e8.LhR_c1wTU (12)
+
+ + +
Rules: minlength: 8; maxlength: 12; required: lower; required: upper; required: digit; required: [!@#$%^&*()];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()
+
charset size: 72, length: 12
+
entropy: Strong 74.04
+
imM78xsDl@RE (12)
+vKG94%WT&gjk (12)
+6Gn$vJ7N0pEd (12)
+xTtQGN#1uq)q (12)
+wNto0SNizib( (12)
+
+ + +
Rules: minlength: 8; maxlength: 12; max-consecutive: 3; required: lower; required: upper; required: digit; allowed: [#$%&()*+,.:;<=>?@_];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@#$%&*_+=():;<>,.?
+
charset size: 80, length: 12
+
entropy: Strong 75.86
+
PjV.2k)vi#nd (12)
+4sLF8)AvHlsh (12)
+1Xcu559sT*WA (12)
+VIC2vZ>aH22d (12)
+2BESuU)$+fe* (12)
+
+ + +
Rules: minlength: 8; maxlength: 12; required: lower, upper; required: digit; allowed: [-!#$%&'()*,.:;=?^{}];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-!#$%^&*=(){}:;',.?
+
charset size: 81, length: 12
+
entropy: Strong 76.08
+
U?tgzjF6%jzW (12)
+dh:$F)}6fV'} (12)
+95;a}&l990eQ (12)
+dVxaT03my6Yc (12)
+$YZEZco6poB9 (12)
+
+ + +
Rules: minlength: 8; maxlength: 12; max-consecutive: 2; required: lower; required: upper; required: digit; required: [-~!@#$%^&*_+=`|(){}[:;"'<>,.?];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;"'<>,.?
+
charset size: 91, length: 12
+
entropy: Strong 78.09
+
x*Od'Puz)lE6 (12)
+=P{8v2!6CkOl (12)
+7b'%WjA85eeC (12)
+Ihq3NDHG*r6$ (12)
+JZ1LdjhGV'Vv (12)
+
+ + +
Rules: minlength: 6; maxlength: 14;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 14
+
entropy: Strong 82.70
+
CuwAEx8eFnET4D (14)
+1kZMaWg37bwRN9 (14)
+cnES9iPNVPh7nf (14)
+qTykVXf9emgpCm (14)
+1G9rdaeN4wFUQb (14)
+
+ + +
Rules: minlength: 8; maxlength: 14;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 14
+
entropy: Strong 82.70
+
y4HycI02CSdwvR (14)
+zwg7mJ5MpXdza6 (14)
+NzQjd0gcHtrtHp (14)
+PNXDcsxe2hggmx (14)
+zaQWkjI7t3Xt1m (14)
+
+ + +
Rules: minlength: 6; maxlength: 15; required: lower, upper;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
+
charset size: 52, length: 15
+
entropy: Strong 85.51
+
vmHHskplWyvCtsb (15)
+aAFEcHbWotNwTcI (15)
+PZrcRMOKgDQKBan (15)
+cBRPCvJfkSjwEjP (15)
+XsWmdMFUYBanZwJ (15)
+
+ + +
Rules: minlength: 6; maxlength: 15;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 15
+
entropy: Strong 88.60
+
DX77jMStaIniZdw (15)
+ghJ0xTNcdWJxAwL (15)
+QKtMcfanf0BCcpI (15)
+DmJ2N1grPMpJ2yB (15)
+bGWoPYEKxmQj7ny (15)
+
+ + +
Rules: minlength: 8; maxlength: 15;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 15
+
entropy: Strong 88.60
+
JQ9tXPYxo8SGHoj (15)
+Xx58js22qiIBIQj (15)
+KDS0Phy2qg5uHza (15)
+czQHcy6VIY2f5gU (15)
+vh2AJ7gqyBzjLSd (15)
+
+ + +
Rules: maxlength: 15;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 15
+
entropy: Strong 88.60
+
BR0hACfWZGMH77b (15)
+9V3MuFWnDKHj5mg (15)
+QsGe98nRmgF2bS6 (15)
+DDDjLz1Noq34ftB (15)
+HrP7cNoYLVcIpVf (15)
+
+ + +
Rules: minlength: 5; maxlength: 15;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 15
+
entropy: Strong 88.60
+
eQEkCnsWm6adEmC (15)
+4IQGcItZDSMKEXg (15)
+G2iVHej6c9XMcIv (15)
+p4jvx0NIbdUiqqu (15)
+pSuHno6UzyGdRJ2 (15)
+
+ + +
Rules: maxlength: 15;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 15
+
entropy: Strong 88.60
+
yXtI8tZwfKq8A88 (15)
+efmRRtBo25QzbjQ (15)
+5te4G6fxjfY2HXy (15)
+EIaF3jYSZdffIa1 (15)
+hiRLaX65i8fhez4 (15)
+
+ + +
Rules: maxlength: 15;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 15
+
entropy: Strong 88.60
+
shCTo4HK4KgwACg (15)
+Q4JJ4gqMdcCAcLL (15)
+20cynBZmSt6Hdpt (15)
+dUfdvhTTAyuZd3E (15)
+w6BycDQuUQ0h8FR (15)
+
+ + +
Rules: minlength: 8; maxlength: 15; required: lower; required: upper; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 15
+
entropy: Strong 89.31
+
l8ZCxWpHiCG6s76 (15)
+aakH9aSBYiQ6BhV (15)
+kEa35hUIuV9fDJu (15)
+vLhc4melp9Yeiom (15)
+emaBYvMjcQXLh5W (15)
+
+ + +
Rules: minlength: 6; maxlength: 15; allowed: lower, upper, digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 15
+
entropy: Strong 89.31
+
87XdeWTTtaOSsqf (15)
+UyvKuuPSHnKsb3j (15)
+kEYCO52GFErvQsA (15)
+wA3JrJYguO0YN9s (15)
+Ht5AwzhpLouIpqf (15)
+
+ + +
Rules: minlength: 6; maxlength: 15; required: lower, upper; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 15
+
entropy: Strong 89.31
+
GeE3P7HdR6w2eD3 (15)
+d4jb7g9truhM3Bi (15)
+vL81SuOxzm2bwxb (15)
+ujVfz4AdgcZ68fV (15)
+WJbt9H91hJMseHp (15)
+
+ + +
Rules: minlength: 8; maxlength: 15; required: lower; required: digit; allowed: upper;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 15
+
entropy: Strong 89.31
+
RU1rccCsScKJliA (15)
+L5Hj9lgVggsBNHD (15)
+YHCOMx0YCun2Pqf (15)
+21uqo4JahNhi67l (15)
+jOyJDAdrIo1hg42 (15)
+
+ + +
Rules: minlength: 8; maxlength: 15; required: lower; required: upper; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 15
+
entropy: Strong 89.31
+
MBdil08zEnDlWh8 (15)
+4IzbDMSVPYPLTEu (15)
+laWtkNXn5SmUZqG (15)
+NMZvn9Cvn5yir3Y (15)
+1AyePjd4H2P0zzQ (15)
+
+ + +
Rules: minlength: 7; maxlength: 15; required: lower; required: upper; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 15
+
entropy: Strong 89.31
+
0ihqYrI5vku1qMu (15)
+doh5f10uATLvLSc (15)
+J2nNldCTKx0UMmI (15)
+ypbhiIEtke4a8C7 (15)
+veADAExb3jd36Ph (15)
+
+ + +
Rules: minlength: 8; maxlength: 15; required: lower; required: upper; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 15
+
entropy: Strong 89.31
+
R9mk8TbEzI5wbNJ (15)
+xfJCzcij3lEWgs8 (15)
+0xzbLxwbJuy8ThJ (15)
+2Q5K0b7uQHQrsaj (15)
+jZsj1w5F9lYhLu8 (15)
+
+ + +
Rules: minlength: 6; maxlength: 15; allowed: lower, upper, digit, [-.];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.
+
charset size: 64, length: 15
+
entropy: Strong 90.00
+
blNxEj6RnjPvS5S (15)
+4rwGypuympJHE1U (15)
+kS3FRXBBem0n2MM (15)
+BqL2hjY-LRSkgFX (15)
+em23u8iYKeNWuT2 (15)
+
+ + +
Rules: minlength: 8; maxlength: 14; required: lower; required: upper; required: digit; required: [-~!@#$%^&_+=`|(){}[:"'<>,.?]];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&_+=`|(){}[:"'<>,.?]
+
charset size: 90, length: 14
+
entropy: Strong 90.89
+
F?C48IGbEzz[98 (14)
+v3,[4RSP(WmvzJ (14)
+~EoWw1BXUW|M># (14)
+"jnX@+6bof5wI[ (14)
+]H7WZ0+6lCUO3_ (14)
+
+ + +
Rules: minlength: 4; maxlength: 16; allowed: lower, upper;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
+
charset size: 52, length: 16
+
entropy: Strong 91.21
+
kRuRlEwcmMUusYhr (16)
+GOsOvzdDDuYYtxGM (16)
+OuWgAuqXKFyadgXA (16)
+bnfdJDQWCQyfnqdN (16)
+jZvkPCFXqkzuLDqC (16)
+
+ + +
Rules: minlength: 8; maxlength: 15; required: lower; required: upper; required: digit, [!@#$&*];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$&*
+
charset size: 68, length: 15
+
entropy: Strong 91.31
+
eO1aKelnED8Tztv (15)
+EOrRJRM4the4lVY (15)
+Hl4noR49pOjQR&M (15)
+F!zTHBMkPIF#VHU (15)
+gcnLJ9CzR9yT*z5 (15)
+
+ + +
Rules: minlength: 6; maxlength: 15; required: lower; required: upper; required: digit; required: [!@#$%&?*];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%&*?
+
charset size: 70, length: 15
+
entropy: Strong 91.94
+
iVdhF7hmVxrd$Rh (15)
+EYR1L#F$cE8NWcH (15)
+gDhy3WVwsa!qs%k (15)
+RP!VPbBmaht2ZwF (15)
+eeEn0@iDiyi5FS9 (15)
+
+ + +
Rules: minlength: 8; maxlength: 15; required: lower; required: upper; required: digit; required: [!@#$%^&*()+];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*+()
+
charset size: 73, length: 15
+
entropy: Strong 92.85
+
*x3Vhi%dT3rlt$H (15)
+wV9mDA7x7JB9p+P (15)
+%1dO1mBk2&3WnjZ (15)
+VHr&J!U5MKqcSCq (15)
+jCw)dBL#Lijx(P7 (15)
+
+ + +
Rules: minlength: 8; maxlength: 15; required: lower; required: upper; required: digit; required: [-!@#$%&*_+=<>];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-!@#$%&*_+=<>
+
charset size: 75, length: 15
+
entropy: Strong 93.43
+
+pEQU6VXjWq%neV (15)
+buFH3Z@>ENN3V&K (15)
+T_r92ha@S=ZgRA$ (15)
+GqPK9jOE3$lwJKI (15)
+tTkeWMfFM1$ftVM (15)
+
+ + +
Rules: minlength: 6; maxlength: 16;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 16
+
entropy: Strong 94.51
+
q97XCogYVgviFjij (16)
+t87c61y40LcMPoXh (16)
+yxAKkbKen9q6DWYN (16)
+38A4DsrEB3w8e441 (16)
+qE3vHxHuDTwvFvEP (16)
+
+ + +
Rules: minlength: 8; maxlength: 16;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 16
+
entropy: Strong 94.51
+
ex2ngcutuSVsmEuE (16)
+mchm7I30eZ0uZaPf (16)
+Z9Miw0cEEawpXLQs (16)
+k6UCdSSvTez0hmLD (16)
+MqkhSC1nAzhfRirc (16)
+
+ + +
Rules: minlength: 8; maxlength: 16;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 16
+
entropy: Strong 94.51
+
nfcjq1y0J1m05t7I (16)
+jHcQeZtYKdH1SyWA (16)
+myA4Dqjnyrc4g2ri (16)
+RQpmocSpvXXfBIB1 (16)
+ijHc68gxRj6Zj9eN (16)
+
+ + +
Rules: minlength: 8; maxlength: 16;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 16
+
entropy: Strong 94.51
+
jKCZbBspHLQW6f0U (16)
+UZbqbthREnrhsQH7 (16)
+6DBNV3qCLjuMmqTs (16)
+f3uxaxRxarzWTk82 (16)
+CVtm0zkkxopyV87P (16)
+
+ + +
Rules: minlength: 8; maxlength: 16;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 16
+
entropy: Strong 94.51
+
2qWqjIq6bW2tYqAG (16)
+CbcK5WXdfqYuK7aP (16)
+hz9gLPqomfjnKuRw (16)
+MaxRdCvhkea7rESf (16)
+Tmh7XSE6UsoCD79o (16)
+
+ + +
Rules: maxlength: 16;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 16
+
entropy: Strong 94.51
+
ve3sapHZBfqmuo2s (16)
+yJ7pGvD3YkJ20ghn (16)
+YnzM61n53vcynW7P (16)
+nSzbXsxMzXW4TMtN (16)
+K8xCQhoIjEa6MqfK (16)
+
+ + +
Rules: minlength: 8; maxlength: 16;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 16
+
entropy: Strong 94.51
+
w9PSxzEnhMnGM1I2 (16)
+eoW4jQ75METstfCK (16)
+rI0dGC4BjKbJVBRx (16)
+wjwB9KGcs5Kb9Vst (16)
+Bi2d3q0hv2cUkzrZ (16)
+
+ + +
Rules: minlength: 6; maxlength: 16;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 16
+
entropy: Strong 94.51
+
g5Pjf5njibD9v1ZY (16)
+7Fsp3VUWnGka2iIe (16)
+VdvdF9YPM5iKDkqs (16)
+eWBn9NN1Mt03MyDY (16)
+zuwqQo3iRYo6SEqq (16)
+
+ + +
Rules: minlength: 6; maxlength: 16;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 16
+
entropy: Strong 94.51
+
65B5a7KnsPFeSuZC (16)
+F3Y58evLwXVtStsJ (16)
+QFiFddF4tsT3Ysqw (16)
+cuJzn34cMagaWGW4 (16)
+6xoADKjvuShnNfN5 (16)
+
+ + +
Rules: minlength: 6; maxlength: 16;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 16
+
entropy: Strong 94.51
+
cLLdwhhiZb7jp5ap (16)
+4MBhdRJESYFTzd7Y (16)
+2GA3t3zEMNpPb7gm (16)
+q09aTaUehkk9DuYs (16)
+GmvhuMg4cnuI7T2n (16)
+
+ + +
Rules: minlength: 8; maxlength: 16;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 16
+
entropy: Strong 94.51
+
xNwazCYumVyD3YGZ (16)
+jIEkhQi4jNrS56g3 (16)
+hhjGxdPeZHh4eZks (16)
+01rNP0N9GGXUaeVg (16)
+JNskg1NtD9NjUmFa (16)
+
+ + +
Rules: minlength: 6; maxlength: 16;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 16
+
entropy: Strong 94.51
+
J2LeXvifpwxSDqVV (16)
+dfeUvrEJu3F0ekEC (16)
+U9KMdDnehCxLUzoU (16)
+hqHdDzt2qkn7c5I2 (16)
+3UfaGDC9v5Dr5XQA (16)
+
+ + +
Rules: minlength: 8; maxlength: 15; required: lower; required: upper; required: digit; required: [!#$%&'()+,.:?@[_`~]];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~!@#$%&_+`()[:',.?]
+
charset size: 81, length: 15
+
entropy: Strong 95.10
+
eQ7Mbllm,hoiI?3 (15)
+3GI?i?$g7qTlK2o (15)
+3BTrZELE?6@!qB& (15)
+GbLi&qItVTGYI'6 (15)
+SXb&_#W3,v8fHAt (15)
+
+ + +
Rules: minlength: 4; maxlength: 16; required: lower; required: upper; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 16
+
entropy: Strong 95.27
+
M6dhxOd8qgDDEJyR (16)
+LdSbwEB9JlxPfOgV (16)
+nPcfLeL2sa2fuorr (16)
+6d4izpQtsqlo7JEB (16)
+34bStbTUkMzZ8PQm (16)
+
+ + +
Rules: minlength: 5; maxlength: 16; required: lower, upper; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 16
+
entropy: Strong 95.27
+
hEx4Ghp9lLOPNxl5 (16)
+gO8jVLCRUzEnnV3T (16)
+6VpThM5hTekhnrlH (16)
+EBG82gASmC0ADvmO (16)
+KQA0Yw95rTEex5bc (16)
+
+ + +
Rules: minlength: 8; maxlength: 16; required: digit; required: upper,lower;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 16
+
entropy: Strong 95.27
+
ko2Ru1qno8aPS1l5 (16)
+8L7zSRtIKrr8O40X (16)
+9BgOhUn1CjJBMftU (16)
+JmEQmrsoOFcP7blh (16)
+YaDY23xHsACWbxeo (16)
+
+ + +
Rules: minlength: 8; maxlength: 16; required: lower, upper, digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 16
+
entropy: Strong 95.27
+
4NDL6mapd2amEtR4 (16)
+hx4KxlHvpAOcaQ1d (16)
+kCkOXmVaSQrUFgm0 (16)
+9RqiQgDNkRbtANn4 (16)
+GKTHmgAg1mhSUYwA (16)
+
+ + +
Rules: minlength: 7; maxlength: 16; required: digit; allowed: lower, upper;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 16
+
entropy: Strong 95.27
+
LjHVICku7XF5q4BQ (16)
+jOzUX7RqecElJGNM (16)
+pdkLFK89llXLczzQ (16)
+Q4iCWe7hMFhQ6ium (16)
+fvR4dHTOsumP2p5D (16)
+
+ + +
Rules: minlength: 4; maxlength: 16; allowed: lower, upper, digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 16
+
entropy: Strong 95.27
+
THCWLarOA7uSLJRv (16)
+mBI4XEPRsYEbHAVU (16)
+5y3iHYe1wlT6mZxe (16)
+MBCIgjsl1BdOor69 (16)
+r5QudD9MJTt3TgrY (16)
+
+ + +
Rules: minlength: 8; maxlength: 16; required: lower, upper; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 16
+
entropy: Strong 95.27
+
yO08iZafAsBGTfWB (16)
+pDYcCOI5g4t8vUeZ (16)
+106sZHZdWhEh8DCf (16)
+iHcB8s0wumONfGcv (16)
+dNPPIyXeHzZ9Td5I (16)
+
+ + +
Rules: minlength: 8; maxlength: 15; required: lower; required: upper; required: digit; allowed: [!#$%()*+,./:;=?@\^`~];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~!@#$%^*+=`():;\,.?/
+
charset size: 82, length: 15
+
entropy: Strong 95.36
+
zUXTp4=3;aoJ0vH (15)
+=Hs,H6D;\K=ihfp (15)
+Se4NJhh\.j6!*?z (15)
+Yi1wIiTh#5b2a.` (15)
+vMjXn@kS2v42b=3 (15)
+
+ + +
Rules: minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; allowed: [$#!];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#$
+
charset size: 65, length: 16
+
entropy: Strong 96.36
+
Brgkiv2NzNAjVpC3 (16)
+uK7kSPTulRIqHzvS (16)
+cba4LtBwoifYW8hF (16)
+tk6ri0MXoG1ErfEf (16)
+v31svXtFw1r6fjYG (16)
+
+ + +
Rules: minlength: 8; maxlength: 16; allowed: upper,lower,digit,[!#$%@];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%
+
charset size: 67, length: 16
+
entropy: Strong 97.06
+
MgGtifdt8B6sgppV (16)
+kJO6jf9XdrUKlOA$ (16)
+IMXaXbyyRMaKTY7D (16)
+jJ0jNRFNmfxaWm5J (16)
+7LboIg6DpYsmE5Vy (16)
+
+ + +
Rules: minlength: 5; maxlength: 15; required: digit; allowed: lower, upper, [-~!@#$^*_=`|(){}[:;"'<>,.?]];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$^*_=`|(){}[:;"'<>,.?]
+
charset size: 89, length: 15
+
entropy: Strong 97.14
+
7m]b'b=7:`L)3uA (15)
+:1~*SF`.sY_m?E} (15)
+0mN}L@{)XZYC2uH (15)
+8QpXA{CLsV1<^At (15)
+2O)sDr"oNtBWwvq (15)
+
+ + +
Rules: minlength: 8; maxlength: 15; required: lower; required: upper; required: digit; allowed: [!"#$%&'()*+,./:;<=>?[\^_`{|}~]];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~!#$%^&*_+=`|(){}[:;\"'<>,.?/]
+
charset size: 92, length: 15
+
entropy: Strong 97.85
+
CF}rzQ?}(/9Y1/W (15)
+*HN4!u^onlE./f> (15)
+#a45p/9~F%i/Huy (15)
+KA&kKk5aV0}R=gl (15)
+(Y;u]3K9l6"n7yU (15)
+
+ + +
Rules: minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; required: [@!$%^*()];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@$%^*()
+
charset size: 70, length: 16
+
entropy: Strong 98.07
+
oPRsOMNfC4bJc!f* (16)
+M9uDiSK71%zRkH@j (16)
+l32hlrxG(f$fejKE (16)
+HjT9F$ZaueCN1ieu (16)
+k%ijF85qbOtbR8lx (16)
+
+ + +
Rules: minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; allowed: [!#$%&*?@];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%&*?
+
charset size: 70, length: 16
+
entropy: Strong 98.07
+
KR90IMCwxHT@YsME (16)
+Se5lHF1FU2hsQGdh (16)
+Njm8WI7s*&mpRCuc (16)
+&%eK%GjDB#?46&P1 (16)
+DLE$lIpaA0kVnXod (16)
+
+ + +
Rules: minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; required: [@#$%^&+=!];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&+=
+
charset size: 71, length: 16
+
entropy: Strong 98.40
+
8x75PY%oJzrNtsGA (16)
+dTkjjc01Pn$IqA3Z (16)
+pQAibCrSe9gO+vjO (16)
+FgCkvojI#MAM1r=d (16)
+pHnrm8sZrGT6du@n (16)
+
+ + +
Rules: minlength: 6; maxlength: 16; required: lower; required: upper; required: digit; allowed: [!#$%*@^_~];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~!@#$%^*_
+
charset size: 71, length: 16
+
entropy: Strong 98.40
+
LUQz12IEU%kBR0Dn (16)
+mzTV0Et7z6kmv2s5 (16)
+yqUj192V8x$3nx5A (16)
+WLE2jXEB~h%yrdoa (16)
+kn6$$Fa2R9eQ43Qk (16)
+
+ + +
Rules: minlength: 8; maxlength: 15; required: lower; required: upper; required: digit; required: special;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\"'<>,.?/ ]
+
charset size: 95, length: 15
+
entropy: Strong 98.55
+
b9Tu^}U4]jBC X& (15)
+tFMj9fT'Za-,exZ (15)
+U8e[kE5vpkzjXur (15)
+l=aVoeMMA9g2CSa (15)
+o-rkVWS&>8Q7o<. (15)
+
+ + +
Rules: minlength: 6; maxlength: 15; required: upper; required: digit; allowed: lower, special;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\"'<>,.?/ ]
+
charset size: 95, length: 15
+
entropy: Strong 98.55
+
E*kMICnV*H:2L2F (15)
+U03axR>:Z>D8-BL (15)
+1T3c3_eB{4@%gQW (15)
+qjrnVma<P8%@GQ~ (15)
+xBtmN-~r@,6r?f" (15)
+
+ + +
Rules: minlength: 6; maxlength: 15; required: lower; required: digit; allowed: ascii-printable;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\"'<>,.?/ ]
+
charset size: 95, length: 15
+
entropy: Strong 98.55
+
1;5?~tk`:Wa!iNC (15)
+FFLy<Ph5ng5C$X/ (15)
+'hDO?L]E6u<aF0H (15)
+9xHW+g(A37LV!iR (15)
+q,3kAO8Gj8o%eM7 (15)
+
+ + +
Rules: minlength: 9; maxlength: 15; required: lower; required: upper; required: digit; allowed: special;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\"'<>,.?/ ]
+
charset size: 95, length: 15
+
entropy: Strong 98.55
+
~{1.lC0r(hruYsT (15)
+3#tM2xG@~wLC0?j (15)
+jGi)4iG,p~A!woZ (15)
+-dE]qx&uSW7HRv, (15)
+157FvSy^2JY8K|i (15)
+
+ + +
Rules: minlength: 8; maxlength: 16; max-consecutive: 2; required: lower; required: upper; required: digit; required: [#$%*+.=@^_];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@#$%^*_+=.
+
charset size: 72, length: 16
+
entropy: Strong 98.72
+
GQ9RRDW@t2m86Nt7 (16)
+JIKaBR#P8HC1kh9u (16)
+I+9^rK@TJrrFjMBJ (16)
+lBntCAs1FWDBtG=E (16)
+c4bJyjf75Prete@M (16)
+
+ + +
Rules: minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; required: [!@#$%^&*()];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()
+
charset size: 72, length: 16
+
entropy: Strong 98.72
+
^l8pss4yw6H)ZlG* (16)
+4qB&H1^2WbzOiqaG (16)
+gDK(xZzMAoT8kzn% (16)
+#zdTwG2Lu$lKA@s^ (16)
+#Yq3N@&PUKr^5P^e (16)
+
+ + +
Rules: minlength: 8; maxlength: 16; required: lower; required: upper; required: digit, [-!#$%&*?@^_];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-!@#$%^&*_?
+
charset size: 73, length: 16
+
entropy: Strong 99.04
+
&E#AlCxaCnhmaWdl (16)
+8$k@q3uG@2yIg5n? (16)
+R^7gvm*^xhUh2qKO (16)
+FEH8dDFzaohnrq$U (16)
+okcn^9l$JNilXnzf (16)
+
+ + +
Rules: minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; required: [-]; required: [!@#$%^&*()+];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-!@#$%^&*+()
+
charset size: 74, length: 16
+
entropy: Strong 99.35
+
K1+WWUeyXdyD-ows (16)
+x-yDwWFOu+-9Aq8H (16)
+&+(saSqJ-mQxq3Th (16)
+zEk$XK@7tSFb)e-D (16)
+Q0-DHCA%apll5TuN (16)
+
+ + +
Rules: minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; required: ["!@#$%^&*(){}[]];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*(){}["]
+
charset size: 77, length: 16
+
entropy: Strong 100.27
+
(TkgJLH4tU[!!n5Z (16)
+6wufGw4)08JY^4vi (16)
+0y9fJA0g3Rwy}2^K (16)
+5}6pRBOFmfgP64my (16)
+Yq1MEFaBXtxnf(e{ (16)
+
+ + +
Rules: minlength: 8; maxlength: 16; required: upper; required: digit; allowed: lower, [!@#$%^*(),.;:/\];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^*():;\,./
+
charset size: 77, length: 16
+
entropy: Strong 100.27
+
a6gL2I);X\gSPxb( (16)
+hAh!Ap/u8jortXy* (16)
+HReK4apY8!WiztGb (16)
+j3fiY:zmZ6mE0nl3 (16)
+oT52,XA;ovg$y6ge (16)
+
+ + +
Rules: minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; required: [!@#$%^&*()+~{}'";:<>?];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~!@#$%^&*+(){}:;"'<>?
+
charset size: 83, length: 16
+
entropy: Strong 102.00
+
iU<A"xy+LQgf*z'3 (16)
+E^DUbul<iwe{aiB3 (16)
+H4Yrhg7)p&p"A;It (16)
+o9DV&GY<fV"N}T9B (16)
+3)FbwH4YeW%sy~a8 (16)
+
+ + +
Rules: minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; required: [#$%&()*+,./<=>?@_{|}~];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~@#$%&*_+=|(){}<>,.?/
+
charset size: 83, length: 16
+
entropy: Strong 102.00
+
5Vub2OKabTXC@6Bd (16)
+Gi@t9/%y*w1qGgv4 (16)
+ZPW46PyZApx*K_u5 (16)
+QOe7GDvXK&m.6.s8 (16)
+q0_8WlMegB@A1bWr (16)
+
+ + +
Rules: minlength: 7; maxlength: 16; required: lower, upper; required: digit; required: [`!@#$%^&*()+~{}'";:<>?]];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~!@#$%^&*+`(){}:;"'<>?]
+
charset size: 85, length: 16
+
entropy: Strong 102.55
+
?o>avlo2oWv1Dhc] (16)
+bFYBs$K8>7wRW<~f (16)
+HVL{hc}1n+8x8*Qd (16)
+Xoj!X?A)5H~6gEvK (16)
+{o`]OLv3n@YFG1BP (16)
+
+ + +
Rules: minlength: 7; maxlength: 16; allowed: lower, upper, digit, [~!@#$%^&*+`(){}[:;"'<>?]];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~!@#$%^&*+`(){}[:;"'<>?]
+
charset size: 86, length: 16
+
entropy: Strong 102.82
+
N``5D`cZaK@CrZeU (16)
+ubygE3*dC7rq[4c( (16)
+pOg61f)nJxVhx#"n (16)
+F%Qkg^f65*8a'33j (16)
+;Hu$[Wt(mEf1u}Zp (16)
+
+ + +
Rules: minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; allowed: [-~!@#$%^&*_+=`|(){}[:;"'<>,.?/\]];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\"'<>,.?/]
+
charset size: 94, length: 16
+
entropy: Strong 104.87
+
rxg0}RvG{5OCrPHU (16)
+DT3-EEjg(3$NN0KR (16)
+!DaK)L}(OaPEO_9D (16)
++3r~(iuCwO'\slUH (16)
+^@Q6[1KQ3]aTy7vi (16)
+
+ + +
Rules: minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; allowed: special;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\"'<>,.?/ ]
+
charset size: 95, length: 16
+
entropy: Strong 105.12
+
vA)4=Wx}c>b7ZSu, (16)
+;e.y-tO\Ce53,we[ (16)
+Fb^7c2'9BOl^)rn2 (16)
+4}O1y7v/wMdx`[OV (16)
+U7/sMs"xK2a:WQKn (16)
+
+ + +
Rules: minlength: 8; maxlength: 16; required: lower, upper; allowed: digit, special;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\"'<>,.?/ ]
+
charset size: 95, length: 16
+
entropy: Strong 105.12
+
9ts'"Im-v~pFHjA] (16)
+xgFD7ipW10^J^02j (16)
+vUDLlMyGnW1J*_U  (16)
+8cX?7kqf(fid#\o0 (16)
+uww|N6ITWAMS!\~, (16)
+
+ + +
Rules: minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; allowed: special;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\"'<>,.?/ ]
+
charset size: 95, length: 16
+
entropy: Strong 105.12
+
`4ndJB]T<L!&&*8h (16)
+,O-Ds>w8ec)ex=dX (16)
+sBb=@>w5sF %,#W' (16)
+D8{PO7EGhvNyC]r4 (16)
+@WToNq{{f9NGMi6' (16)
+
+ + +
Rules: minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; required: special;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\"'<>,.?/ ]
+
charset size: 95, length: 16
+
entropy: Strong 105.12
+
Z;0v{[Z3uH\U)P0P (16)
+\`QfWj->59y#Fsp; (16)
+S{uVsl\e0H*E0js[ (16)
+Z@%F^DtkYiHvIRn6 (16)
+Jt&x&xojWAgHar50 (16)
+
+ + +
Rules: minlength: 8; maxlength: 16; max-consecutive: 2; required: lower; required: upper; required: digit; required: special;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\"'<>,.?/ ]
+
charset size: 95, length: 16
+
entropy: Strong 105.12
+
#hU[!5Y"z-=oS65i (16)
+|y?0cU&dM;Zy1A\e (16)
+dOmif8m{>VD"LMz5 (16)
+5PhlYUl{QVJvsGQf (16)
+^8o{r:?hgj8WcovQ (16)
+
+ + +
Rules: minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; allowed: ascii-printable;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\"'<>,.?/ ]
+
charset size: 95, length: 16
+
entropy: Strong 105.12
+
upt;Ez-42;4wP\:k (16)
+0:=v+MI!h})TQLoR (16)
+/}q8K9N5B5=j ak? (16)
+qQ,L~MfMzF^6beOp (16)
+f1FXf^#wu@xVZ.zV (16)
+
+ + +
Rules: minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; required: special;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\"'<>,.?/ ]
+
charset size: 95, length: 16
+
entropy: Strong 105.12
+
8gzIS'EvPht'KIve (16)
+TrdwF[oQaS44-t[h (16)
+n$y9^_Wyj fQb[gp (16)
+/=tPhwDWK('2wzS~ (16)
+%yGa3~S2WJxVES0x (16)
+
+ + +
Rules: minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; required: special;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\"'<>,.?/ ]
+
charset size: 95, length: 16
+
entropy: Strong 105.12
+
Zhd;Iyu8e-vkn6/C (16)
+c!GN;4<2IIWK8:Y' (16)
+gGf;]W4V*p&G~Atb (16)
+E7=K8J\D.j5OV1L" (16)
+ZqQFIh@Dd@X0f#>H (16)
+
+ + +
Rules: minlength: 7; maxlength: 18; required: lower, upper; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 18
+
entropy: Strong 107.18
+
eoPXfUxqD53nGUiEkV (18)
+s0bbwBvkDKdWxAbuEG (18)
+PeJ9F7v4HoOgfgAJDS (18)
+xTimXripefodagh7cU (18)
+JHvxqMiZ0I3YHJC5j2 (18)
+
+ + +
Rules: minlength: 11; required: upper; required: digit; required: [!@#$%&_];
+
charset: ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%&_
+
charset size: 43, length: 20
+
entropy: Strong 108.53
+
0_VMKLMRBTS9LUSCI81S (20)
+QR_KKLI1#7#A59!QF_0! (20)
+LDK6MX71&&SRZ$TD!06# (20)
+N%L3JE26CL8G$$KF24$1 (20)
+V7BQDF0WF!XLNW1DE4W8 (20)
+
+ + +
Rules: minlength: 6; maxlength: 19;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 19
+
entropy: Strong 112.23
+
RfSZviyujpk3q5qYGpH (19)
+LK7ZXNjNkeeQSYfJbIp (19)
+aGjB2DpnNBQjrq0mFvT (19)
+MIkSfVzXHhR9Ie0CCdi (19)
+YF6TiEP0f6edCDubbFU (19)
+
+ + +
Rules: maxlength: 19;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 19
+
entropy: Strong 112.23
+
RkvVfmnQxTudbEkt33k (19)
+CfNRc9syGnPMnLjRVTv (19)
+Zj2J3sFfnKvbSieHWh5 (19)
+W9mZVymeS0RBGYD3DTd (19)
+hV76KqwtDoXwnBfyJL4 (19)
+
+ + +
Rules: minlength: 12; maxlength: 128; required: lower; required: digit; allowed: [-!#$%&*+/=?^_'.{|}];
+
charset: abcdefghijklmnopqrstuvwxyz0123456789-!#$%^&*_+=|{}'.?/
+
charset size: 54, length: 20
+
entropy: Strong 115.10
+
4owa?#20^k8'eof.#cye (20)
+1?kl#a-3yhrn#r#vhq76 (20)
+rf6.._&-'d9''v08500| (20)
+o'_t+qj#3pae{0v6u0|s (20)
+$4e1qpfpd3#e#ki?o=ng (20)
+
+ + +
Rules: minlength: 8; maxlength: 18; required: lower; required: upper; required: digit,[-!"#$%&'()*+,.:;<=>?@[^_`{|}~]];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;"'<>,.?]
+
charset size: 92, length: 18
+
entropy: Strong 117.42
+
spy~y1(ZGrB0{mPjo$ (18)
+bg,J&nkO-k0g*uUf23 (18)
+(oi@~Hd`wWM7,$JjP] (18)
+@@~Zg3:9d``IJ7&EIx (18)
+3,&?Lw2&isNBVdH$uv (18)
+
+ + +
Rules: minlength: 8; maxlength: 72;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 20
+
entropy: Strong 118.14
+
27xyUcfIXL3XEYzGFnYi (20)
+IRwhVrHTw2ANc8HmxWwN (20)
+0S8M5PijPSQpsyaMF7wo (20)
+vWE6VddoueofZDd7gjy1 (20)
+eNHBASXVGcRdN696nfTk (20)
+
+ + +
Rules: minlength: 7; maxlength: 72;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 20
+
entropy: Strong 118.14
+
SknsBm2vmBWxKq9fkse1 (20)
+GHNdpUjyZGs1ajjmMfPF (20)
+iFUjJo8RCMoiGYbcSV5E (20)
+Mtkni6k4tLaTRA8iai1s (20)
+1cmDFjUG1MrmbZIgpp6G (20)
+
+ + +
Rules: minlength: 6; maxlength: 20;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 20
+
entropy: Strong 118.14
+
jcozNq05YAxG1iz41VKH (20)
+kp6agnnuDvukCz6T1Luf (20)
+5b91eKJsjj8sb3G7Ckx4 (20)
+nYvvRkLAaS8ruKqa43Yi (20)
+91agmo5NWp6DemRLVI1A (20)
+
+ + +
Rules: minlength: 10;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 20
+
entropy: Strong 118.14
+
p9zt3cZSSADptNwsAHmN (20)
+S2qVKu1h3D0Apa37NPpK (20)
+NgW8ZZvZ5UUiozpspLGV (20)
+NaI2FBa9bFxfAj3gsW8e (20)
+in0hQ0i4TS8kN8pgwyXv (20)
+
+ + +
Rules: minlength: 8;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 20
+
entropy: Strong 118.14
+
HSPM15XzJpK6rJm2Bayi (20)
+EwBiQKcGyiwujA5ZXkHe (20)
+REURrAIIVv4GvDfV4PeX (20)
+DvJoMv9gNsexDYFAzz6P (20)
+W10gPMFwk9gFhxrKgT3C (20)
+
+ + +
Rules: minlength: 6; maxlength: 32;
+
charset: abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
+
charset size: 60, length: 20
+
entropy: Strong 118.14
+
SD3Z90bESd5dLCnXumRs (20)
+5NZrEGkh390KUkSnb55I (20)
+aKPsZApPZRCRTZuD5t7b (20)
+8HZXpYRZ1mY8kK0aNpxn (20)
+LrD2uLwHs634k67Hgp24 (20)
+
+ + +
Rules: minlength: 6; required: lower, upper; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 20
+
entropy: Strong 119.08
+
vBERxaoybsssC3X3J7mh (20)
+6LsekcZcdQBSgX1mqUOq (20)
+Sn9FXyIFflvfAXIQEXYG (20)
+03FucPFnn5S9SdkQc5hf (20)
+uk7Ql187cugJbEWmTLbU (20)
+
+ + +
Rules: minlength: 8; maxlength: 25; required: lower; required: upper; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 20
+
entropy: Strong 119.08
+
4JQq6209tvsQiwNi5xKM (20)
+XQfITKe072Ub1tDt6UZs (20)
+jJVv7ilaxD7hfR8e61Xv (20)
+3kuCRWBBkfRRNpeltnwg (20)
+60nqXvejVlgXJ8ZBKSqj (20)
+
+ + +
Rules: minlength: 6; maxlength: 20; allowed: lower, upper, digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 20
+
entropy: Strong 119.08
+
1JHbtuTwoAJ4QFTcBZl6 (20)
+8YpAeYb5GSfUjAm71pKz (20)
+SBmUNc3Nqie7EniC5bQp (20)
+fzPRsgeriBxJSk3nnIEd (20)
+0vJqDFOhu21nB2xWBDa1 (20)
+
+ + +
Rules: minlength: 8; max-consecutive: 2; required: digit; required: upper,lower;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 20
+
entropy: Strong 119.08
+
2X7oVIIR8RCapViCjVeg (20)
+E3l5mLaZRKPmyshbnB7F (20)
+75SdvFTyTIrgyNruhP6H (20)
+eScFAHjP1R3loqrrEGn4 (20)
+TneWYlhZ6VnWBibOWhGv (20)
+
+ + +
Rules: minlength: 6; maxlength: 20; required: lower; required: upper; required: digit; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 20
+
entropy: Strong 119.08
+
sG9zS1JlrtlNDinAuRAM (20)
+XnbaHHFPRKzlOtlo2WcK (20)
+OYPouAHXp9OW1ZsqKmcY (20)
+HTYQX90OMeQ2uFjCbvBO (20)
+EL2OPagr4zfbAdmAF0aW (20)
+
+ + +
Rules: minlength: 8; maxlength: 20; max-consecutive: 2; required: lower, upper; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 20
+
entropy: Strong 119.08
+
aLFfWTbRZaN9muqvBcJ6 (20)
+ELqnZ8QfWneC79V3whwL (20)
+R2UsfPWtU9iONK3HXpya (20)
+9NwUyFZ50vZIskXgHBSd (20)
+tf1NqWJeYsLTWoRLAnVB (20)
+
+ + +
Rules: minlength: 7; maxlength: 100; required: lower, upper; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 20
+
entropy: Strong 119.08
+
c0SnIrtLmk1Rvhhqfx3P (20)
+ERSiQqg4BypC1TTIuk7g (20)
+hFcXDghB4t9IMncn1TpB (20)
+1SAGWinibFbwQEvsvhex (20)
+xtccIGhj4ELSgn6gj6vj (20)
+
+ + +
Rules: minlength: 5; required: lower, upper; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 20
+
entropy: Strong 119.08
+
8h9rvakS5hle8dyQ24Lq (20)
+Rz65fr1nb0HqvqHm4g6S (20)
+P4dbsdnSFwuPyJhmebFU (20)
+oMLjFHNE80akXGb4wxeO (20)
+Yjp4qrJk1DZdX4iamJbp (20)
+
+ + +
Rules: minlength: 8; required: lower; required: upper; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 20
+
entropy: Strong 119.08
+
BWcYdlBUK1QKuF469Ks7 (20)
+A1awYUYueymo4JtoesiP (20)
+AI1gJTCv0X9jKYC9qMfP (20)
+Ga5ZSlHxGkyxMMR4KGtc (20)
+4Fb8vIT0CaaIR0U4CYzJ (20)
+
+ + +
Rules: minlength: 8; maxlength: 20; max-consecutive: 2;required: lower, upper; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 20
+
entropy: Strong 119.08
+
16NYsZcby7a1sIOcGh4g (20)
+CGIZnOmoWqfIYvh6nVRx (20)
+eONRCPVjJK9sPm2B51aN (20)
+SvzbSFzqO4A76cbBxSoS (20)
+sF2faylPxn0mXcFP9kd7 (20)
+
+ + +
Rules: minlength: 8; required: lower; required: upper; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 20
+
entropy: Strong 119.08
+
uIJWmrLcV8gUPviEH7dR (20)
+Vka7t4F6XK4enXfYfUfM (20)
+FfgVLgPDaYCdesIDF95f (20)
+ufY1zJ5hcCRAierhYQRQ (20)
+JvoUfpRPcwe5kA0U1Tet (20)
+
+ + +
Rules: minlength: 8; maxlength: 30; required: lower; required: upper; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 20
+
entropy: Strong 119.08
+
J12lbgEO8zRl204OL7NX (20)
+vziMFWauOJlwE7XUm7Oh (20)
+Xf0VNAG1TpEQifCo4DMy (20)
+7a5zNQjzhKPC1Kbju0Pm (20)
+mA2aMkONKVcqpoPa0YjF (20)
+
+ + +
Rules: minlength: 8; maxlength: 45; required: lower; required: upper; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 20
+
entropy: Strong 119.08
+
sWjWGgLgTdo2XsMWTjVk (20)
+SNQj5bfwKGrXu4ZT85CD (20)
+ZsqlRwvWZG5Jc0eQsm0f (20)
+6Eud0OxlgvB0Fm88iMJK (20)
+2HmWvMvTkBjeaJlUUgBU (20)
+
+ + +
Rules: minlength: 8; maxlength: 20; required: lower; required: upper; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 20
+
entropy: Strong 119.08
+
OaL8XftlEy3RmQxZPR8M (20)
+EpdhwknPyw3Kws0Q9ogq (20)
+qMQB0p1S6ZMVPcogk9zg (20)
+MB5bg1TPd6QSjo5JCJzF (20)
+2aJdcojOoPukOebD77I0 (20)
+
+ + +
Rules: minlength: 8; required: lower; required: upper; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 20
+
entropy: Strong 119.08
+
hFOpqXpTKuPY0stnQxsg (20)
+c2ouDckRQYfffdAcPn4Q (20)
+70F07poaBinjeTzvVD7v (20)
+gcgz29XAh6nzBMEyfdBt (20)
+LBQ5UtTkeQ7zJDn5wnaI (20)
+
+ + +
Rules: minlength: 8; maxlength: 30; required: lower; required: upper; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 20
+
entropy: Strong 119.08
+
dM22cxbosrD48d0UX4qh (20)
+2bYHiSYtY8wVylfVbMrb (20)
+JTsFJA0w0327zECbXRdb (20)
+faLgObFQOt0CAfLEkzgb (20)
+bUTEZ1ZkmdBYit07mfl0 (20)
+
+ + +
Rules: minlength: 8; maxlength: 32; required: lower; required: upper; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 20
+
entropy: Strong 119.08
+
EWEH5z7yvAk5ueiFlluf (20)
+7Ony1PWiD2q3oiLVFkr2 (20)
+o2JrYsKNVeYvSpKQ5hrD (20)
+hN1GmgFUhloj2YhNXeqv (20)
+6vksjaek7eYV09VigggJ (20)
+
+ + +
Rules: minlength: 6; maxlength: 20; required: lower, upper; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 20
+
entropy: Strong 119.08
+
H8IgdDPbw0AuRhpN8Z4q (20)
+zoVFrqneSkNSXQ4dTtPX (20)
+hdxCm11YU1mS6Y0pOcQG (20)
+xGXYXhzweuHaL7bNdTDg (20)
+b0IpPTeyy0YVFzf154PO (20)
+
+ + +
Rules: minlength: 8; maxlength: 20; required: digit; allowed: lower, upper;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 20
+
entropy: Strong 119.08
+
i7IcR5VRNhZ0JkHhAa9M (20)
+6WvmoYmdV7sFPq98i9sO (20)
+wgc7GfPAsrbu78iJ3VE4 (20)
+Ii05ew9aNXhHmyKIfxNC (20)
+tslXPUGbIvQ4pcxP5YIk (20)
+
+ + +
Rules: minlength: 8; required: digit; required: digit; allowed: lower, upper;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 20
+
entropy: Strong 119.08
+
L2OHVl9xzyfhT08FIkbj (20)
+MnKKwOf4Y8mJrd4aZWdd (20)
+9C0JJa0KQd7hzAmPnIfZ (20)
+UN0YSazDhcqAMEfEdilC (20)
+ofKb5PsxXjLlEatjlzv6 (20)
+
+ + +
Rules: minlength: 8; maxlength: 32; required: lower; required: upper; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 20
+
entropy: Strong 119.08
+
ahxqhnL4M4IVtOiYPl4i (20)
+zu0lCYEMGYaH8jPu4b8j (20)
+Gt3qPEV73B49ZtLmVFpg (20)
+DQbJC0n4ilHYqlHEmh3Q (20)
+eseEi5XPkZ0Bk1gizeSo (20)
+
+ + +
Rules: minlength: 6; maxlength: 20; allowed: lower, upper, digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 20
+
entropy: Strong 119.08
+
btbp30yGmghgYAmLFcNl (20)
+4BJ8rG5bRSxd3MsBgUYT (20)
+k7hprdi0wFRh08hVaopB (20)
+na18MXfHJisIpW4imFoN (20)
+vuzjsKrW4t0zFfWJWnyI (20)
+
+ + +
Rules: minlength: 7; required: digit; allowed: lower, upper;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 20
+
entropy: Strong 119.08
+
JcxGRQ5qJtSDuA0PyGhs (20)
+TH115i2ISoZiq1iVql6f (20)
+LUmfd8m4vEB9kHoXoPr6 (20)
+Ua5g8rWQpkUDsVyLeOnz (20)
+cXkVhu8ZXu2nlEoVlr9T (20)
+
+ + +
Rules: minlength: 8; maxlength: 38; allowed: upper,lower,digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 20
+
entropy: Strong 119.08
+
7CtjfCV7n694iduD8V0y (20)
+7FC6N90yTYAstde99gVp (20)
+oI4q5mjAauopd82O3m3E (20)
+hvxcWjHdKsKn12ngyzA0 (20)
+ZI5YconM5Q9UNN2FJlPd (20)
+
+ + +
Rules: minlength: 5; maxlength: 20; required: lower; required: upper; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 20
+
entropy: Strong 119.08
+
kf2lceYKSskVgEPZqg97 (20)
+p0XgTRhrr7bPE10VsFlj (20)
+LVpCMDdJ0fl9x8JYEBQs (20)
+Ga3u9dTzIY1EWKlqwbbW (20)
+DSTN2O5gRNxxV3yzAOpJ (20)
+
+ + +
Rules: minlength: 10; maxlength: 20; allowed: upper,lower,digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 20
+
entropy: Strong 119.08
+
ReetBQXbbN3jgWBXbx9A (20)
+xOWbiyWexeHPnwcqPFS2 (20)
+naATvq7VRX14XDDZgx0x (20)
+PS2jitYVLVrc2HUSh3gb (20)
+Id9lQaOw60OyEWuKOGrU (20)
+
+ + +
Rules: minlength: 6; maxlength: 20; required: lower; required: upper; required: digit; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 20
+
entropy: Strong 119.08
+
y5bKCxGgmhB85XiW4jm8 (20)
+0AgmGwTe97TKtHRe0zf6 (20)
+k17va3eiwuaJSvL0KJcd (20)
+EKMdDefMGLI072XZ32KL (20)
+z6RaxOdmqZwuAFapGAuy (20)
+
+ + +
Rules: minlength: 8; maxlength: 50; required: lower; required: upper; required: digit; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 20
+
entropy: Strong 119.08
+
skGiZrmWAJVxKdkwaYx1 (20)
+DpIXaPUA1pFulP4NXCgP (20)
+YsuKQi4da8ZygiwGKgTv (20)
+AN6qOM9o09r8CNfEeFnt (20)
+7KVXLMmb0rRYR7u9edKU (20)
+
+ + +
Rules: minlength: 8; maxlength: 64; required: lower, upper, digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 20
+
entropy: Strong 119.08
+
w2bpNed8JvFtEwARCfvg (20)
+nLdYKk87QBlbUPl9gU3U (20)
+iXzgiGm0t8Blnke4WqN1 (20)
+tRAOSvU75xeDKVNBMmxi (20)
+HC95Wab9xZEyXjUaf9UL (20)
+
+ + +
Rules: minlength: 8; maxlength: 32; max-consecutive: 6; required: lower; required: upper; required: digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
charset size: 62, length: 20
+
entropy: Strong 119.08
+
ixiyKXotO14cacZqM9H5 (20)
+wv9sJm606sMEEw1UiEbZ (20)
+nbcqpWa1wOacvXryfW8O (20)
+UPejshsfsKCRXrdkF6wi (20)
+z25fr85fzGhvgMoaN94c (20)
+
+ + +
Rules: minlength: 6; required: lower, upper; required: digit; required: ["]
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
+
charset size: 63, length: 20
+
entropy: Strong 119.55
+
Pdi3M8fzJ"5EuNHvSg7A (20)
+QnoD91OIY4270x5S"jW1 (20)
+mUkpnsKdYdQU"49ToRWa (20)
+sdk8E91tbH"WcZd9gBRN (20)
+ZUzkvUo7QJSu5C"52LOT (20)
+
+ + +
Rules: minlength: 6; maxlength: 20; required: lower; required: upper; required: digit; required: [-];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-
+
charset size: 63, length: 20
+
entropy: Strong 119.55
+
RRY1X3g2ARKksgP-j250 (20)
+-FWRsTicnux3Z13t35ee (20)
+U13yHDYD135ZAu-SPUCw (20)
+h4-eJ6E9485cDCX2lySL (20)
+-KX86LdpFDBjmqwiZELr (20)
+
+ + +
Rules: minlength: 8; maxlength: 20; max-consecutive: 3; required: lower, upper; required: digit; allowed: [!#$*];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#$*
+
charset size: 66, length: 20
+
entropy: Strong 120.89
+
4Pja5yc5MSFblQwVC3yi (20)
+0Jdzvb3s7MHhHbl2!Vxf (20)
+X8JOYh#fN*rYL5!1vAj7 (20)
+Zh4zK14*7aphB59SLqwe (20)
+bJllyqkt0KR7YdVITzE4 (20)
+
+ + +
Rules: allowed: lower, upper, digit, [!$#@];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$
+
charset size: 66, length: 20
+
entropy: Strong 120.89
+
t2qqaKNYAInXAdU!Cnmh (20)
+Mk6TQSLzjJvJbBNHZyw9 (20)
+r01lSqIcpzEvsWXR@nps (20)
+8r6AGJX0K3uCWcMweHy7 (20)
+o5trv6hsJkaBDvp!hbwY (20)
+
+ + +
Rules: minlength: 6; maxlength: 50; max-consecutive: 2; required: lower, upper; required: digit; allowed: [_!@$]
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@$_
+
charset size: 66, length: 20
+
entropy: Strong 120.89
+
sGhG_4n@3FBSBbYy2u$U (20)
+4P3Ws7gkVEh2zFMU07GO (20)
+YjsBqq3l7Mw5v8Ilqhcc (20)
+EI$v9fy1Pt1OhtfVhWj$ (20)
+I0dEf9OnANOEqHocu$Vf (20)
+
+ + +
Rules: minlength: 8; required: lower; required: upper; required: digit; required: [$#%!];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#$%
+
charset size: 66, length: 20
+
entropy: Strong 120.89
+
RcgUjL8gDhMl#wcF2ial (20)
+ngpjcvc33zZNOI%L7dhd (20)
+pmMG4OVurglj$yMGFXNx (20)
+53z1nsxu04KXf%4YHc0m (20)
+TzEqhbEF!4GYGxq2dkSI (20)
+
+ + +
Rules: minlength: 6; maxlength: 30; required: lower; required: upper; required: digit; allowed: ['.@_];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@_'.
+
charset size: 66, length: 20
+
entropy: Strong 120.89
+
7DaIoSf.AHGX5ZZbTKoF (20)
+RO2oZjQcUNc@DFu2i33P (20)
+vPHFTvkapT1h4kTrX4dY (20)
+yc7nmHhGMlwzAvykY4Ab (20)
+T7gQzLkDCd2c0PruzY.p (20)
+
+ + +
Rules: minlength: 8; required: lower, upper; required: digit; required: [!@#$];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$
+
charset size: 66, length: 20
+
entropy: Strong 120.89
+
PA8ezcmObIPQsu$yzB2b (20)
+Na!VaizxAzUTwUFi5@#A (20)
+G$cHsL94oll92nNw4mfI (20)
+xB9#93us7MeUC1AfLR5u (20)
+KNNFYrSc4sLMLsRXs@UG (20)
+
+ + +
Rules: minlength: 8; required: lower; required: upper; required: digit; required: [!#$@];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$
+
charset size: 66, length: 20
+
entropy: Strong 120.89
+
cocIJIpqT1C4lhIF62l@ (20)
+9BwZ#HuBrCWPKRalPe2N (20)
+ZxruDXFOU!nVYQ5Ceuw! (20)
+RiliRj#LvegXa0@HMfeA (20)
+4B9t4PT$sTmcspX6Bp2Q (20)
+
+ + +
Rules: minlength: 8; maxlength: 20; max-consecutive: 2; required: upper; required: digit; allowed: lower, [-_&#@];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-@#&_
+
charset size: 67, length: 20
+
entropy: Strong 121.32
+
yUtPvf-g9Y-d7XlR5CLM (20)
+BfpYKbg0p96Mfqdz&T-Z (20)
+ykHRZ6Xsi_SnRmHNO9iU (20)
+up6_QbfyXFCFEMJMueMJ (20)
+YOEcFW4uiGRQV3jNBGzF (20)
+
+ + +
Rules: minlength: 8; maxlength: 20; required: lower; required: upper; required: digit; required: [!$*+@];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@$*+
+
charset size: 67, length: 20
+
entropy: Strong 121.32
+
KRir5SAe6CKRjZifc+Lq (20)
+tjhxxQN*ZR*Nvw3ame2x (20)
+y60Ju!boN8W*5c0rrGaU (20)
+eb+1!ym*7QHpJ!xvXNAj (20)
++3of7c4qQuYc4sirVkmD (20)
+
+ + +
Rules: minlength: 8; maxlength: 225; required: lower; required: upper; required: digit; required: [!@#$%];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%
+
charset size: 67, length: 20
+
entropy: Strong 121.32
+
o4ztKSHvwGcglPgEKxt$ (20)
+VMhaX2JujJeEIin6RLK% (20)
+emeJSOf8HWKYSEyKWra% (20)
+LT4gey0@2CeDz3!WKGPC (20)
+X5%vlBzs$QyPwqwY5opr (20)
+
+ + +
Rules: minlength: 8; allowed: upper,lower,digit,[- .=_];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_=. 
+
charset size: 67, length: 20
+
entropy: Strong 121.32
+
WKV18hylsb1Au34uFkyW (20)
+CUn5TILOP44X1ttaKndn (20)
+ MIxaTC EykbC5LfTn-z (20)
+dgaMPsI=yl59QimgbJ5R (20)
+U_vc0sikrsQYSMqhMQPm (20)
+
+ + +
Rules: minlength: 8; maxlength: 20; max-consecutive: 4; required: lower, upper; required: digit; allowed: [%&_?#=];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#%&_=?
+
charset size: 68, length: 20
+
entropy: Strong 121.75
+
Hwjt0=uy2FiFnIvu66jQ (20)
+EZ6#O5l#PxzcZQGh%YGR (20)
+6Eou?3whSBBAr=w2XyE9 (20)
+lzn5hdkbn2U2UwwRLJLp (20)
+xsbgwIVdhWaN_D10K9Wz (20)
+
+ + +
Rules: minlength: 8; maxlength: 20; max-consecutive: 3; required: lower, upper; required: digit; allowed: [!$*?@|];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@$*|?
+
charset size: 68, length: 20
+
entropy: Strong 121.75
+
DCsQ6XVFs3Rs2KfL7F|c (20)
+dzJ9svjXPhvc!tBHcz0d (20)
+rkX9lip*ZcVi*|FFgN1? (20)
+xekEnzLByGYXW?gtk7Bc (20)
+d2N4H2?qH0dZFI9uvFLi (20)
+
+ + +
Rules: minlength: 8; maxlength: 20; allowed: lower, upper, digit, [_.!$*=];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!$*_=.
+
charset size: 68, length: 20
+
entropy: Strong 121.75
+
o6=cJQZGEdauDfmXgKL1 (20)
+5Mq1M6UJ!$guCzeKyJw6 (20)
+mrjKcj5HWNuovz0S92jH (20)
+6vI.nYXTpC9PbRS6zR5Q (20)
+pqPfusctFOjcICsO3eh5 (20)
+
+ + +
Rules: minlength: 8; maxlength: 50; required: upper; required: lower; required: digit; required: [!@#$&*];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$&*
+
charset size: 68, length: 20
+
entropy: Strong 121.75
+
$R5SMiZKCxFEuGEE7$GR (20)
+T45!hMNVOtriO7JPGt#6 (20)
+2iPPzANNZul!1t7YI6aN (20)
+e1YNxWvPgHy*Fx9CEEX! (20)
+h0PFdve2ZyXoYu!YJW&X (20)
+
+ + +
Rules: minlength: 8; required: lower; required: upper; required: digit, [!@#$%^];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^
+
charset size: 68, length: 20
+
entropy: Strong 121.75
+
G%hycjuLPmcMnlUan0^y (20)
+MEK@J3htBgeJNjLYzCL3 (20)
+DxFFtYSNWfMreKz8ihqe (20)
+n60uoEVUxIOnfIF@jOJX (20)
+TEQ%wIXtemj16yTYlnNm (20)
+
+ + +
Rules: minlength: 8; maxlength: 25; required: lower; required: upper; required: digit; required: [!@#$%^&];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&
+
charset size: 69, length: 20
+
entropy: Strong 122.17
+
VMyi8ur@qymaxjxpqX1s (20)
+ML2L&VSdAzMGJdJ#rtNl (20)
+uHEaP4kcRdqqtPP$RTwg (20)
+spulEyy$lo7kS!kAlvUy (20)
+zDB93GVIahNW8^bev8JM (20)
+
+ + +
Rules: minlength: 8; maxlength: 25; required: lower; required: upper; required: digit; required: [!@$%^&*];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@$%^&*
+
charset size: 69, length: 20
+
entropy: Strong 122.17
+
Opab@azO%am8vTKDObRO (20)
+8Vv6wY$B@8zfl7ot*FjU (20)
+fVFnJmEa1b1U*^DuRlZu (20)
+8hEqdYJxOlQ8KGNEfF*F (20)
+O@17nn@HcvluGO^5VFCt (20)
+
+ + +
Rules: minlength: 8; maxlength: 21; required: lower, upper; required: digit; required: [!@$%^&*];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@$%^&*
+
charset size: 69, length: 20
+
entropy: Strong 122.17
+
cdUkikkS4OwsvNC5q&Az (20)
+C9psYyKLbF07v3v$m0hI (20)
+rB3yY4OVNrfS^Bvcz0qt (20)
+$KQn0cxtwEJhxFeOODGt (20)
+nfhf5PT%Fh!JivhfAFG$ (20)
+
+ + +
Rules: minlength: 8; maxlength: 30; max-consecutive: 3; required: lower; required: upper; required: digit; required: [#$%^&!@];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&
+
charset size: 69, length: 20
+
entropy: Strong 122.17
+
U&Nr!^rSKCNzSe7UJyVj (20)
+uyr$JLW$CeVhsXa4GkqN (20)
+S1$XnaEJRbxUXjpZqYe3 (20)
+fy5diC7YYq#SEOWAswHO (20)
+fkBa1vgvsIRmt#fT3hb0 (20)
+
+ + +
Rules: allowed: lower, upper, digit, [!#%&*@^];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#%^&*
+
charset size: 69, length: 20
+
entropy: Strong 122.17
+
2MoAbg4hFe!bAhK0QwY* (20)
+LGTHG4T%2^b4rG50qr5! (20)
+UXptxTaadUO7SCF*ay%N (20)
+Rj#R3@rZKXGpzVhGxvSA (20)
+Zw8sR*ujnJ2%#3NCaSU4 (20)
+
+ + +
Rules: minlength: 8; maxlength: 32; required: lower; required: upper; required: digit; required: [!#$%&*@];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%&*
+
charset size: 69, length: 20
+
entropy: Strong 122.17
+
NxdrSuVKu934tPGa1tB! (20)
+Gq!zgPa3E8xnoQ$Z23!1 (20)
+r7M4rQGGI@JKINm1dg2I (20)
+Pl0GmeFnC%UxGZqNQvR8 (20)
+IXmeCwc%DA1m6OVEllba (20)
+
+ + +
Rules: minlength: 8; required: lower; required: upper; required: digit; required: [!#$%&@^];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&
+
charset size: 69, length: 20
+
entropy: Strong 122.17
+
#BEgfUgdOl@4J7NTLqMK (20)
+SfkfW$PZFKgak2hlTK30 (20)
+a3%5unn#o@89JQSQF4a3 (20)
+1bd9Xjbz2!Ijc3S@RTRx (20)
+N0tw$xlZrShBvt!jk3Pz (20)
+
+ + +
Rules: minlength: 8; maxlength: 30; max-consecutive: 3; required: lower, upper; required: digit; allowed: [!#$%./_];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#$%_./
+
charset size: 69, length: 20
+
entropy: Strong 122.17
+
CtGESCRP9RSlw5mMdaN7 (20)
+f!0vpDoF4PJVl_U0!1/f (20)
+dOmERDtEnD1uHLcbwR46 (20)
+n9/ac_DAoArhKNBT##lk (20)
+d6P2WjqJc8lRpWN!_WST (20)
+
+ + +
Rules: minlength: 8; required: lower, upper; required: digit; required: [$!@~_,%&];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~!@$%&_,
+
charset size: 70, length: 20
+
entropy: Strong 122.59
+
h399r0g$yFOewtA&dpD% (20)
+tR7feny$6vqqFUwpj0uN (20)
+Ze$Nk!1hBw0$nveclH!N (20)
+qAekKAR&3hYEljeUqgXz (20)
+C2EyLcNTKp_Kf4LA84%I (20)
+
+ + +
Rules: minlength: 10; required: upper; required: digit; required: [!#$%&*?@]; allowed: lower;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%&*?
+
charset size: 70, length: 20
+
entropy: Strong 122.59
+
cZXG!%vqR#l65STL3Z!t (20)
+HkhwgkmPsth!rQTs83pc (20)
+rHEKeKiW*XAfmhiNl%v2 (20)
+2z1sZy#SkMT0Nxg1bg9b (20)
+dKC#NPBxa6PZGJ5a!mfT (20)
+
+ + +
Rules: minlength: 12; required: lower; required: upper; required: digit; required: [!#$%&*@^];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*
+
charset size: 70, length: 20
+
entropy: Strong 122.59
+
t$2wO4S3WsiDkD6@T3ya (20)
+j%xkd*Hej6hXzEtFf0q4 (20)
+zlZSdTFBWP$OK*D2RgTv (20)
+oB*fOvPI28GnImKS@R&7 (20)
+GCcJFp$FQPb8dzNy5Wal (20)
+
+ + +
Rules: minlength: 8; maxlength: 20; allowed: lower; required: upper, digit, [!#$%&*?@];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%&*?
+
charset size: 70, length: 20
+
entropy: Strong 122.59
+
AoorHg80lt8lVhAuTlHk (20)
+y$r%umcSNl0GLewY1HMh (20)
+AzKjJbZJH4g3TRfcWGwN (20)
+CjnVleMDsGUs@FCxtfhf (20)
+0rpzz1bkibHIQoJIDIDz (20)
+
+ + +
Rules: minlength: 12; required: lower; required: upper; required: digit; required: [!@#$%^&*];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*
+
charset size: 70, length: 20
+
entropy: Strong 122.59
+
@Q!TMoqw5QDHY&RoBO7k (20)
+pQ@QjNeeTh3M1isaRyF3 (20)
+FWm95x^lIfuTpzk1weQx (20)
+BDhQtc5P8lXwFH%rvkgg (20)
+sARU!JDgNtzuLJno@Oo9 (20)
+
+ + +
Rules: minlength: 8; required: lower; required: upper; required: digit; required: [@$!%*#?&];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%&*?
+
charset size: 70, length: 20
+
entropy: Strong 122.59
+
RFSRgM#V!7#$76Nx8bEA (20)
+mMFLxX2b&qcnk0fvK2Dt (20)
+w#metAS$SPcyMr1Shjoh (20)
+UgHfn4WClP9Ka@Wro0bu (20)
+M9g7jEjniB4y#eK&fbbb (20)
+
+ + +
Rules: minlength: 8; maxlength: 20; required: lower; required: upper; required: digit; allowed: [$!#&@?%=];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%&=?
+
charset size: 70, length: 20
+
entropy: Strong 122.59
+
sdCqbC73LPMH#8WSMw82 (20)
+w8M7O0P%OOvrzb@8T2dY (20)
+H?q9ceyDFwKRK#M8Qds8 (20)
+IsS1vZkpkICBnFInbmsp (20)
+cczlC%khs8odU6iBl2tQ (20)
+
+ + +
Rules: minlength: 8; required: lower; required: upper; required: digit; allowed: [ !#$%&*?@];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%&*? 
+
charset size: 71, length: 20
+
entropy: Strong 122.99
+
4UrepymmxGJkJWqbiQoX (20)
+phHncov iojuI6Cpjm9P (20)
+!VIUC9LArwkK2&Xna%Cu (20)
+J@lU7@Njo!EhtP6qjcOa (20)
+A*Whhko! qrdUBDAiV9* (20)
+
+ + +
Rules: minlength: 8; maxlength: 32; max-consecutive: 2; required: lower, upper; required: digit; required: [!#$%+/=@~];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~!@#$%+=/
+
charset size: 71, length: 20
+
entropy: Strong 122.99
+
j1h/W2pYtDvy!1cXHSr% (20)
+rRQyftJ=M7HaI5tJdWr# (20)
+~e~t@sGwnOjpj@0iHXkq (20)
+bpyQaHPpkkok7Cwc6W$3 (20)
+rMaKznxI=A~6#pysT9Yf (20)
+
+ + +
Rules: minlength: 8; maxlength: 24; required: digit; required: upper,lower; allowed: [!#$%()*@^];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^*()
+
charset size: 71, length: 20
+
entropy: Strong 122.99
+
lNB2B8FLMjak$I)Z9@^1 (20)
+HWrL4a3P7HSY6FkiD)2l (20)
+y1g*Yl0bYejAuy$Cs9fO (20)
+$UDQzkbhySxK0@#dmMW@ (20)
+hnl#!zZxzhtUlMfaRG5P (20)
+
+ + +
Rules: minlength: 8; required: lower; required: upper; required: digit; required: [!#$%&*?@^];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*?
+
charset size: 71, length: 20
+
entropy: Strong 122.99
+
yvW4Eul%xRtjL0kVPSbP (20)
+7KXmJiIDEFGBGZw^rNmM (20)
+bMy^nFnt?W@D&5KbgWHj (20)
+lMvl8m$AlDQbxE1FWtfE (20)
+PN5reUFQACo*dPJXzd^o (20)
+
+ + +
Rules: required: lower; required: upper; required: digit; required: [@#$%^&+=_];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@#$%^&_+=
+
charset size: 71, length: 20
+
entropy: Strong 122.99
+
n6$TAmGF5pEyD^^qR7VL (20)
+e0HhcOmWL5AwGud$+ie_ (20)
+TGOBULc1_CheE1s6s@iU (20)
+NcS#s&rx9@QCQu@9^cAA (20)
+_2yaea55CWdtT_%F$hol (20)
+
+ + +
Rules: required: lower; required: upper; required: digit; required: [~!@#$%^&*];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~!@#$%^&*
+
charset size: 71, length: 20
+
entropy: Strong 122.99
+
aoM2pZXIPZQflny~E&4k (20)
+R0BVGausNran4ivhpy!d (20)
+lT%h7TMv&fN&!iyPegmA (20)
+rNs~Km@txRHxKTmuqc*6 (20)
+tUZjU3bvGfT&0vNrZo!K (20)
+
+ + +
Rules: minlength: 6; required: lower; required: upper; required: digit; allowed: [~!@#$%^&*];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~!@#$%^&*
+
charset size: 71, length: 20
+
entropy: Strong 122.99
+
ZnskXOJdD6uF4ke73ExS (20)
+caXE@ZHvVIZK!D8O~Le2 (20)
+eg~4T%b^uko^ktecCsys (20)
+esn5v83vSft2sPZoNQLn (20)
+x&d#FzmP1S#09CLyXhnX (20)
+
+ + +
Rules: minlength: 8; required: lower; required: upper; required: digit; allowed: [?!@$%^+=&];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@$%^&+=?
+
charset size: 71, length: 20
+
entropy: Strong 122.99
+
c7%@50hA9!GAyXp!wcRt (20)
+lGQOF1c2IVsFAIdD0KNB (20)
+FhGKNW^0U5eABYdn?slr (20)
+&?GBaxHVsaesc0JgO4yl (20)
+BPrYm4OoAIJ&Gt6QQIRQ (20)
+
+ + +
Rules: minlength: 8; maxlength: 25; required: lower, upper; required: digit; allowed: [!@#$%^&*()];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()
+
charset size: 72, length: 20
+
entropy: Strong 123.40
+
P5W#v7U0MI9WdsNO@sJo (20)
+M0H0mA$M6ZPOLQGU&c#U (20)
+xF5xbMptKWiiFdT55cjb (20)
+sVFOe3idM6ngBdyJAz7q (20)
+b%EU&2V!mMB0#2r$v@6q (20)
+
+ + +
Rules: minlength: 8; required: lower; required: upper; required: digit; required: [-!#$%_=+<>];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-!#$%_+=<>
+
charset size: 72, length: 20
+
entropy: Strong 123.40
+
yCk9H-q$2-E2X3LDINLa (20)
++tp8>NcMzR6O=NGF1zyw (20)
+Md4poryHc4I7m<r2TYFK (20)
+JaahgH#sb15V1g7yl_ib (20)
++V=zqC6mXG2e8>LBqkbK (20)
+
+ + +
Rules: minlength: 6; maxlength: 20; required: digit; allowed: lower, upper, [@$!#()&^*%];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()
+
charset size: 72, length: 20
+
entropy: Strong 123.40
+
vJJJJ(gxERFPlK&9LHBo (20)
+Un0oK4G^EGs%$@DisIWg (20)
+)OAZd9HD&!et9@E(s(wt (20)
+Bv39q%MpSV8%v#HufCX8 (20)
+#ixeJJtNkM0BKm^4Vevx (20)
+
+ + +
Rules: minlength: 8; maxlength: 30; required: lower, upper; required: digit; allowed: [-!$*.=?@_'];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-!@$*_='.?
+
charset size: 72, length: 20
+
entropy: Strong 123.40
+
tDsndj*fw-N6uxbpr4AH (20)
+UC36DHiyZ'hyZ3?r2-uB (20)
+9ad*tnK83gaKbALqb$am (20)
+E12_.sz?VUveErSjfk_4 (20)
+AG*W6sN2a5J4l6*20==@ (20)
+
+ + +
Rules: minlength: 6; maxlength: 128; allowed: lower, upper, digit, [!@#$%^&*()];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()
+
charset size: 72, length: 20
+
entropy: Strong 123.40
+
BRiMO%S!S6RFlsHpj5w4 (20)
+g8vY4)vq8^LVe%vpgj(C (20)
+Ui0cWRA)9pnkT)npqxYv (20)
+&Zx9XHdImf^5i6yCgWs@ (20)
+WMzztcMwpPk01$N^o0e4 (20)
+
+ + +
Rules: minlength: 8; maxlength: 20; max-consecutive: 3; required: lower, upper; required: digit, [!@#$%^&*()];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()
+
charset size: 72, length: 20
+
entropy: Strong 123.40
+
Dzp*K10JVcviuCJF^dkv (20)
+!IUqlNflG(JsO6OxLU6b (20)
+E(vx5V49@*@x7fRFJw9# (20)
+H^cnQyGp^VRqBe$c*MH$ (20)
+MeSHXfTEm8^ytb1OR1uj (20)
+
+ + +
Rules: minlength: 8; required: lower; required: upper; required: digit; required: [!#$%&()*@^];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()
+
charset size: 72, length: 20
+
entropy: Strong 123.40
+
&)uWm&z09tntwU9TZqHN (20)
+LO@ieKsOnYbBxaBWad76 (20)
+VyiN*R0cOFrZrHR)p6tB (20)
+FbM$zjL4i0kGCWtONBcR (20)
+eJ4o!5K!ozDlEAjYZPEr (20)
+
+ + +
Rules: minlength: 8; maxlength: 32; required: lower, upper; required: digit; allowed: [-_./\@$*&!#];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-!@#$&*_\./
+
charset size: 73, length: 20
+
entropy: Strong 123.80
+
c4yjaMclHt2yNYP2kOdW (20)
+5#xCEHwZtJls@SmA3egg (20)
+QkVyOVq92g8W7E*OkHYH (20)
+ae8cyB0KawEtzVpcOSQ& (20)
+3rBim&\Jq\/xz#ZBjVlF (20)
+
+ + +
Rules: minlength: 8; maxlength: 30; required: lower, upper; required: digit; allowed: [-!@#^&*=+;:];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-!@#^&*+=:;
+
charset size: 73, length: 20
+
entropy: Strong 123.80
+
llTs0T&HQBpDvK#6QsRo (20)
+N7ow!InMj;aM3CFH4NBI (20)
+f0:pDopld+NjrepWrfre (20)
+inq@j7f9TIh5IEgFBmlT (20)
+IR5*DKPb^*goIr-Uediz (20)
+
+ + +
Rules: minlength: 8; required: lower; required: upper; required: digit; required: [!@#$%^&*<>?];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*<>?
+
charset size: 73, length: 20
+
entropy: Strong 123.80
+
c%#9>8TPCW@Jo!mLEsvS (20)
+nl2T&8IVcy5sBb293rQy (20)
+J?2L&dtIzF!>0Ht4V^A# (20)
+m&Wzf8^lCi3vDNSrTrcg (20)
+u*n?HhynRFGg1*wJ$DdE (20)
+
+ + +
Rules: minlength: 8; maxlength: 20; required: lower; required: upper; required: digit; required: [!#$%&*?@^_~];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~!@#$%^&*_?
+
charset size: 73, length: 20
+
entropy: Strong 123.80
+
IhR2OAQR~s_^6G2TqHnq (20)
+nBZjSEFI@o&34dW$AkB3 (20)
+?XXyJ%mMiceacm*2xd#9 (20)
+FZtkTyTx_f1wayEt0N54 (20)
+n1VVAuhW3_dYR1f0HYcY (20)
+
+ + +
Rules: minlength: 8; maxlength: 64; required: lower, upper; required: digit; allowed: [-!@#^&*=+;:];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-!@#^&*+=:;
+
charset size: 73, length: 20
+
entropy: Strong 123.80
+
T=ABsSxkR0&gt0&AbrKZ (20)
+i&e*JA9fJeFWYbc4nYDM (20)
+@Fy6WOojusf33wAbZTeE (20)
+ZvK7anc7^lQ=bYPgnf;I (20)
+ywykdrHpye9tbof&D4hv (20)
+
+ + +
Rules: minlength: 12; maxlength: 30; required: lower; required: upper; required: digit; required: [!@#$%^&*()+];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*+()
+
charset size: 73, length: 20
+
entropy: Strong 123.80
+
$*#hVaaKrpR%qha6!xS3 (20)
+X3Xff+O0@HuClQQ&^+KU (20)
+&7BK%ppzkhqrizsl2O2Z (20)
+J7Ly*1eTcDG*kqBHrd1B (20)
+zxc!f3p6WBwdfmzvbWWs (20)
+
+ + +
Rules: minlength: 8; required: digit; required: upper,lower; required: [!#$%&*+=?@^];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*+=?
+
charset size: 73, length: 20
+
entropy: Strong 123.80
+
Py+A4CHArjvWPxX19*zM (20)
+aH1KU8nHo9I%pGK@VjXe (20)
+N*4Fea7VbirJcDZCmGff (20)
+a$KzCT1Qsuj&j^b$zEqt (20)
+sFDS!=@2x&%Eo8Fy+HXq (20)
+
+ + +
Rules: minlength: 8; required: lower; required: upper; required: digit; required: [!#$%&()*+@^_];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*_+()
+
charset size: 74, length: 20
+
entropy: Strong 124.19
+
KDno4YJ#Sz0ubG^1eXbj (20)
+ulbJuiH_sz3LYph^*imx (20)
+Gpbkyi*FGO#f6L%FtkUA (20)
+O622+4BUlZtts+BW4B9m (20)
+g!nUqSvp(7hy%eszqkCv (20)
+
+ + +
Rules: minlength: 8; required: lower; allowed: upper, digit, [-!@#$%&*_+=<>];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-!@#$%&*_+=<>
+
charset size: 75, length: 20
+
entropy: Strong 124.58
+
4-<qJe4O5oA6Tsgb%0Ug (20)
+qYzCU4#&wIy8rAyOPh_V (20)
+$J1wF-2fEg8BCCOd$@K0 (20)
+YMd*w>yJ2O>gCnAZ2*Wf (20)
+adJgFDkgw+uqSiY6JQPM (20)
+
+ + +
Rules: minlength: 8; maxlength: 64; required: lower; required: upper; required: digit; required: [-!@#$%&*_+=<>];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-!@#$%&*_+=<>
+
charset size: 75, length: 20
+
entropy: Strong 124.58
+
_Gjtzmr->Ov488&7X>2! (20)
+bpYJZx%jKAZtz&hgo%@2 (20)
+zbr=eENhDg_Kk*3i$vBk (20)
+Hi3>D7tUC+kdgs@lI4SM (20)
+uxzhAp<-5MQLro5zTRBu (20)
+
+ + +
Rules: minlength: 8; maxlength: 50; max-consecutive: 2; required: lower; required: upper; required: digit; allowed: [-!"#&'()+,./?@];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-!@#&+()"',.?/
+
charset size: 76, length: 20
+
entropy: Strong 124.96
+
geZr@XQlxXMud"Wg#&s6 (20)
+PGH+BDt5agLL.iyGcsqK (20)
+Px+'ezWeXV/ljfpnFa,0 (20)
+ywGstFYU(3LpJ7L8!838 (20)
+xPje4&eMz.c3Fb.bn3hi (20)
+
+ + +
Rules: minlength: 8; maxlength: 38; required: lower, upper; required: digit; allowed: [-äüöÄÜÖß!$%&/()=?+#,.:];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-!#$%&+=():,.?/
+
charset size: 77, length: 20
+
entropy: Strong 125.34
+
e,ZDuFqgUKq9Uu%+oOt- (20)
+NkH5rK#?H(D+PvNHQ/8? (20)
+0xKz$ICedo/h#MpPY5wE (20)
+Vl,nCvOSfjbx+s5JsLMr (20)
+C1Q(xo!5j6MWkgts.y+w (20)
+
+ + +
Rules: minlength: 6; maxlength: 20; required: lower; required: upper; required: digit; allowed: [!#$%&()*+/=?^_{}];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#$%^&*_+=(){}?/
+
charset size: 78, length: 20
+
entropy: Strong 125.71
+
l6e)8lu(M(KSuZtkX+J( (20)
+$29$?W^m(eevIv9sg12e (20)
+)JNIby52_LCxSv3NjcU# (20)
+0hqf/7YFKi97435{44se (20)
+cfYKU&)FlkRbAs8pNHIV (20)
+
+ + +
Rules: minlength: 8; required: lower; required: upper; required: digit,[!"#$%&'()*+,<>?@];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%&*+()"'<>,?
+
charset size: 78, length: 20
+
entropy: Strong 125.71
+
$qfnJVjGvHtyDAfS%15T (20)
+1SkE33a1,?7&kSjE>cpa (20)
+Kw%8pL+Ypul*e8R#<bY3 (20)
+aX08USr%09PEmTf>J@p3 (20)
+qPmq9Yj0A(??j>xjJ1Z+ (20)
+
+ + +
Rules: minlength: 8; maxlength: 30; required: upper, lower; required: digit, [!#$%&()*+<>?@^_~];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~!@#$%^&*_+()<>?
+
charset size: 78, length: 20
+
entropy: Strong 125.71
+
en9@)I_odFn)ZHiiGu%d (20)
+%vZ>Shr53Ur~u%WAy1>c (20)
+>RyOxaJoNu?QACfjne7$ (20)
+hzfV&DTqHe(Rca>m~o<n (20)
+j>zbTKTsPlpsg5w0dg?@ (20)
+
+ + +
Rules: minlength: 8; maxlength: 20; max-consecutive: 3; required: lower; required: upper; required: digit; allowed: [-@#*()+={}/?~;,._];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~@#*_+=(){};,.?/
+
charset size: 79, length: 20
+
entropy: Strong 126.08
+
2)xX;+hJBf+vZXXzcE,b (20)
+Vjjazqx*DPaWg1.x);UV (20)
+66;Dbn*?et5BmimW)._J (20)
+8ylm0XBx*gsH{Af}/#VE (20)
+=_k1+o+ayfa-768PT0IG (20)
+
+ + +
Rules: minlength: 10; maxlength: 30; required: digit; allowed: lower, upper, [!@#$%*()_+^}{:;?.];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^*_+(){}:;.?
+
charset size: 79, length: 20
+
entropy: Strong 126.08
+
{C)ld10rwyLUcwas7r.C (20)
+zGifSSVhS9CdPbj92P7C (20)
+i)}cEQ9ar^!Iff5WyCba (20)
+cXbb!@$Vbd_iCX59;8T! (20)
+TI8YNfjVNftDDZYvXPeD (20)
+
+ + +
Rules: minlength: 8; maxlength: 65; required: lower; required: upper; required: digit; allowed: [-!"§$%&/()=?;:_+*'#];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-!#$%&*_+=():;"'?/
+
charset size: 80, length: 20
+
entropy: Strong 126.44
+
nA6Cbo:qXy%hOUmT1:$4 (20)
+ET4*T6Di1GFB3nAaq0%% (20)
+n_=kapXLsfh;S(4L?#sU (20)
+b58BJPY'+xamr-(80S*k (20)
+Mj*'gdr=QdMnyc3:Hyao (20)
+
+ + +
Rules: minlength: 6; maxlength: 20; required: lower; allowed: upper,digit,[!$%'()+,./:;=?@^_|~];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~!@$%^_+=|():;',.?/
+
charset size: 81, length: 20
+
entropy: Strong 126.80
+
M+Tpyjmw5IgZjVc9+Ai^ (20)
+,E/0_PdcBY|/vby1hJJC (20)
+|T'9$B4yhppl^zuh@G$_ (20)
+jBGe;(PgL%YB1Ne6Id!8 (20)
+4ZHD~)hSSl!y'uc8SU_u (20)
+
+ + +
Rules: minlength: 8; required: lower; required: upper; required: digit; required: [!#$%&'()+,.:?@[_`~]];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~!@#$%&_+`()[:',.?]
+
charset size: 81, length: 20
+
entropy: Strong 126.80
+
dyjd0udQ04[&M#fsW85` (20)
+)w:fw6!J2nY+vp%5+m'# (20)
+JkZ.ef?%k$&zM9Cho[Vx (20)
+,rn9YfIen(y'rwUvuj3m (20)
+v4OOOaCzM'#HKayw#8Sr (20)
+
+ + +
Rules: minlength: 8; required: lower; required: upper; required: digit; required: [!#$%&()*+,./:;<>?@"_];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%&*_+():;"<>,.?/
+
charset size: 82, length: 20
+
entropy: Very Strong 127.15
+
i(3Pv5I#L!7ia?.2aG>, (20)
+<T_H8wHI@_n*Enpm6nH# (20)
+9O,D(ck?DD>j&h9,c.bx (20)
+.tQhjte8gve82&hA!wj! (20)
+r.HA$XwgV#Klk9yMF$!h (20)
+
+ + +
Rules: minlength: 8; maxlength: 32; required: lower; required: upper; required: digit; required: [!#$%&()*+,./:;<>?@"_];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%&*_+():;"<>,.?/
+
charset size: 82, length: 20
+
entropy: Very Strong 127.15
+
maF3k3Byu,8wziN7@z9P (20)
+/RQpJTr$iG)N572.6SMW (20)
++(C:zyxru"g9XX0c"MVs (20)
+xsb%FFb;6?:#>mkbU3XW (20)
+o!<ut36kK::)WO6+4VVh (20)
+
+ + +
Rules: minlength: 8; required: lower; required: upper; required: digit; required: [!"#$%&()*,.:<>?@^{|}];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*|(){}:"<>,.?
+
charset size: 82, length: 20
+
entropy: Very Strong 127.15
+
Lmi.TQNj,@TrvXWR:L1Q (20)
+6E&NotdMJVOlfA$nO16w (20)
+7,0sYsx&L&ATV*?tUlE< (20)
+BlMebAtBMt{}1ukoCDTV (20)
+tuQV6cM6j?H.:0zJtKE9 (20)
+
+ + +
Rules: minlength: 9; maxlength: 64; required: lower; required: upper; required: digit; required: [!"#$%&()*,.:<>?@^_{|}];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*_|(){}:"<>,.?
+
charset size: 83, length: 20
+
entropy: Very Strong 127.50
+
1F}6QS1y@({w%EiHc?H> (20)
+$#h>201(vP6kOInr%eHr (20)
+,JSkK.O:u5ZQfB$4?BvH (20)
+d9@gt5es<Z03LGYOLBQ2 (20)
+Ae,yANA>|mvmaRAMv21R (20)
+
+ + +
Rules: minlength: 6; required: lower; required: upper; required: digit; required: [`!@#$%^&*()+~{}'";:<>?]];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~!@#$%^&*+`(){}:;"'<>?]
+
charset size: 85, length: 20
+
entropy: Very Strong 128.19
+
M6rHv5N@q4}$Z7s*8>}0 (20)
+Y>(G#h3wkh;Kk(?d!i`4 (20)
+#3DMRUz)pRjsZ(d'Cucp (20)
+J8R}CRisjX^qOocX90i+ (20)
+cEdIDf*"p4P5G{gN`81U (20)
+
+ + +
Rules: minlength: 8; required: lower; required: upper; required: digit; allowed: [-!$"%&/()=*+#.,;:@?{}[]];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-!@#$%&*+=(){}[:;",.?/]
+
charset size: 85, length: 20
+
entropy: Very Strong 128.19
+
#S,7vG=1}SQ6$ClG,G2! (20)
+Rv5Em*i"g,O:C,Y8}N=, (20)
+*+]QgNZ1?Ae[(aa{Ij6; (20)
+lckBpq.n7n/;,SBH*Z7V (20)
+fF6U,f1Ge[o#ZzvbxJ7Q (20)
+
+ + +
Rules: minlength: 8; maxlength: 32; required: lower; required: upper; required: digit; required: [-!@#$%^*~:;&><[{}|_+=?]];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=|{}[:;<>?]
+
charset size: 85, length: 20
+
entropy: Very Strong 128.19
+
[%udHxtI2]dZ@Ag3??lA (20)
+-ta#v3<PkL#=<;_FPtt@ (20)
+9=Ekokpj|VpPDnEesJU# (20)
+O*fNE+}XaV=7d[-EaG>] (20)
+6p!eOc[Rmj[aJ{y;&G#b (20)
+
+ + +
Rules: minlength: 8; max-consecutive: 3; required: lower; required: upper; required: digit; allowed: [-!@#$%^&*_+=`|(){}[:;,.?]];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-!@#$%^&*_+=`|(){}[:;,.?]
+
charset size: 87, length: 20
+
entropy: Very Strong 128.86
+
4d[U-??Z3LW!%iA_*tTu (20)
+h{{PiXS^Oh$1L4`3i-x$ (20)
+g|.wBx[xSWmoHY|e6X:: (20)
+Qz-NJz%vQi$|+4QX_iyU (20)
+YlL=Z}=_It8X48rQqu;G (20)
+
+ + +
Rules: minlength: 8; maxlength: 20; required: lower, upper; allowed: digit, [-!#$%&'()*+/:;=?@[^_`{|}~]];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;'?/]
+
charset size: 88, length: 20
+
entropy: Very Strong 129.19
+
ak_5NFF3y^l+pMwKa3'd (20)
+Kbi|ruboHaq(z}IN{#57 (20)
+e5Y6OMGW9Atx3OT}`Wh6 (20)
+4:mi/@^wd@pTfFG[!Vsb (20)
+[NLAWTN4)SO^XbV4y4Rg (20)
+
+ + +
Rules: minlength: 8; maxlength: 50; max-consecutive: 2; required: lower; required: upper; required: digit, [-~!@#$%^&*_+=`|(){}[:;,.?]];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;,.?]
+
charset size: 88, length: 20
+
entropy: Very Strong 129.19
+
2(VhjqHnD%%PfQV67$C1 (20)
+K84H)RFXnc:=wA6y5zkq (20)
+ex-RJ($0$+b^)P7$5P1n (20)
+f6dhWYA`K$0?{ur._+u} (20)
+]2!B[9V0*rvfH$$P3%-C (20)
+
+ + +
Rules: minlength: 8; required: lower; required: upper; required: digit, [-~!#$%&_+=|(){}[:;"’<>,.? ]];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!#$%&_+=|(){}[:;"<>,.? ]
+
charset size: 88, length: 20
+
entropy: Very Strong 129.19
+
}Wu+}Wto|iIE>z]sP|Sw (20)
+4kvO!Lw"c1+dYrO G~e- (20)
+flKH"&YJ(_oORx15($_L (20)
+<xC~f]oJ2D }#0ykm_<i (20)
+eQtb)HSQ(8V_0v3CMde  (20)
+
+ + +
Rules: minlength: 15; required: lower; required: lower; required: upper; required: upper; required: digit; required: digit; required: [-!@#$%^&*()_+|~=`{}[:";'?,./.]]; required: [-!@#$%^&*()_+|~=`{}[:";'?,./.]];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;"',.?/]
+
charset size: 91, length: 20
+
entropy: Very Strong 130.16
+
XJ.$_ET+4AsZ{_c^2"&E (20)
+Kd3)U~1pOxmR=DjB`w(K (20)
+-Ok)-@N|c8W?$6^WZhu5 (20)
+WnH1cAHgF$5]}eBuJjqD (20)
+r8$acj&DWL5iqAFtffSX (20)
+
+ + +
Rules: minlength: 8; required: lower; required: upper; required: digit; required: [!#$%&'()*+,./:;<>?@\^_`{|}~[]];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~!@#$%^&*_+`|(){}[:;\'<>,.?/]
+
charset size: 91, length: 20
+
entropy: Very Strong 130.16
+
fnI!2OxhB7w<7#Hc!O3e (20)
+xzXgI^1Uuj4d[xVxp*t) (20)
+L}t6M>*O2m]GkwT,q4MC (20)
+~UCn_rsA5lJQ%#Pv`i(] (20)
+~/;fGq,pm3s#jraoNXv+ (20)
+
+ + +
Rules: minlength: 8; maxlength: 20; required: lower, upper; required: digit, [-!"#$%&'()*+,./:;=?@[\^_`{|}~];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\"',.?/
+
charset size: 91, length: 20
+
entropy: Very Strong 130.16
+
xQ$NbhMDQNL@~6sEfO89 (20)
+?c\-Z8WDHGN?6Yc_je9A (20)
+dUlt13~iO#Pl^(weF*u: (20)
+p7:s.s%SP_TWiCLXc`am (20)
+@svsmqqxu^!Z5ipmCH?h (20)
+
+ + +
Rules: minlength: 8; required: digit; required: [- !"#$&'()*+,.:;<=>?@[^_`{|}~]]; allowed: lower, upper;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$^&*_+=`|(){}[:;"'<>,.? ]
+
charset size: 92, length: 20
+
entropy: Very Strong 130.47
+
H8$#$HqRANXu+TWD f.F (20)
+ :oWBGf~CJ_@5-SD$lI: (20)
+{g4uLI0i@F!E7PzmVbIR (20)
+}kXM0t&=8]a"HnxFj Of (20)
+f0)J^u96*SLy#9dIZSC8 (20)
+
+ + +
Rules: minlength: 8; required: lower; required: upper; required: digit; required: [!"#$%&'()*+,./:;<=>?@[^_`{|}~]];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~!@#$%^&*_+=`|(){}[:;"'<>,.?/]
+
charset size: 92, length: 20
+
entropy: Very Strong 130.47
+
'C$+o#.j,r#W|0<Fot?A (20)
+_WuCGq[5Jg33/4JK(o%U (20)
+qXaylswJ6SFF,_t2yw2t (20)
+9LbIYg3Y[NnLEAf*KT5P (20)
+D1Ijxl|,^?ZoX$Tp!>ci (20)
+
+ + +
Rules: minlength: 8; maxlength: 40; allowed: lower, upper, digit, [-<=>~!|()@#{}$%,.?^'&*_+`:;"[]];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;"'<>,.?]
+
charset size: 92, length: 20
+
entropy: Very Strong 130.47
+
3eg&"XE>ZC_!b9Rau=td (20)
+}_@e3+e+?7JfHZ98-*S0 (20)
+"p%~tt#7#fLaW?N`$!9S (20)
+B;v?>VaNQQ"vnFI>Ih91 (20)
+b{~m`cqMrsWa^52`FZQe (20)
+
+ + +
Rules: minlength: 8; allowed: lower, upper, digit, [-!"#$%&'()*+,./:;<=>?@[^_{|}~]];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=|(){}[:;"'<>,.?/]
+
charset size: 92, length: 20
+
entropy: Very Strong 130.47
+
BY%pftf4)<#pKw7Mtgc' (20)
+@C0:YSLkvlG4mxAsS[_# (20)
+zuckIFsQ@Mj/SB5lu|b_ (20)
+IAfgazCZ61*chqX8X1Kd (20)
+5U(oI9cx2^^p?$_KB2SD (20)
+
+ + +
Rules: minlength: 6; maxlength: 30; allowed: lower, upper, digit, [-~!@#$%^&*_+=`|(){}[:;"'<>,.?]];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;"'<>,.?]
+
charset size: 92, length: 20
+
entropy: Very Strong 130.47
+
tTgK*xTt!EY@$[4fgvtW (20)
+.6fY5w~@@pbV;]I"~Pn; (20)
+qBF4M?e!KQl3D|8zp(cQ (20)
+WO=Y1^KT`mSU#u7Xj1#z (20)
+45yTx@jA2Tv-}SD[ph+j (20)
+
+ + +
Rules: minlength: 6; maxlength: 32; allowed: upper, lower, digit,[-!"#$%&'()*+,.:;<=>?@[^_`{|}~]];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;"'<>,.?]
+
charset size: 92, length: 20
+
entropy: Very Strong 130.47
+
ycD"=)&&VaG[e==h76nB (20)
+LoWW'G=!B=ZFI^?V02Kg (20)
+&IiU8~p,1?aVb*i!~Ejm (20)
+1SiH5egqVB-tz87dJ@H{ (20)
+yva%!|&iH4Bh1M.H;MrO (20)
+
+ + +
Rules: minlength: 10; maxlength: 100; required: lower; required: upper; required: digit; allowed: [-@_#!&$`%*+()./,;~:{}|?>=<^[']];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;'<>,.?/]
+
charset size: 92, length: 20
+
entropy: Very Strong 130.47
+
5]'NqqnP&k&2Y+><O7mj (20)
+:gn4Q%tD<El;Mg4Q24!s (20)
+6(XDuk=+#Qv}ah'6&U!{ (20)
+-Rk#P4VM(kyK#5}sF4ml (20)
+gx=7,<#1|8ljj7KhwVuG (20)
+
+ + +
Rules: minlength: 8; required: lower; required: upper; required: digit; allowed: [-@_#!&$`%*+()./,;~:{}|?>=<^'[]];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;'<>,.?/]
+
charset size: 92, length: 20
+
entropy: Very Strong 130.47
+
pm~R>m5wS{0ZVSsGbOt3 (20)
+OX|7O^FMt_zkL@M]<QR; (20)
+Bc4oZ)PkPwPWnketGG^a (20)
+{dNa&U*J^T#`-|2Yke;x (20)
+-d:wB[}sQMyKOL{OJ8ym (20)
+
+ + +
Rules: minlength: 9; maxlength: 20; required: lower; required: upper; required: digit; allowed: [-@_#!&$`%*+()./,;~:{}|?>=<^'[]];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;'<>,.?/]
+
charset size: 92, length: 20
+
entropy: Very Strong 130.47
+
#x6e01%$T0o;qor@>,fB (20)
+mF&(IH4lxI@YWYe?OMsy (20)
+u95cHMRE-H0#QH>$+I%U (20)
+TL&Z:w=0m9~U/Uk<fw<] (20)
+-XT)&*ia@,L6cbKY+KZK (20)
+
+ + +
Rules: allowed: lower, upper, digit, [-(~!@#$%^&*_+=`|(){}[:;"'<>,.?]];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;"'<>,.?]
+
charset size: 92, length: 20
+
entropy: Very Strong 130.47
+
TaZz?|~~|1HYyc`QF!y! (20)
+hm*5xQ&de'18'@rHz+!6 (20)
+?.&z;NbDttHL_hm{6Z`I (20)
+=db&Gt5eZ6E-<|Vg9-YV (20)
+JYqCFn{XRXoc%`dW"7)# (20)
+
+ + +
Rules: minlength: 8; maxlength: 40; allowed: lower, upper, digit, [-<=>~!|()@#{}$%,.?^'&*_+`:;"[]];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;"'<>,.?]
+
charset size: 92, length: 20
+
entropy: Very Strong 130.47
+
u'nfZoPsdNc;6le<9+ro (20)
+tKDm[N0>wHYhVQ0*M}Sl (20)
+1gO.xH4caoz:Sc9%[X9) (20)
+P26[GU*WD5LaC2f|z.![ (20)
+<&u4x#)e)|-+tQ9nS!n? (20)
+
+ + +
Rules: minlength: 8; required: lower; required: upper; required: digit; required: [-!"#$%&'()*+,./:;<=>?@[^_`{|}~]];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;"'<>,.?/]
+
charset size: 93, length: 20
+
entropy: Very Strong 130.78
+
1c~vNcNX/ewPACYBa1k7 (20)
+t]BK1Szc#Ej9.6[lyRWt (20)
+2j;^?MUd%grGv$9w^#~Z (20)
+x~zHy/_$Nj8U!2XprrWn (20)
+xAk2@$?W.5zoV9@!HQTH (20)
+
+ + +
Rules: minlength: 7; required: lower; required: upper; required: digit; required: [-!"#$%&'()*+,./:;<=>?@[^_`{|}~]];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;"'<>,.?/]
+
charset size: 93, length: 20
+
entropy: Very Strong 130.78
+
|D&mbsTlz$F6drmEyreT (20)
+KlSUS)e1-Z!rau:j5cd} (20)
+OUyB~LY@+8D*impx7CB) (20)
+]~LZl%?c4Zb^h^Bhyq~T (20)
+pj@6zxum)7Tov.b`JV]D (20)
+
+ + +
Rules: minlength: 10; required: lower; required: upper; required: digit; required: special;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\"'<>,.?/ ]
+
charset size: 95, length: 20
+
entropy: Very Strong 131.40
+
T}[t\l@A5sOJyoJPI34w (20)
+\$HJ-%wTD'gnbwo?6g'n (20)
+dm+2emf18`hR8`<2ICXk (20)
+ZV3:YNAHJugyb@k2ejd? (20)
+B-0uaD:|c!0YEiAJMtjQ (20)
+
+ + +
Rules: minlength: 8; maxlength: 63; required: lower; required: upper; required: digit; allowed: ascii-printable;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\"'<>,.?/ ]
+
charset size: 95, length: 20
+
entropy: Very Strong 131.40
+
{R&<V2sCy0-/\N%8+CsC (20)
+nUxF_cI`a+0EcJe!oXUp (20)
+LKBjZW0~xD2~0,--_S>a (20)
+{`b69ha^yf&o)6c)PG?{ (20)
+blXWy} ]f!dsh90a7Fnk (20)
+
+ + +
Rules: required: upper; required: upper; required: digit; required: digit; required: special; required: special; allowed: lower;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\"'<>,.?/ ]
+
charset size: 95, length: 20
+
entropy: Very Strong 131.40
+
T"LM1j<`[!QF/7`&EWMW (20)
+a3CVwJ2O4a7T7$CZIw6  (20)
+V1DJwG4UW39~]0L,gMsr (20)
+&ArOt4t/N'-`ZaqiFx0L (20)
+esIBC0)%zQG0Ko*02;7x (20)
+
+ + +
Rules: minlength: 20; required: lower; required: upper; required: digit; required: special;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\"'<>,.?/ ]
+
charset size: 95, length: 20
+
entropy: Very Strong 131.40
+
9QXl^wT2eiKJFV 0`[[a (20)
+J]Y;p.CPS~jp1yopZyM6 (20)
+.erlZ08r^&r2o9*k(+J7 (20)
+Xr*UUlcX4%1rM#;AyMB@ (20)
+l<fybldiOJ~I%9.9|L=+ (20)
+
+ + +
Rules: minlength: 8; required: upper; required: special; allowed: lower, digit;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\"'<>,.?/ ]
+
charset size: 95, length: 20
+
entropy: Very Strong 131.40
+
fV| %h:ZL%\[%of s/kV (20)
+w`EqLNsi*GE,$V+.6f)b (20)
+%%pfva^J|4&4deLzbZcZ (20)
+,hiZ5U[YJOFBPX^Mq7Cs (20)
+%(nL^lkI5h!5`!VmK~n_ (20)
+
+ + +
Rules: minlength: 8; required: lower; required: upper; required: digit, special;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\"'<>,.?/ ]
+
charset size: 95, length: 20
+
entropy: Very Strong 131.40
+
Qo@}1:^($VH)w!:+UyD# (20)
+EB~z1j3*0\#C'L9lmjpt (20)
+F3y_F]6Q!|^D=P<cV*Hj (20)
+UTD(dIF7P9Fdv,9}4jmO (20)
+3b[Hm(91 IK&5NJ''p#3 (20)
+
+ + +
Rules: minlength: 8; required: lower; required: upper; required: digit; required: special;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\"'<>,.?/ ]
+
charset size: 95, length: 20
+
entropy: Very Strong 131.40
+
PC$LVGS0Z${/d2]/Ijkp (20)
+?(a&t~.)rFrjjPoCzZ!0 (20)
+h9ql=,D\|H[U,0zqZQ(b (20)
+p23-e'2vx&Mr-[%O9yui (20)
+$-^lO+YSu~N#swJM4BZu (20)
+
+ + +
Rules: minlength: 8; required: lower, upper; required: digit; allowed: ascii-printable;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\"'<>,.?/ ]
+
charset size: 95, length: 20
+
entropy: Very Strong 131.40
+
@&X"zY:0;O7W-yH.@_:U (20)
+spL+,'#E%cn5%a#mL6KE (20)
+J%qF?uX*eW m*Rn-2E$s (20)
+5w\H~63Re/CVaR7/;U(e (20)
+"_wR ^)@UYu7erN/dg[N (20)
+
+ + +
Rules: minlength: 8; maxlength: 20; required: lower; required: upper; required: digit; required: special; allowed: [!#$%&()*+:;=@[^_`{}~]];
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\"'<>,.?/ ]
+
charset size: 95, length: 20
+
entropy: Very Strong 131.40
+
JKn5qxj?\y[!vqwB!1O~ (20)
+2XIDmJhqG;"vQ4lPq-xq (20)
+UoCrZTMmL|G"e[3`+#U~ (20)
+7/0vQAVr?mAXkI 6.>as (20)
+5SDi/z`5I m8\%iH1SSR (20)
+
+ + +
Rules: minlength: 4; maxlength: 60; required: lower, upper, digit; allowed: special;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\"'<>,.?/ ]
+
charset size: 95, length: 20
+
entropy: Very Strong 131.40
+
$=pC6c{[WBi:7aL0rPY1 (20)
+Q#qa$MX|&mX\NyAQvefe (20)
+oGR{V#P8(E4rDM*0rYBj (20)
+~XM,/w>JGe$x@q~2|2j} (20)
+HYAHT5JsGpR]Wn''`;KY (20)
+
+ + +
Rules: minlength: 8; required: lower; required: upper; required: digit; required: special;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\"'<>,.?/ ]
+
charset size: 95, length: 20
+
entropy: Very Strong 131.40
+
$=w[Z';uj+ifuDEP.{6[ (20)
+B9^KKfe"Zb:^,sGtC-]! (20)
+FjN!x>YmZP=8FFZ$Qizc (20)
+SH1B~|Dsle_qd~y\1%U& (20)
+p372 3wpN6361Y 1$R3( (20)
+
+ + +
Rules: minlength: 5; maxlength: 20; required: lower; required: upper; required: digit; allowed: ascii-printable;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\"'<>,.?/ ]
+
charset size: 95, length: 20
+
entropy: Very Strong 131.40
+
)}i.&uCrynbJVM+nTFK8 (20)
+#:N6Gy*e=0Mnmr9@d:s_ (20)
+J+A{HHE~")[X3)0lWLM9 (20)
+g5b0pgq&g,WhJ*m@5.W! (20)
+2pt|U?]iG` laYc;mng5 (20)
+
+ + +
Rules: minlength: 8; maxlength: 20; required: lower, upper; required: digit; allowed: unicode;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\"'<>,.?/ ]
+
charset size: 95, length: 20
+
entropy: Very Strong 131.40
+
)J7F$8&YWJSo"80Qee-c (20)
+"QF76XM<36=~wnjKCZP$ (20)
+pX%oq[^0M2Zs $^Fd:4# (20)
+GJwf#sR{v,!0=rcg[n?i (20)
+!u_q)CElyys0=- aIT_> (20)
+
+ + +
Rules: minlength: 8; required: upper; required: digit; allowed: lower, special;
+
charset: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\"'<>,.?/ ]
+
charset size: 95, length: 20
+
entropy: Very Strong 131.40
+
b& R1m^OPFr.ub=:R1if (20)
+zf0}mX@2R`O`/iy5$!=m (20)
+}dD:aaf&JW7/td *FSX0 (20)
++dsy;6usR/d4<yZY=FC4 (20)
+1a%[)m<t<yJ-p:4!uP;e (20)
+
+
+ + + diff --git a/packages/password/html-testing/login.html b/packages/password/html-testing/login.html new file mode 100644 index 000000000..59126a464 --- /dev/null +++ b/packages/password/html-testing/login.html @@ -0,0 +1,23 @@ + + + + + + + Login + + +

Login

+

Signup

+
+ + + +
+ + diff --git a/packages/password/index.js b/packages/password/index.js new file mode 100644 index 000000000..68812390e --- /dev/null +++ b/packages/password/index.js @@ -0,0 +1,115 @@ +const {Password} = require('./lib/apple.password') +const {ParserError} = require('./lib/rules-parser') +const {constants} = require('./lib/constants') + +/** + * @typedef {{ + * domain?: string | null | undefined; + * input?: string | null | undefined; + * rules?: RulesFormat | null | undefined; + * onError?: ((error: unknown) => void) | null | undefined; + * }} GenerateOptions + */ + +/** + * Generate a random password based on the following attempts + * + * 1) using `options.input` if provided -> falling back to default ruleset + * 2) using `options.domain` if provided -> falling back to default ruleset + * 3) using default ruleset + * + * Note: This API is designed to never throw - if you want to observe errors + * during development, you can provide an `onError` callback + * + * @param {GenerateOptions} [options] + */ +function generate (options = {}) { + try { + if (typeof options?.input === 'string') { + return Password.generateOrThrow(options.input) + } + if (typeof options?.domain === 'string') { + if (options?.rules) { + const rules = _selectPasswordRules(options.domain, options.rules) + if (rules) { + return Password.generateOrThrow(rules) + } + } + } + } catch (e) { + // if an 'onError' callback was provided, forward all errors + if (options?.onError && typeof options?.onError === 'function') { + options.onError(e) + } else { + // otherwise, only console.error unknown errors (which could be implementation bugs) + const isKnownError = e instanceof ParserError || e instanceof HostnameInputError + if (!isKnownError) { + console.error(e) + } + } + } + + // At this point, we have to trust the generation will not throw + // as it is NOT using any user/page-provided data + return Password.generateDefault() +} + +// An extension type to differentiate between known errors +class HostnameInputError extends Error {} + +/** + * @typedef {Record} RulesFormat + */ + +/** + * @private + * @param {string} inputHostname + * @param {RulesFormat} rules + * @returns {string | undefined} + * @throws {HostnameInputError} + */ +function _selectPasswordRules (inputHostname, rules) { + const hostname = _safeHostname(inputHostname) + // direct match + if (rules[hostname]) { + return rules[hostname]['password-rules'] + } + + // otherwise, start chopping off subdomains and re-joining to compare + const pieces = hostname.split('.') + while (pieces.length > 1) { + pieces.shift() + const joined = pieces.join('.') + if (rules[joined]) { + return rules[joined]['password-rules'] + } + } + return undefined +} + +/** + * @private + * @param {string} inputHostname; + * @throws {HostnameInputError} + * @returns {string} + */ +function _safeHostname (inputHostname) { + if (inputHostname.startsWith('http:') || inputHostname.startsWith('https:')) { + throw new HostnameInputError('invalid input, you can only provide a hostname but you gave a scheme') + } + if (inputHostname.includes(':')) { + throw new HostnameInputError('invalid input, you can only provide a hostname but you gave a :port') + } + try { + const asUrl = new URL('https://' + inputHostname) + return asUrl.hostname + } catch (e) { + throw new HostnameInputError(`could not instantiate a URL from that hostname ${inputHostname}`) + } +} + +module.exports.generate = generate +module.exports._selectPasswordRules = _selectPasswordRules +module.exports.HostnameInputError = HostnameInputError +module.exports.ParserError = ParserError +module.exports.constants = constants diff --git a/packages/password/lib/apple.password.js b/packages/password/lib/apple.password.js new file mode 100644 index 000000000..e44d7bdf5 --- /dev/null +++ b/packages/password/lib/apple.password.js @@ -0,0 +1,550 @@ +/* + * + * NOTE: + * + * This file was created with inspiration from https://developer.apple.com/password-rules + * + * * The changes made by DuckDuckGo employees are: + * + * 1) removed all logic relating to 'more typeable passwords' + * 2) reduced the number of password styles from 4 to only the 1 which suits our needs + * 2) added JSDoc comments (for Typescript checking) + * + */ +const parser = require('./rules-parser') +const {constants} = require('./constants') + +/** + * @typedef {{ + * PasswordAllowedCharacters?: string, + * PasswordRequiredCharacters?: string[], + * PasswordRepeatedCharacterLimit?: number, + * PasswordConsecutiveCharacterLimit?: number, + * PasswordMinLength?: number, + * PasswordMaxLength?: number, + * }} Requirements + */ + +/** + * @typedef {{ + * NumberOfRequiredRandomCharacters: number, + * PasswordAllowedCharacters: string, + * RequiredCharacterSets: string[] + * }} PasswordParameters + */ + +const defaults = Object.freeze({ + SCAN_SET_ORDER: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\\\"'<>,.?/ ]", + defaultUnambiguousCharacters: 'abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789', + defaultPasswordLength: constants.MIN_LENGTH, + defaultPasswordRules: constants.DEFAULT_PASSWORD_RULES, + defaultRequiredCharacterSets: ['abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', '0123456789'], + /** + * @type {typeof window.crypto.getRandomValues | typeof import("crypto").randomFillSync | null} + */ + getRandomValues: null +}) + +/** + * This is added here to ensure: + * + * 1) `getRandomValues` is called with the correct prototype chain + * 2) `window` is not accessed when in a node environment + * 3) `bind` is not called in a hot code path + * + * @type {{ getRandomValues: typeof window.crypto.getRandomValues }} + */ +const safeGlobals = {} +if (typeof window !== 'undefined') { + safeGlobals.getRandomValues = window.crypto.getRandomValues.bind(window.crypto) +} + +class Password { + /** + * @type {typeof defaults} + */ + options; + /** + * @param {Partial} [options] + */ + constructor (options = {}) { + this.options = { + ...defaults, + ...options + } + return this + } + + /** + * This is here to provide external access to un-modified defaults + * in case they are needed for tests/verifications + * @type {typeof defaults} + */ + static defaults = defaults; + + /** + * Generates a password from the given input. + * + * Note: This method will throw an error if parsing fails - use with caution + * + * @example + * + * ```javascript + * const password = Password.generateOrThrow("minlength: 20") + * ``` + * @public + * @param {string} inputString + * @param {Partial} [options] + * @throws {ParserError|Error} + * @returns {string} + */ + static generateOrThrow (inputString, options = {}) { + return new Password(options) + .parse(inputString) + .generate() + } + /** + * Generates a password using the default ruleset. + * + * @example + * + * ```javascript + * const password = Password.generateDefault() + * ``` + * + * @public + * @param {Partial} [options] + * @returns {string} + */ + static generateDefault (options = {}) { + return new Password(options) + .parse(Password.defaults.defaultPasswordRules) + .generate() + } + + /** + * Convert a ruleset into it's internally-used component pieces. + * + * @param {string} inputString + * @throws {parser.ParserError|Error} + * @returns {{ + * requirements: Requirements; + * parameters: PasswordParameters; + * rules: parser.Rule[], + * get entropy(): number; + * generate: () => string; + * }} + */ + parse (inputString) { + const rules = parser.parsePasswordRules(inputString) + const requirements = this._requirementsFromRules(rules) + if (!requirements) throw new Error('could not generate requirements for ' + JSON.stringify(inputString)) + const parameters = this._passwordGenerationParametersDictionary(requirements) + return { + requirements, + parameters, + rules, + get entropy () { + return Math.log2(parameters.PasswordAllowedCharacters.length ** parameters.NumberOfRequiredRandomCharacters) + }, + generate: () => { + const password = this._generatedPasswordMatchingRequirements(requirements, parameters) + /** + * The following is unreachable because if user input was incorrect then + * the parsing phase would throw. The following lines is to satisfy Typescript + */ + if (password === '') throw new Error('unreachable') + return password + } + } + } + + /** + * Given an array of `Rule's`, convert into `Requirements` + * + * @param {parser.Rule[]} passwordRules + * @returns {Requirements | null} + */ + _requirementsFromRules (passwordRules) { + /** @type {Requirements} */ + const requirements = {} + for (let rule of passwordRules) { + if (rule.name === parser.RuleName.ALLOWED) { + console.assert(!('PasswordAllowedCharacters' in requirements)) + const chars = this._charactersFromCharactersClasses(rule.value) + const scanSet = this._canonicalizedScanSetFromCharacters(chars) + if (scanSet) { + requirements.PasswordAllowedCharacters = scanSet + } + } else if (rule.name === parser.RuleName.MAX_CONSECUTIVE) { + console.assert(!('PasswordRepeatedCharacterLimit' in requirements)) + requirements.PasswordRepeatedCharacterLimit = rule.value + } else if (rule.name === parser.RuleName.REQUIRED) { + let requiredCharacters = requirements.PasswordRequiredCharacters + if (!requiredCharacters) { + requiredCharacters = requirements.PasswordRequiredCharacters = [] + } + requiredCharacters.push(this._canonicalizedScanSetFromCharacters(this._charactersFromCharactersClasses(rule.value))) + } else if (rule.name === parser.RuleName.MIN_LENGTH) { + requirements.PasswordMinLength = rule.value + } else if (rule.name === parser.RuleName.MAX_LENGTH) { + requirements.PasswordMaxLength = rule.value + } + } + + // Only include an allowed rule matching SCAN_SET_ORDER (all characters) when a required rule is also present. + if (requirements.PasswordAllowedCharacters === this.options.SCAN_SET_ORDER && !requirements.PasswordRequiredCharacters) { + delete requirements.PasswordAllowedCharacters + } + + // Fix up PasswordRequiredCharacters, if needed. + if (requirements.PasswordRequiredCharacters && requirements.PasswordRequiredCharacters.length === 1 && requirements.PasswordRequiredCharacters[0] === this.options.SCAN_SET_ORDER) { + delete requirements.PasswordRequiredCharacters + } + + return Object.keys(requirements).length ? requirements : null + } + + /** + * @param {number} range + * @returns {number} + */ + _randomNumberWithUniformDistribution (range) { + const getRandomValues = this.options.getRandomValues || safeGlobals.getRandomValues + // Based on the algorithm described in https://pthree.org/2018/06/13/why-the-multiply-and-floor-rng-method-is-biased/ + const max = Math.floor(2 ** 32 / range) * range + let x + do { + x = getRandomValues(new Uint32Array(1))[0] + } while (x >= max) + + return (x % range) + } + + /** + * @param {number} numberOfRequiredRandomCharacters + * @param {string} allowedCharacters + */ + _classicPassword (numberOfRequiredRandomCharacters, allowedCharacters) { + const length = allowedCharacters.length + const randomCharArray = Array(numberOfRequiredRandomCharacters) + for (let i = 0; i < numberOfRequiredRandomCharacters; i++) { + const index = this._randomNumberWithUniformDistribution(length) + randomCharArray[i] = allowedCharacters[index] + } + return randomCharArray.join('') + } + + /** + * @param {string} password + * @param {number} consecutiveCharLimit + * @returns {boolean} + */ + _passwordHasNotExceededConsecutiveCharLimit (password, consecutiveCharLimit) { + let longestConsecutiveCharLength = 1 + let firstConsecutiveCharIndex = 0 + // Both "123" or "abc" and "321" or "cba" are considered consecutive. + let isSequenceAscending + for (let i = 1; i < password.length; i++) { + const currCharCode = password.charCodeAt(i) + const prevCharCode = password.charCodeAt(i - 1) + if (isSequenceAscending) { + // If `isSequenceAscending` is defined, then we know that we are in the middle of an existing + // pattern. Check if the pattern continues based on whether the previous pattern was + // ascending or descending. + if ((isSequenceAscending.valueOf() && currCharCode === prevCharCode + 1) || (!isSequenceAscending.valueOf() && currCharCode === prevCharCode - 1)) { + continue + } + + // Take into account the case when the sequence transitions from descending + // to ascending. + if (currCharCode === prevCharCode + 1) { + firstConsecutiveCharIndex = i - 1 + isSequenceAscending = Boolean(true) + continue + } + + // Take into account the case when the sequence transitions from ascending + // to descending. + if (currCharCode === prevCharCode - 1) { + firstConsecutiveCharIndex = i - 1 + isSequenceAscending = Boolean(false) + continue + } + + isSequenceAscending = null + } else if (currCharCode === prevCharCode + 1) { + isSequenceAscending = Boolean(true) + continue + } else if (currCharCode === prevCharCode - 1) { + isSequenceAscending = Boolean(false) + continue + } + + const currConsecutiveCharLength = i - firstConsecutiveCharIndex + if (currConsecutiveCharLength > longestConsecutiveCharLength) { + longestConsecutiveCharLength = currConsecutiveCharLength + } + + firstConsecutiveCharIndex = i + } + + if (isSequenceAscending) { + const currConsecutiveCharLength = password.length - firstConsecutiveCharIndex + if (currConsecutiveCharLength > longestConsecutiveCharLength) { + longestConsecutiveCharLength = currConsecutiveCharLength + } + } + + return longestConsecutiveCharLength <= consecutiveCharLimit + } + + /** + * @param {string} password + * @param {number} repeatedCharLimit + * @returns {boolean} + */ + _passwordHasNotExceededRepeatedCharLimit (password, repeatedCharLimit) { + let longestRepeatedCharLength = 1 + let lastRepeatedChar = password.charAt(0) + let lastRepeatedCharIndex = 0 + for (let i = 1; i < password.length; i++) { + const currChar = password.charAt(i) + if (currChar === lastRepeatedChar) { + continue + } + + const currRepeatedCharLength = i - lastRepeatedCharIndex + if (currRepeatedCharLength > longestRepeatedCharLength) { + longestRepeatedCharLength = currRepeatedCharLength + } + + lastRepeatedChar = currChar + lastRepeatedCharIndex = i + } + return longestRepeatedCharLength <= repeatedCharLimit + } + + /** + * @param {string} password + * @param {string[]} requiredCharacterSets + * @returns {boolean} + */ + _passwordContainsRequiredCharacters (password, requiredCharacterSets) { + const requiredCharacterSetsLength = requiredCharacterSets.length + const passwordLength = password.length + for (let i = 0; i < requiredCharacterSetsLength; i++) { + const requiredCharacterSet = requiredCharacterSets[i] + let hasRequiredChar = false + for (let j = 0; j < passwordLength; j++) { + const char = password.charAt(j) + if (requiredCharacterSet.indexOf(char) !== -1) { + hasRequiredChar = true + break + } + } + if (!hasRequiredChar) { + return false + } + } + return true + } + + /** + * @param {string} string1 + * @param {string} string2 + * @returns {boolean} + */ + _stringsHaveAtLeastOneCommonCharacter (string1, string2) { + const string2Length = string2.length + for (let i = 0; i < string2Length; i++) { + const char = string2.charAt(i) + if (string1.indexOf(char) !== -1) { + return true + } + } + + return false + } + + /** + * @param {Requirements} requirements + * @returns {PasswordParameters} + */ + _passwordGenerationParametersDictionary (requirements) { + let minPasswordLength = requirements.PasswordMinLength + const maxPasswordLength = requirements.PasswordMaxLength + + // @ts-ignore + if (minPasswordLength > maxPasswordLength) { + // Resetting invalid value of min length to zero means "ignore min length parameter in password generation". + minPasswordLength = 0 + } + + const requiredCharacterArray = requirements.PasswordRequiredCharacters + let allowedCharacters = requirements.PasswordAllowedCharacters + let requiredCharacterSets = this.options.defaultRequiredCharacterSets + + if (requiredCharacterArray) { + const mutatedRequiredCharacterSets = [] + const requiredCharacterArrayLength = requiredCharacterArray.length + + for (let i = 0; i < requiredCharacterArrayLength; i++) { + const requiredCharacters = requiredCharacterArray[i] + if (allowedCharacters && this._stringsHaveAtLeastOneCommonCharacter(requiredCharacters, allowedCharacters)) { + mutatedRequiredCharacterSets.push(requiredCharacters) + } + } + requiredCharacterSets = mutatedRequiredCharacterSets + } + + // If requirements allow, we will generateOrThrow the password in default format: "xxx-xxx-xxx-xxx". + let numberOfRequiredRandomCharacters = this.options.defaultPasswordLength + if (minPasswordLength && minPasswordLength > numberOfRequiredRandomCharacters) { + numberOfRequiredRandomCharacters = minPasswordLength + } + + if (maxPasswordLength && maxPasswordLength < numberOfRequiredRandomCharacters) { + numberOfRequiredRandomCharacters = maxPasswordLength + } + + if (!allowedCharacters) { + allowedCharacters = this.options.defaultUnambiguousCharacters + } + + // In default password format, we use dashes only as separators, not as symbols you can encounter at a random position. + + if (!requiredCharacterSets) { + requiredCharacterSets = this.options.defaultRequiredCharacterSets + } + + // If we have more requirements of the type "need a character from set" than the length of the password we want to generateOrThrow, then + // we will never be able to meet these requirements, and we'll end up in an infinite loop generating passwords. To avoid this, + // reset required character sets if the requirements are impossible to meet. + if (requiredCharacterSets.length > numberOfRequiredRandomCharacters) { + requiredCharacterSets = [] + } + + // Do not require any character sets that do not contain allowed characters. + const requiredCharacterSetsLength = requiredCharacterSets.length + const mutatedRequiredCharacterSets = [] + const allowedCharactersLength = allowedCharacters.length + for (let i = 0; i < requiredCharacterSetsLength; i++) { + const requiredCharacterSet = requiredCharacterSets[i] + let requiredCharacterSetContainsAllowedCharacters = false + for (let j = 0; j < allowedCharactersLength; j++) { + const character = allowedCharacters.charAt(j) + if (requiredCharacterSet.indexOf(character) !== -1) { + requiredCharacterSetContainsAllowedCharacters = true + break + } + } + if (requiredCharacterSetContainsAllowedCharacters) { + mutatedRequiredCharacterSets.push(requiredCharacterSet) + } + } + requiredCharacterSets = mutatedRequiredCharacterSets + + return { + NumberOfRequiredRandomCharacters: numberOfRequiredRandomCharacters, + PasswordAllowedCharacters: allowedCharacters, + RequiredCharacterSets: requiredCharacterSets + } + } + + /** + * @param {Requirements | null} requirements + * @param {PasswordParameters} [parameters] + * @returns {string} + */ + _generatedPasswordMatchingRequirements (requirements, parameters) { + requirements = requirements || {} + parameters = parameters || this._passwordGenerationParametersDictionary(requirements) + const numberOfRequiredRandomCharacters = parameters.NumberOfRequiredRandomCharacters + const repeatedCharLimit = requirements.PasswordRepeatedCharacterLimit + const allowedCharacters = parameters.PasswordAllowedCharacters + const shouldCheckRepeatedCharRequirement = !!repeatedCharLimit + + while (true) { + const password = this._classicPassword(numberOfRequiredRandomCharacters, allowedCharacters) + + if (!this._passwordContainsRequiredCharacters(password, parameters.RequiredCharacterSets)) { + continue + } + + if (shouldCheckRepeatedCharRequirement) { + if (repeatedCharLimit !== undefined && repeatedCharLimit >= 1 && !this._passwordHasNotExceededRepeatedCharLimit(password, repeatedCharLimit)) { + continue + } + } + + const consecutiveCharLimit = requirements.PasswordConsecutiveCharacterLimit + if (consecutiveCharLimit && consecutiveCharLimit >= 1) { + if (!this._passwordHasNotExceededConsecutiveCharLimit(password, consecutiveCharLimit)) { + continue + } + } + + return password || '' + } + } + + /** + * @param {parser.CustomCharacterClass | parser.NamedCharacterClass} characterClass + * @returns {string[]} + */ + _scanSetFromCharacterClass (characterClass) { + if (characterClass instanceof parser.CustomCharacterClass) { + return characterClass.characters + } + console.assert(characterClass instanceof parser.NamedCharacterClass) + switch (characterClass.name) { + case parser.Identifier.ASCII_PRINTABLE: + case parser.Identifier.UNICODE: + return this.options.SCAN_SET_ORDER.split('') + case parser.Identifier.DIGIT: + return this.options.SCAN_SET_ORDER.substring(this.options.SCAN_SET_ORDER.indexOf('0'), this.options.SCAN_SET_ORDER.indexOf('9') + 1).split('') + case parser.Identifier.LOWER: + return this.options.SCAN_SET_ORDER.substring(this.options.SCAN_SET_ORDER.indexOf('a'), this.options.SCAN_SET_ORDER.indexOf('z') + 1).split('') + case parser.Identifier.SPECIAL: + return this.options.SCAN_SET_ORDER.substring(this.options.SCAN_SET_ORDER.indexOf('-'), this.options.SCAN_SET_ORDER.indexOf(']') + 1).split('') + case parser.Identifier.UPPER: + return this.options.SCAN_SET_ORDER.substring(this.options.SCAN_SET_ORDER.indexOf('A'), this.options.SCAN_SET_ORDER.indexOf('Z') + 1).split('') + } + console.assert(false, parser.SHOULD_NOT_BE_REACHED) + return [] + } + + /** + * @param {(parser.CustomCharacterClass | parser.NamedCharacterClass)[]} characterClasses + */ + _charactersFromCharactersClasses (characterClasses) { + const output = [] + for (let characterClass of characterClasses) { + output.push(...this._scanSetFromCharacterClass(characterClass)) + } + return output + } + + /** + * @param {string[]} characters + * @returns {string} + */ + _canonicalizedScanSetFromCharacters (characters) { + if (!characters.length) { + return '' + } + let shadowCharacters = Array.prototype.slice.call(characters) + shadowCharacters.sort((a, b) => this.options.SCAN_SET_ORDER.indexOf(a) - this.options.SCAN_SET_ORDER.indexOf(b)) + let uniqueCharacters = [shadowCharacters[0]] + for (let i = 1, length = shadowCharacters.length; i < length; ++i) { + if (shadowCharacters[i] === shadowCharacters[i - 1]) { + continue + } + uniqueCharacters.push(shadowCharacters[i]) + } + return uniqueCharacters.join('') + } +} + +module.exports.Password = Password diff --git a/packages/password/lib/constants.js b/packages/password/lib/constants.js new file mode 100644 index 000000000..331ac0236 --- /dev/null +++ b/packages/password/lib/constants.js @@ -0,0 +1,11 @@ +const MIN_LENGTH = 20 +const MAX_LENGTH = 30 +const DEFAULT_PASSWORD_RULES = `minlength: ${MIN_LENGTH}; maxlength: ${MAX_LENGTH};` + +const constants = { + MIN_LENGTH, + MAX_LENGTH, + DEFAULT_PASSWORD_RULES +} + +module.exports.constants = constants diff --git a/packages/password/lib/rules-parser.js b/packages/password/lib/rules-parser.js new file mode 100644 index 000000000..9d5d82964 --- /dev/null +++ b/packages/password/lib/rules-parser.js @@ -0,0 +1,644 @@ +// Copyright (c) 2019 - 2020 Apple Inc. Licensed under MIT License. + +/* + * + * NOTE: + * + * This file was taken as intended from https://github.com/apple/password-manager-resources. + * + * The only additions from DuckDuckGo employees are + * + * 1) exporting some identifiers + * 2) adding some JSDoc comments + * 3) making this parser throw when it cannot produce any rules + * ^ the default implementation still returns a base-line ruleset, which we didn't want. + * + */ + +const Identifier = { + ASCII_PRINTABLE: 'ascii-printable', + DIGIT: 'digit', + LOWER: 'lower', + SPECIAL: 'special', + UNICODE: 'unicode', + UPPER: 'upper' +} + +const RuleName = { + ALLOWED: 'allowed', + MAX_CONSECUTIVE: 'max-consecutive', + REQUIRED: 'required', + MIN_LENGTH: 'minlength', + MAX_LENGTH: 'maxlength' +} + +const CHARACTER_CLASS_START_SENTINEL = '[' + +const CHARACTER_CLASS_END_SENTINEL = ']' +const PROPERTY_VALUE_SEPARATOR = ',' +const PROPERTY_SEPARATOR = ';' +const PROPERTY_VALUE_START_SENTINEL = ':' +const SPACE_CODE_POINT = ' '.codePointAt(0) + +const SHOULD_NOT_BE_REACHED = 'Should not be reached' + +class Rule { + constructor (name, value) { + this._name = name + this.value = value + } + get name () { return this._name } + toString () { return JSON.stringify(this) } +}; + +class NamedCharacterClass { + constructor (name) { + console.assert(_isValidRequiredOrAllowedPropertyValueIdentifier(name)) + this._name = name + } + get name () { return this._name.toLowerCase() } + toString () { return this._name } + toHTMLString () { return this._name } +}; + +class ParserError extends Error {}; + +class CustomCharacterClass { + constructor (characters) { + console.assert(characters instanceof Array) + this._characters = characters + } + get characters () { return this._characters } + toString () { return `[${this._characters.join('')}]` } + toHTMLString () { return `[${this._characters.join('').replace('"', '"')}]` } +}; + +// MARK: Lexer functions + +function _isIdentifierCharacter (c) { + console.assert(c.length === 1) + // eslint-disable-next-line no-mixed-operators + return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c === '-' +} + +function _isASCIIDigit (c) { + console.assert(c.length === 1) + return c >= '0' && c <= '9' +} + +function _isASCIIPrintableCharacter (c) { + console.assert(c.length === 1) + return c >= ' ' && c <= '~' +} + +function _isASCIIWhitespace (c) { + console.assert(c.length === 1) + return c === ' ' || c === '\f' || c === '\n' || c === '\r' || c === '\t' +} + +// MARK: ASCII printable character bit set and canonicalization functions + +function _bitSetIndexForCharacter (c) { + console.assert(c.length === 1) + // @ts-ignore + return c.codePointAt(0) - SPACE_CODE_POINT +} + +function _characterAtBitSetIndex (index) { + return String.fromCodePoint(index + SPACE_CODE_POINT) +} + +function _markBitsForNamedCharacterClass (bitSet, namedCharacterClass) { + console.assert(bitSet instanceof Array) + console.assert(namedCharacterClass.name !== Identifier.UNICODE) + console.assert(namedCharacterClass.name !== Identifier.ASCII_PRINTABLE) + if (namedCharacterClass.name === Identifier.UPPER) { + bitSet.fill(true, _bitSetIndexForCharacter('A'), _bitSetIndexForCharacter('Z') + 1) + } else if (namedCharacterClass.name === Identifier.LOWER) { + bitSet.fill(true, _bitSetIndexForCharacter('a'), _bitSetIndexForCharacter('z') + 1) + } else if (namedCharacterClass.name === Identifier.DIGIT) { + bitSet.fill(true, _bitSetIndexForCharacter('0'), _bitSetIndexForCharacter('9') + 1) + } else if (namedCharacterClass.name === Identifier.SPECIAL) { + bitSet.fill(true, _bitSetIndexForCharacter(' '), _bitSetIndexForCharacter('/') + 1) + bitSet.fill(true, _bitSetIndexForCharacter(':'), _bitSetIndexForCharacter('@') + 1) + bitSet.fill(true, _bitSetIndexForCharacter('['), _bitSetIndexForCharacter('`') + 1) + bitSet.fill(true, _bitSetIndexForCharacter('{'), _bitSetIndexForCharacter('~') + 1) + } else { + console.assert(false, SHOULD_NOT_BE_REACHED, namedCharacterClass) + } +} + +function _markBitsForCustomCharacterClass (bitSet, customCharacterClass) { + for (let character of customCharacterClass.characters) { + bitSet[_bitSetIndexForCharacter(character)] = true + } +} + +function _canonicalizedPropertyValues (propertyValues, keepCustomCharacterClassFormatCompliant) { + // @ts-ignore + let asciiPrintableBitSet = new Array('~'.codePointAt(0) - ' '.codePointAt(0) + 1) + + for (let propertyValue of propertyValues) { + if (propertyValue instanceof NamedCharacterClass) { + if (propertyValue.name === Identifier.UNICODE) { + return [new NamedCharacterClass(Identifier.UNICODE)] + } + + if (propertyValue.name === Identifier.ASCII_PRINTABLE) { + return [new NamedCharacterClass(Identifier.ASCII_PRINTABLE)] + } + + _markBitsForNamedCharacterClass(asciiPrintableBitSet, propertyValue) + } else if (propertyValue instanceof CustomCharacterClass) { + _markBitsForCustomCharacterClass(asciiPrintableBitSet, propertyValue) + } + } + + let charactersSeen = [] + + function checkRange (start, end) { + let temp = [] + for (let i = _bitSetIndexForCharacter(start); i <= _bitSetIndexForCharacter(end); ++i) { + if (asciiPrintableBitSet[i]) { + temp.push(_characterAtBitSetIndex(i)) + } + } + + let result = temp.length === (_bitSetIndexForCharacter(end) - _bitSetIndexForCharacter(start) + 1) + if (!result) { + charactersSeen = charactersSeen.concat(temp) + } + return result + } + + let hasAllUpper = checkRange('A', 'Z') + let hasAllLower = checkRange('a', 'z') + let hasAllDigits = checkRange('0', '9') + + // Check for special characters, accounting for characters that are given special treatment (i.e. '-' and ']') + let hasAllSpecial = false + let hasDash = false + let hasRightSquareBracket = false + let temp = [] + for (let i = _bitSetIndexForCharacter(' '); i <= _bitSetIndexForCharacter('/'); ++i) { + if (!asciiPrintableBitSet[i]) { + continue + } + + let character = _characterAtBitSetIndex(i) + if (keepCustomCharacterClassFormatCompliant && character === '-') { + hasDash = true + } else { + temp.push(character) + } + } + for (let i = _bitSetIndexForCharacter(':'); i <= _bitSetIndexForCharacter('@'); ++i) { + if (asciiPrintableBitSet[i]) { + temp.push(_characterAtBitSetIndex(i)) + } + } + for (let i = _bitSetIndexForCharacter('['); i <= _bitSetIndexForCharacter('`'); ++i) { + if (!asciiPrintableBitSet[i]) { + continue + } + + let character = _characterAtBitSetIndex(i) + if (keepCustomCharacterClassFormatCompliant && character === ']') { + hasRightSquareBracket = true + } else { + temp.push(character) + } + } + for (let i = _bitSetIndexForCharacter('{'); i <= _bitSetIndexForCharacter('~'); ++i) { + if (asciiPrintableBitSet[i]) { + temp.push(_characterAtBitSetIndex(i)) + } + } + + if (hasDash) { + temp.unshift('-') + } + if (hasRightSquareBracket) { + temp.push(']') + } + + let numberOfSpecialCharacters = (_bitSetIndexForCharacter('/') - _bitSetIndexForCharacter(' ') + 1) + + (_bitSetIndexForCharacter('@') - _bitSetIndexForCharacter(':') + 1) + + (_bitSetIndexForCharacter('`') - _bitSetIndexForCharacter('[') + 1) + + (_bitSetIndexForCharacter('~') - _bitSetIndexForCharacter('{') + 1) + hasAllSpecial = temp.length === numberOfSpecialCharacters + if (!hasAllSpecial) { + charactersSeen = charactersSeen.concat(temp) + } + + let result = [] + if (hasAllUpper && hasAllLower && hasAllDigits && hasAllSpecial) { + return [new NamedCharacterClass(Identifier.ASCII_PRINTABLE)] + } + if (hasAllUpper) { + result.push(new NamedCharacterClass(Identifier.UPPER)) + } + if (hasAllLower) { + result.push(new NamedCharacterClass(Identifier.LOWER)) + } + if (hasAllDigits) { + result.push(new NamedCharacterClass(Identifier.DIGIT)) + } + if (hasAllSpecial) { + result.push(new NamedCharacterClass(Identifier.SPECIAL)) + } + if (charactersSeen.length) { + result.push(new CustomCharacterClass(charactersSeen)) + } + return result +} + +// MARK: Parser functions + +function _indexOfNonWhitespaceCharacter (input, position = 0) { + console.assert(position >= 0) + console.assert(position <= input.length) + + let length = input.length + while (position < length && _isASCIIWhitespace(input[position])) { ++position } + + return position +} + +function _parseIdentifier (input, position) { + console.assert(position >= 0) + console.assert(position < input.length) + console.assert(_isIdentifierCharacter(input[position])) + + let length = input.length + let seenIdentifiers = [] + do { + let c = input[position] + if (!_isIdentifierCharacter(c)) { + break + } + + seenIdentifiers.push(c) + ++position + } while (position < length) + + return [seenIdentifiers.join(''), position] +} + +function _isValidRequiredOrAllowedPropertyValueIdentifier (identifier) { + return identifier && Object.values(Identifier).includes(identifier.toLowerCase()) +} + +function _parseCustomCharacterClass (input, position) { + console.assert(position >= 0) + console.assert(position < input.length) + console.assert(input[position] === CHARACTER_CLASS_START_SENTINEL) + + let length = input.length + ++position + if (position >= length) { + // console.error('Found end-of-line instead of character class character') + return [null, position] + } + + let initialPosition = position + let result = [] + do { + let c = input[position] + if (!_isASCIIPrintableCharacter(c)) { + ++position + continue + } + + if (c === '-' && (position - initialPosition) > 0) { + // FIXME: Should this be an error? + console.warn("Ignoring '-'; a '-' may only appear as the first character in a character class") + ++position + continue + } + + result.push(c) + ++position + if (c === CHARACTER_CLASS_END_SENTINEL) { + break + } + } while (position < length) + + if (position < length && input[position] !== CHARACTER_CLASS_END_SENTINEL) { + // Fix up result; we over consumed. + result.pop() + return [result, position] + } else if (position === length && input[position - 1] === CHARACTER_CLASS_END_SENTINEL) { + // Fix up result; we over consumed. + result.pop() + return [result, position] + } + + if (position < length && input[position] === CHARACTER_CLASS_END_SENTINEL) { + return [result, position + 1] + } + + // console.error('Found end-of-line instead of end of character class') + return [null, position] +} + +function _parsePasswordRequiredOrAllowedPropertyValue (input, position) { + console.assert(position >= 0) + console.assert(position < input.length) + + let length = input.length + let propertyValues = [] + while (true) { + if (_isIdentifierCharacter(input[position])) { + let identifierStartPosition = position + // eslint-disable-next-line no-redeclare + var [propertyValue, position] = _parseIdentifier(input, position) + if (!_isValidRequiredOrAllowedPropertyValueIdentifier(propertyValue)) { + // console.error('Unrecognized property value identifier: ' + propertyValue) + return [null, identifierStartPosition] + } + propertyValues.push(new NamedCharacterClass(propertyValue)) + } else if (input[position] === CHARACTER_CLASS_START_SENTINEL) { + // eslint-disable-next-line no-redeclare + var [propertyValue, position] = _parseCustomCharacterClass(input, position) + if (propertyValue && propertyValue.length) { + propertyValues.push(new CustomCharacterClass(propertyValue)) + } + } else { + // console.error('Failed to find start of property value: ' + input.substr(position)) + return [null, position] + } + + position = _indexOfNonWhitespaceCharacter(input, position) + if (position >= length || input[position] === PROPERTY_SEPARATOR) { + break + } + + if (input[position] === PROPERTY_VALUE_SEPARATOR) { + position = _indexOfNonWhitespaceCharacter(input, position + 1) + if (position >= length) { + // console.error('Found end-of-line instead of start of next property value') + return [null, position] + } + continue + } + + // console.error('Failed to find start of next property or property value: ' + input.substr(position)) + return [null, position] + } + return [propertyValues, position] +} + +/** + * @param input + * @param position + * @returns {[Rule|null, number, string|undefined]} + * @private + */ +function _parsePasswordRule (input, position) { + console.assert(position >= 0) + console.assert(position < input.length) + console.assert(_isIdentifierCharacter(input[position])) + + let length = input.length + + var mayBeIdentifierStartPosition = position + // eslint-disable-next-line no-redeclare + var [identifier, position] = _parseIdentifier(input, position) + if (!Object.values(RuleName).includes(identifier)) { + // console.error('Unrecognized property name: ' + identifier) + return [null, mayBeIdentifierStartPosition, undefined] + } + + if (position >= length) { + // console.error('Found end-of-line instead of start of property value') + return [null, position, undefined] + } + + if (input[position] !== PROPERTY_VALUE_START_SENTINEL) { + // console.error('Failed to find start of property value: ' + input.substr(position)) + return [null, position, undefined] + } + + let property = { name: identifier, value: null } + + position = _indexOfNonWhitespaceCharacter(input, position + 1) + // Empty value + if (position >= length || input[position] === PROPERTY_SEPARATOR) { + return [new Rule(property.name, property.value), position, undefined] + } + + switch (identifier) { + case RuleName.ALLOWED: + case RuleName.REQUIRED: { + // eslint-disable-next-line no-redeclare + var [propertyValue, position] = _parsePasswordRequiredOrAllowedPropertyValue(input, position) + if (propertyValue) { + property.value = propertyValue + } + return [new Rule(property.name, property.value), position, undefined] + } + case RuleName.MAX_CONSECUTIVE: { + // eslint-disable-next-line no-redeclare + var [propertyValue, position] = _parseMaxConsecutivePropertyValue(input, position) + if (propertyValue) { + property.value = propertyValue + } + return [new Rule(property.name, property.value), position, undefined] + } + case RuleName.MIN_LENGTH: + case RuleName.MAX_LENGTH: { + // eslint-disable-next-line no-redeclare + var [propertyValue, position] = _parseMinLengthMaxLengthPropertyValue(input, position) + if (propertyValue) { + property.value = propertyValue + } + return [new Rule(property.name, property.value), position, undefined] + } + } + console.assert(false, SHOULD_NOT_BE_REACHED) + return [null, -1, undefined] +} + +function _parseMinLengthMaxLengthPropertyValue (input, position) { + return _parseInteger(input, position) +} + +function _parseMaxConsecutivePropertyValue (input, position) { + return _parseInteger(input, position) +} + +function _parseInteger (input, position) { + console.assert(position >= 0) + console.assert(position < input.length) + + if (!_isASCIIDigit(input[position])) { + // console.error('Failed to parse value of type integer; not a number: ' + input.substr(position)) + return [null, position] + } + + let length = input.length + // let initialPosition = position + let result = 0 + do { + result = 10 * result + parseInt(input[position], 10) + ++position + } while (position < length && input[position] !== PROPERTY_SEPARATOR && _isASCIIDigit(input[position])) + + if (position >= length || input[position] === PROPERTY_SEPARATOR) { + return [result, position] + } + + // console.error('Failed to parse value of type integer; not a number: ' + input.substr(initialPosition)) + return [null, position] +} + +/** + * @param input + * @returns {[Rule[]|null, string|undefined]} + * @private + */ +function _parsePasswordRulesInternal (input) { + let parsedProperties = [] + let length = input.length + + var position = _indexOfNonWhitespaceCharacter(input) + while (position < length) { + if (!_isIdentifierCharacter(input[position])) { + // console.warn('Failed to find start of property: ' + input.substr(position)) + return [parsedProperties, undefined] + } + + // eslint-disable-next-line no-redeclare + var [parsedProperty, position, message] = _parsePasswordRule(input, position) + if (parsedProperty && parsedProperty.value) { + parsedProperties.push(parsedProperty) + } + + position = _indexOfNonWhitespaceCharacter(input, position) + if (position >= length) { + break + } + + if (input[position] === PROPERTY_SEPARATOR) { + position = _indexOfNonWhitespaceCharacter(input, position + 1) + if (position >= length) { + return [parsedProperties, undefined] + } + + continue + } + + // console.error('Failed to find start of next property: ' + input.substr(position)) + return [null, message || 'Failed to find start of next property: ' + input.substr(position)] + } + + return [parsedProperties, undefined] +} + +/** + * @param {string} input + * @param {boolean} [formatRulesForMinifiedVersion] + * @returns {Rule[]} + */ +function parsePasswordRules (input, formatRulesForMinifiedVersion) { + let [passwordRules, maybeMessage] = _parsePasswordRulesInternal(input) + + if (!passwordRules) { + throw new ParserError(maybeMessage) + } + + if (passwordRules.length === 0) { + throw new ParserError('No valid rules were provided') + } + + // When formatting rules for minified version, we should keep the formatted rules + // as similar to the input as possible. Avoid copying required rules to allowed rules. + let suppressCopyingRequiredToAllowed = formatRulesForMinifiedVersion + + let requiredRules = [] + let newAllowedValues = [] + let minimumMaximumConsecutiveCharacters = null + let maximumMinLength = 0 + let minimumMaxLength = null + + for (let rule of passwordRules) { + switch (rule.name) { + case RuleName.MAX_CONSECUTIVE: + minimumMaximumConsecutiveCharacters = minimumMaximumConsecutiveCharacters ? Math.min(rule.value, minimumMaximumConsecutiveCharacters) : rule.value + break + + case RuleName.MIN_LENGTH: + maximumMinLength = Math.max(rule.value, maximumMinLength) + break + + case RuleName.MAX_LENGTH: + minimumMaxLength = minimumMaxLength ? Math.min(rule.value, minimumMaxLength) : rule.value + break + + case RuleName.REQUIRED: + rule.value = _canonicalizedPropertyValues(rule.value, formatRulesForMinifiedVersion) + requiredRules.push(rule) + if (!suppressCopyingRequiredToAllowed) { + newAllowedValues = newAllowedValues.concat(rule.value) + } + break + + case RuleName.ALLOWED: + newAllowedValues = newAllowedValues.concat(rule.value) + break + } + } + + let newPasswordRules = [] + + if (maximumMinLength > 0) { + newPasswordRules.push(new Rule(RuleName.MIN_LENGTH, maximumMinLength)) + } + + if (minimumMaxLength !== null) { + newPasswordRules.push(new Rule(RuleName.MAX_LENGTH, minimumMaxLength)) + } + + if (minimumMaximumConsecutiveCharacters !== null) { + newPasswordRules.push(new Rule(RuleName.MAX_CONSECUTIVE, minimumMaximumConsecutiveCharacters)) + } + + let sortedRequiredRules = requiredRules.sort(function (a, b) { + const namedCharacterClassOrder = [Identifier.LOWER, Identifier.UPPER, Identifier.DIGIT, Identifier.SPECIAL, Identifier.ASCII_PRINTABLE, Identifier.UNICODE] + let aIsJustOneNamedCharacterClass = (a.value.length === 1 && (a.value[0] instanceof NamedCharacterClass)) + let bIsJustOneNamedCharacterClass = (b.value.length === 1 && (b.value[0] instanceof NamedCharacterClass)) + if (aIsJustOneNamedCharacterClass && !bIsJustOneNamedCharacterClass) { + return -1 + } + if (!aIsJustOneNamedCharacterClass && bIsJustOneNamedCharacterClass) { + return 1 + } + if (aIsJustOneNamedCharacterClass && bIsJustOneNamedCharacterClass) { + let aIndex = namedCharacterClassOrder.indexOf(a.value[0].name) + let bIndex = namedCharacterClassOrder.indexOf(b.value[0].name) + return aIndex - bIndex + } + return 0 + }) + newPasswordRules = newPasswordRules.concat(sortedRequiredRules) + + newAllowedValues = _canonicalizedPropertyValues(newAllowedValues, suppressCopyingRequiredToAllowed) + if (!suppressCopyingRequiredToAllowed && !newAllowedValues.length) { + newAllowedValues = [new NamedCharacterClass(Identifier.ASCII_PRINTABLE)] + } + if (newAllowedValues.length) { + newPasswordRules.push(new Rule(RuleName.ALLOWED, newAllowedValues)) + } + + return newPasswordRules +} + +module.exports.parsePasswordRules = parsePasswordRules +module.exports.Identifier = Identifier +module.exports.RuleName = RuleName +module.exports.SHOULD_NOT_BE_REACHED = SHOULD_NOT_BE_REACHED +module.exports.Rule = Rule +module.exports.ParserError = ParserError +module.exports.NamedCharacterClass = NamedCharacterClass +module.exports.CustomCharacterClass = CustomCharacterClass diff --git a/packages/password/package-lock.json b/packages/password/package-lock.json new file mode 100644 index 000000000..d716f5046 --- /dev/null +++ b/packages/password/package-lock.json @@ -0,0 +1,12 @@ +{ + "name": "password", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "version": "1.0.0", + "license": "ISC" + } + } +} diff --git a/packages/password/package.json b/packages/password/package.json new file mode 100644 index 000000000..f29bd5c94 --- /dev/null +++ b/packages/password/package.json @@ -0,0 +1,25 @@ +{ + "private": true, + "version": "1.0.0", + "description": "Password generation utilities", + "main": "index.js", + "scripts": { + "test": "npm run test", + "generate:html": "node html-testing/generate.js", + "rules:update": "node scripts/rules.js --write-rules-json" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/duckduckgo/duckduckgo-autofill.git" + }, + "keywords": [ + "duckduckgo", + "password" + ], + "author": "", + "license": "ISC", + "bugs": { + "url": "https://github.com/duckduckgo/duckduckgo-autofill/issues" + }, + "homepage": "https://github.com/duckduckgo/duckduckgo-autofill/blob/main/packages/password/docs/password.md" +} diff --git a/packages/password/readme.md b/packages/password/readme.md new file mode 100644 index 000000000..b0257caf7 --- /dev/null +++ b/packages/password/readme.md @@ -0,0 +1,6 @@ +# Password generation utilities + +## Docs + +- [Password generation](./docs/password.md) +- [Updating rules](./docs/updating-rules.md) diff --git a/packages/password/rules.json b/packages/password/rules.json new file mode 100644 index 000000000..5c5bdf976 --- /dev/null +++ b/packages/password/rules.json @@ -0,0 +1,764 @@ +{ + "163.com": { + "password-rules": "minlength: 6; maxlength: 16;" + }, + "1800flowers.com": { + "password-rules": "minlength: 6; required: lower, upper; required: digit;" + }, + "access.service.gov.uk": { + "password-rules": "minlength: 10; required: lower; required: upper; required: digit; required: special;" + }, + "admiral.com": { + "password-rules": "minlength: 8; required: digit; required: [- !\"#$&'()*+,.:;<=>?@[^_`{|}~]]; allowed: lower, upper;" + }, + "ae.com": { + "password-rules": "minlength: 8; maxlength: 25; required: lower; required: upper; required: digit;" + }, + "aetna.com": { + "password-rules": "minlength: 8; maxlength: 20; max-consecutive: 2; required: upper; required: digit; allowed: lower, [-_&#@];" + }, + "airasia.com": { + "password-rules": "minlength: 8; maxlength: 15; required: lower; required: upper; required: digit;" + }, + "ajisushionline.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; allowed: [ !#$%&*?@];" + }, + "aliexpress.com": { + "password-rules": "minlength: 6; maxlength: 20; allowed: lower, upper, digit;" + }, + "alliantcreditunion.com": { + "password-rules": "minlength: 8; maxlength: 20; max-consecutive: 3; required: lower, upper; required: digit; allowed: [!#$*];" + }, + "allianz.com.br": { + "password-rules": "minlength: 4; maxlength: 4;" + }, + "americanexpress.com": { + "password-rules": "minlength: 8; maxlength: 20; max-consecutive: 4; required: lower, upper; required: digit; allowed: [%&_?#=];" + }, + "anatel.gov.br": { + "password-rules": "minlength: 6; maxlength: 15; allowed: lower, upper, digit;" + }, + "ancestry.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: [-!\"#$%&'()*+,./:;<=>?@[^_`{|}~]];" + }, + "angieslist.com": { + "password-rules": "minlength: 6; maxlength: 15;" + }, + "anthem.com": { + "password-rules": "minlength: 8; maxlength: 20; max-consecutive: 3; required: lower, upper; required: digit; allowed: [!$*?@|];" + }, + "app.digio.in": { + "password-rules": "minlength: 8; maxlength: 15;" + }, + "app.parkmobile.io": { + "password-rules": "minlength: 8; maxlength: 25; required: lower; required: upper; required: digit; required: [!@#$%^&];" + }, + "apple.com": { + "password-rules": "minlength: 8; maxlength: 63; required: lower; required: upper; required: digit; allowed: ascii-printable;" + }, + "areariservata.bancaetica.it": { + "password-rules": "minlength: 8; maxlength: 10; required: lower; required: upper; required: digit; required: [!#&*+/=@_];" + }, + "artscyclery.com": { + "password-rules": "minlength: 6; maxlength: 19;" + }, + "astonmartinf1.com": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; allowed: special;" + }, + "autify.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: [!\"#$%&'()*+,./:;<=>?@[^_`{|}~]];" + }, + "axa.de": { + "password-rules": "minlength: 8; maxlength: 65; required: lower; required: upper; required: digit; allowed: [-!\"§$%&/()=?;:_+*'#];" + }, + "baidu.com": { + "password-rules": "minlength: 6; maxlength: 14;" + }, + "bancochile.cl": { + "password-rules": "minlength: 8; maxlength: 8; required: lower; required: upper; required: digit;" + }, + "bankofamerica.com": { + "password-rules": "minlength: 8; maxlength: 20; max-consecutive: 3; required: lower; required: upper; required: digit; allowed: [-@#*()+={}/?~;,._];" + }, + "battle.net": { + "password-rules": "minlength: 8; maxlength: 16; required: lower, upper; allowed: digit, special;" + }, + "bcassessment.ca": { + "password-rules": "minlength: 8; maxlength: 14;" + }, + "belkin.com": { + "password-rules": "minlength: 8; required: lower, upper; required: digit; required: [$!@~_,%&];" + }, + "benefitslogin.discoverybenefits.com": { + "password-rules": "minlength: 10; required: upper; required: digit; required: [!#$%&*?@]; allowed: lower;" + }, + "benjerry.com": { + "password-rules": "required: upper; required: upper; required: digit; required: digit; required: special; required: special; allowed: lower;" + }, + "bestbuy.com": { + "password-rules": "minlength: 20; required: lower; required: upper; required: digit; required: special;" + }, + "bhphotovideo.com": { + "password-rules": "maxlength: 15;" + }, + "billerweb.com": { + "password-rules": "minlength: 8; max-consecutive: 2; required: digit; required: upper,lower;" + }, + "biovea.com": { + "password-rules": "maxlength: 19;" + }, + "bitly.com": { + "password-rules": "minlength: 6; required: lower; required: upper; required: digit; required: [`!@#$%^&*()+~{}'\";:<>?]];" + }, + "bloomingdales.com": { + "password-rules": "minlength: 7; maxlength: 16; required: lower, upper; required: digit; required: [`!@#$%^&*()+~{}'\";:<>?]];" + }, + "bluesguitarunleashed.com": { + "password-rules": "allowed: lower, upper, digit, [!$#@];" + }, + "bochk.com": { + "password-rules": "minlength: 8; maxlength: 12; max-consecutive: 3; required: lower; required: upper; required: digit; allowed: [#$%&()*+,.:;<=>?@_];" + }, + "box.com": { + "password-rules": "minlength: 6; maxlength: 20; required: lower; required: upper; required: digit; required: digit;" + }, + "brighthorizons.com": { + "password-rules": "minlength: 8; maxlength: 16;" + }, + "callofduty.com": { + "password-rules": "minlength: 8; maxlength: 20; max-consecutive: 2; required: lower, upper; required: digit;" + }, + "capitalone.com": { + "password-rules": "minlength: 8; maxlength: 32; required: lower, upper; required: digit; allowed: [-_./\\@$*&!#];" + }, + "cardbenefitservices.com": { + "password-rules": "minlength: 7; maxlength: 100; required: lower, upper; required: digit;" + }, + "cb2.com": { + "password-rules": "minlength: 7; maxlength: 18; required: lower, upper; required: digit;" + }, + "cecredentialtrust.com": { + "password-rules": "minlength: 12; required: lower; required: upper; required: digit; required: [!#$%&*@^];" + }, + "chase.com": { + "password-rules": "minlength: 8; maxlength: 32; max-consecutive: 2; required: lower, upper; required: digit; required: [!#$%+/=@~];" + }, + "cigna.co.uk": { + "password-rules": "minlength: 8; maxlength: 12; required: lower; required: upper; required: digit;" + }, + "cigna.com": { + "password-rules": "minlength: 8; maxlength: 12; required: upper; required: digit; required: [_!.&@]; allowed: lower;" + }, + "citi.com": { + "password-rules": "minlength: 6; maxlength: 50; max-consecutive: 2; required: lower, upper; required: digit; allowed: [_!@$]" + }, + "claimlookup.com": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; required: [@#$%^&+=!];" + }, + "claro.com.br": { + "password-rules": "minlength: 8; required: lower; allowed: upper, digit, [-!@#$%&*_+=<>];" + }, + "clien.net": { + "password-rules": "minlength: 5; required: lower, upper; required: digit;" + }, + "collectivehealth.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit;" + }, + "comcastpaymentcenter.com": { + "password-rules": "minlength: 8; maxlength: 20; max-consecutive: 2;required: lower, upper; required: digit;" + }, + "comed.com": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; allowed: [-~!@#$%^&*_+=`|(){}[:;\"'<>,.?/\\]];" + }, + "commerzbank.de": { + "password-rules": "minlength: 5; maxlength: 8; required: lower, upper; required: digit;" + }, + "consorsbank.de": { + "password-rules": "minlength: 5; maxlength: 5; required: lower, upper, digit;" + }, + "consorsfinanz.de": { + "password-rules": "minlength: 6; maxlength: 15; allowed: lower, upper, digit, [-.];" + }, + "costco.com": { + "password-rules": "minlength: 8; maxlength: 20; required: lower, upper; allowed: digit, [-!#$%&'()*+/:;=?@[^_`{|}~]];" + }, + "coursera.com": { + "password-rules": "minlength: 8; maxlength: 72;" + }, + "cox.com": { + "password-rules": "minlength: 8; maxlength: 24; required: digit; required: upper,lower; allowed: [!#$%()*@^];" + }, + "crateandbarrel.com": { + "password-rules": "minlength: 9; maxlength: 64; required: lower; required: upper; required: digit; required: [!\"#$%&()*,.:<>?@^_{|}];" + }, + "cvs.com": { + "password-rules": "minlength: 8; maxlength: 25; required: lower, upper; required: digit; allowed: [!@#$%^&*()];" + }, + "dailymail.co.uk": { + "password-rules": "minlength: 5; maxlength: 15;" + }, + "dan.org": { + "password-rules": "minlength: 8; maxlength: 25; required: lower; required: upper; required: digit; required: [!@$%^&*];" + }, + "danawa.com": { + "password-rules": "minlength: 8; maxlength: 21; required: lower, upper; required: digit; required: [!@$%^&*];" + }, + "darty.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit;" + }, + "dbs.com.hk": { + "password-rules": "minlength: 8; maxlength: 30; required: lower; required: upper; required: digit;" + }, + "decluttr.com": { + "password-rules": "minlength: 8; maxlength: 45; required: lower; required: upper; required: digit;" + }, + "delta.com": { + "password-rules": "minlength: 8; maxlength: 20; required: lower; required: upper; required: digit;" + }, + "deutsche-bank.de": { + "password-rules": "minlength: 5; maxlength: 5; required: lower, upper, digit;" + }, + "devstore.cn": { + "password-rules": "minlength: 6; maxlength: 12;" + }, + "dickssportinggoods.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: [!#$%&*?@^];" + }, + "dkb.de": { + "password-rules": "minlength: 8; maxlength: 38; required: lower, upper; required: digit; allowed: [-äüöÄÜÖß!$%&/()=?+#,.:];" + }, + "dmm.com": { + "password-rules": "minlength: 4; maxlength: 16; required: lower; required: upper; required: digit;" + }, + "dowjones.com": { + "password-rules": "maxlength: 15;" + }, + "ea.com": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; allowed: special;" + }, + "easycoop.com": { + "password-rules": "minlength: 8; required: upper; required: special; allowed: lower, digit;" + }, + "easyjet.com": { + "password-rules": "minlength: 6; maxlength: 20; required: lower; required: upper; required: digit; required: [-];" + }, + "ebrap.org": { + "password-rules": "minlength: 15; required: lower; required: lower; required: upper; required: upper; required: digit; required: digit; required: [-!@#$%^&*()_+|~=`{}[:\";'?,./.]]; required: [-!@#$%^&*()_+|~=`{}[:\";'?,./.]];" + }, + "ecompanystore.com": { + "password-rules": "minlength: 8; maxlength: 16; max-consecutive: 2; required: lower; required: upper; required: digit; required: [#$%*+.=@^_];" + }, + "eddservices.edd.ca.gov": { + "password-rules": "minlength: 8; maxlength: 12; required: lower; required: upper; required: digit; required: [!@#$%^&*()];" + }, + "empower-retirement.com": { + "password-rules": "minlength: 8; maxlength: 16;" + }, + "epicgames.com": { + "password-rules": "minlength: 7; required: lower; required: upper; required: digit; required: [-!\"#$%&'()*+,./:;<=>?@[^_`{|}~]];" + }, + "epicmix.com": { + "password-rules": "minlength: 8; maxlength: 16;" + }, + "equifax.com": { + "password-rules": "minlength: 8; maxlength: 20; required: lower; required: upper; required: digit; required: [!$*+@];" + }, + "essportal.excelityglobal.com": { + "password-rules": "minlength: 6; maxlength: 8; allowed: lower, upper, digit;" + }, + "ettoday.net": { + "password-rules": "minlength: 6; maxlength: 12;" + }, + "examservice.com.tw": { + "password-rules": "minlength: 6; maxlength: 8;" + }, + "expertflyer.com": { + "password-rules": "minlength: 5; maxlength: 16; required: lower, upper; required: digit;" + }, + "extraspace.com": { + "password-rules": "minlength: 8; maxlength: 20; allowed: lower; required: upper, digit, [!#$%&*?@];" + }, + "ezpassva.com": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; required: special;" + }, + "fc2.com": { + "password-rules": "minlength: 8; maxlength: 16;" + }, + "fedex.com": { + "password-rules": "minlength: 8; max-consecutive: 3; required: lower; required: upper; required: digit; allowed: [-!@#$%^&*_+=`|(){}[:;,.?]];" + }, + "fidelity.com": { + "password-rules": "minlength: 6; maxlength: 20; required: lower; allowed: upper,digit,[!$%'()+,./:;=?@^_|~];" + }, + "flysas.com": { + "password-rules": "minlength: 8; maxlength: 14; required: lower; required: upper; required: digit; required: [-~!@#$%^&_+=`|(){}[:\"'<>,.?]];" + }, + "fnac.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit;" + }, + "fuelrewards.com": { + "password-rules": "minlength: 8; maxlength: 16; allowed: upper,lower,digit,[!#$%@];" + }, + "gamestop.com": { + "password-rules": "minlength: 8; maxlength: 225; required: lower; required: upper; required: digit; required: [!@#$%];" + }, + "getflywheel.com": { + "password-rules": "minlength: 7; maxlength: 72;" + }, + "girlscouts.org": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; allowed: [$#!];" + }, + "gmx.net": { + "password-rules": "minlength: 8; maxlength: 40; allowed: lower, upper, digit, [-<=>~!|()@#{}$%,.?^'&*_+`:;\"[]];" + }, + "google.com": { + "password-rules": "minlength: 8; allowed: lower, upper, digit, [-!\"#$%&'()*+,./:;<=>?@[^_{|}~]];" + }, + "guardiananytime.com": { + "password-rules": "minlength: 8; maxlength: 50; max-consecutive: 2; required: lower; required: upper; required: digit, [-~!@#$%^&*_+=`|(){}[:;,.?]];" + }, + "gwl.greatwestlife.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: [-!#$%_=+<>];" + }, + "hangseng.com": { + "password-rules": "minlength: 8; maxlength: 30; required: lower; required: upper; required: digit;" + }, + "hawaiianairlines.com": { + "password-rules": "maxlength: 16;" + }, + "hertz.com": { + "password-rules": "minlength: 8; maxlength: 30; max-consecutive: 3; required: lower; required: upper; required: digit; required: [#$%^&!@];" + }, + "hetzner.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit, special;" + }, + "hilton.com": { + "password-rules": "minlength: 8; maxlength: 32; required: lower; required: upper; required: digit;" + }, + "hkbea.com": { + "password-rules": "minlength: 8; maxlength: 12; required: lower; required: upper; required: digit;" + }, + "hkexpress.com": { + "password-rules": "minlength: 8; maxlength: 15; required: lower; required: upper; required: digit; required: special;" + }, + "hotels.com": { + "password-rules": "minlength: 6; maxlength: 20; required: digit; allowed: lower, upper, [@$!#()&^*%];" + }, + "hotwire.com": { + "password-rules": "minlength: 6; maxlength: 30; allowed: lower, upper, digit, [-~!@#$%^&*_+=`|(){}[:;\"'<>,.?]];" + }, + "hrblock.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: [$#%!];" + }, + "hsbc.com.hk": { + "password-rules": "minlength: 6; maxlength: 30; required: lower; required: upper; required: digit; allowed: ['.@_];" + }, + "hsbc.com.my": { + "password-rules": "minlength: 8; maxlength: 30; required: lower, upper; required: digit; allowed: [-!$*.=?@_'];" + }, + "hypovereinsbank.de": { + "password-rules": "minlength: 6; maxlength: 10; required: lower, upper, digit; allowed: [!\"#$%&()*+:;<=>?@[{}~]];" + }, + "hyresbostader.se": { + "password-rules": "minlength: 6; maxlength: 20; required: lower, upper; required: digit;" + }, + "id.sonyentertainmentnetwork.com": { + "password-rules": "minlength: 8; maxlength: 30; required: lower, upper; required: digit; allowed: [-!@#^&*=+;:];" + }, + "identitytheft.gov": { + "password-rules": "allowed: lower, upper, digit, [!#%&*@^];" + }, + "idestination.info": { + "password-rules": "maxlength: 15;" + }, + "impots.gouv.fr": { + "password-rules": "minlength: 12; maxlength: 128; required: lower; required: digit; allowed: [-!#$%&*+/=?^_'.{|}];" + }, + "indochino.com": { + "password-rules": "minlength: 6; maxlength: 15; required: upper; required: digit; allowed: lower, special;" + }, + "internationalsos.com": { + "password-rules": "required: lower; required: upper; required: digit; required: [@#$%^&+=_];" + }, + "irctc.co.in": { + "password-rules": "minlength: 8; maxlength: 15; required: lower; required: upper; required: digit; required: [!@#$%^&*()+];" + }, + "irs.gov": { + "password-rules": "minlength: 8; maxlength: 32; required: lower; required: upper; required: digit; required: [!#$%&*@];" + }, + "jal.co.jp": { + "password-rules": "minlength: 8; maxlength: 16;" + }, + "japanpost.jp": { + "password-rules": "minlength: 8; maxlength: 16; required: digit; required: upper,lower;" + }, + "jordancu-onlinebanking.org": { + "password-rules": "minlength: 6; maxlength: 32; allowed: upper, lower, digit,[-!\"#$%&'()*+,.:;<=>?@[^_`{|}~]];" + }, + "keldoc.com": { + "password-rules": "minlength: 12; required: lower; required: upper; required: digit; required: [!@#$%^&*];" + }, + "key.harvard.edu": { + "password-rules": "minlength: 10; maxlength: 100; required: lower; required: upper; required: digit; allowed: [-@_#!&$`%*+()./,;~:{}|?>=<^[']];" + }, + "kfc.ca": { + "password-rules": "minlength: 6; maxlength: 15; required: lower; required: upper; required: digit; required: [!@#$%&?*];" + }, + "klm.com": { + "password-rules": "minlength: 8; maxlength: 12;" + }, + "la-z-boy.com": { + "password-rules": "minlength: 6; maxlength: 15; required: lower, upper; required: digit;" + }, + "ladwp.com": { + "password-rules": "minlength: 8; maxlength: 20; required: digit; allowed: lower, upper;" + }, + "launtel.net.au": { + "password-rules": "minlength: 8; required: digit; required: digit; allowed: lower, upper;" + }, + "leetchi.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: [!#$%&()*+,./:;<>?@\"_];" + }, + "lg.com": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; allowed: [-!#$%&'()*+,.:;=?@[^_{|}~]];" + }, + "live.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; allowed: [-@_#!&$`%*+()./,;~:{}|?>=<^'[]];" + }, + "lloydsbank.co.uk": { + "password-rules": "minlength: 8; maxlength: 15; required: lower; required: digit; allowed: upper;" + }, + "lowes.com": { + "password-rules": "minlength: 8; maxlength: 12; required: lower, upper; required: digit;" + }, + "lsacsso.b2clogin.com": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit, [-!#$%&*?@^_];" + }, + "lufthansa.com": { + "password-rules": "minlength: 8; maxlength: 32; required: lower; required: upper; required: digit; required: [!#$%&()*+,./:;<>?@\"_];" + }, + "macys.com": { + "password-rules": "minlength: 7; maxlength: 16; allowed: lower, upper, digit, [~!@#$%^&*+`(){}[:;\"'<>?]];" + }, + "mailbox.org": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; allowed: [-!$\"%&/()=*+#.,;:@?{}[]];" + }, + "makemytrip.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: [@$!%*#?&];" + }, + "marriott.com": { + "password-rules": "minlength: 8; maxlength: 20; required: lower; required: upper; required: digit; allowed: [$!#&@?%=];" + }, + "maybank2u.com.my": { + "password-rules": "minlength: 8; maxlength: 12; max-consecutive: 2; required: lower; required: upper; required: digit; required: [-~!@#$%^&*_+=`|(){}[:;\"'<>,.?];" + }, + "medicare.gov": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; required: [@!$%^*()];" + }, + "metlife.com": { + "password-rules": "minlength: 6; maxlength: 20;" + }, + "microsoft.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: special;" + }, + "minecraft.com": { + "password-rules": "minlength: 8; required: lower, upper; required: digit; allowed: ascii-printable;" + }, + "mintmobile.com": { + "password-rules": "minlength: 8; maxlength: 20; required: lower; required: upper; required: digit; required: special; allowed: [!#$%&()*+:;=@[^_`{}~]];" + }, + "mlb.com": { + "password-rules": "minlength: 8; maxlength: 15; required: lower; required: upper; required: digit; allowed: [!\"#$%&'()*+,./:;<=>?[\\^_`{|}~]];" + }, + "mpv.tickets.com": { + "password-rules": "minlength: 8; maxlength: 15; required: lower; required: upper; required: digit;" + }, + "my.konami.net": { + "password-rules": "minlength: 8; maxlength: 32; required: lower; required: upper; required: digit;" + }, + "myaccess.dmdc.osd.mil": { + "password-rules": "minlength: 9; maxlength: 20; required: lower; required: upper; required: digit; allowed: [-@_#!&$`%*+()./,;~:{}|?>=<^'[]];" + }, + "mygoodtogo.com": { + "password-rules": "minlength: 8; maxlength: 16; required: lower, upper, digit;" + }, + "myhealthrecord.com": { + "password-rules": "minlength: 8; maxlength: 20; allowed: lower, upper, digit, [_.!$*=];" + }, + "mysubaru.com": { + "password-rules": "minlength: 8; maxlength: 15; required: lower; required: upper; required: digit; allowed: [!#$%()*+,./:;=?@\\^`~];" + }, + "naver.com": { + "password-rules": "minlength: 6; maxlength: 16;" + }, + "nelnet.net": { + "password-rules": "minlength: 8; maxlength: 15; required: lower; required: upper; required: digit, [!@#$&*];" + }, + "netflix.com": { + "password-rules": "minlength: 4; maxlength: 60; required: lower, upper, digit; allowed: special;" + }, + "netgear.com": { + "password-rules": "minlength: 6; maxlength: 128; allowed: lower, upper, digit, [!@#$%^&*()];" + }, + "nowinstock.net": { + "password-rules": "minlength: 6; maxlength: 20; allowed: lower, upper, digit;" + }, + "order.wendys.com": { + "password-rules": "minlength: 6; maxlength: 20; required: lower; required: upper; required: digit; allowed: [!#$%&()*+/=?^_{}];" + }, + "ototoy.jp": { + "password-rules": "minlength: 8; allowed: upper,lower,digit,[- .=_];" + }, + "packageconciergeadmin.com": { + "password-rules": "minlength: 4; maxlength: 4; allowed: digit;" + }, + "paypal.com": { + "password-rules": "minlength: 8; maxlength: 20; max-consecutive: 3; required: lower, upper; required: digit, [!@#$%^&*()];" + }, + "payvgm.youraccountadvantage.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: special;" + }, + "pilotflyingj.com": { + "password-rules": "minlength: 7; required: digit; allowed: lower, upper;" + }, + "pixnet.cc": { + "password-rules": "minlength: 4; maxlength: 16; allowed: lower, upper;" + }, + "planetary.org": { + "password-rules": "minlength: 5; maxlength: 20; required: lower; required: upper; required: digit; allowed: ascii-printable;" + }, + "portal.edd.ca.gov": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: [!#$%&()*@^];" + }, + "portals.emblemhealth.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: [!#$%&'()*+,./:;<>?@\\^_`{|}~[]];" + }, + "portlandgeneral.com": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; allowed: [!#$%&*?@];" + }, + "poste.it": { + "password-rules": "minlength: 8; maxlength: 16; max-consecutive: 2; required: lower; required: upper; required: digit; required: special;" + }, + "posteo.de": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit, [-~!#$%&_+=|(){}[:;\"’<>,.? ]];" + }, + "powells.com": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; required: [\"!@#$%^&*(){}[]];" + }, + "preferredhotels.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: [!#$%&()*+@^_];" + }, + "premier.ticketek.com.au": { + "password-rules": "minlength: 6; maxlength: 16;" + }, + "prepaid.bankofamerica.com": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; required: [!@#$%^&*()+~{}'\";:<>?];" + }, + "prestocard.ca": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit,[!\"#$%&'()*+,<>?@];" + }, + "propelfuels.com": { + "password-rules": "minlength: 6; maxlength: 16;" + }, + "qdosstatusreview.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: [!#$%&@^];" + }, + "questdiagnostics.com": { + "password-rules": "minlength: 8; maxlength: 30; required: upper, lower; required: digit, [!#$%&()*+<>?@^_~];" + }, + "rejsekort.dk": { + "password-rules": "minlength: 7; maxlength: 15; required: lower; required: upper; required: digit;" + }, + "renaud-bray.com": { + "password-rules": "minlength: 8; maxlength: 38; allowed: upper,lower,digit;" + }, + "ring.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: [!@#$%^&*<>?];" + }, + "riteaid.com": { + "password-rules": "minlength: 8; maxlength: 15; required: lower; required: upper; required: digit;" + }, + "robinhood.com": { + "password-rules": "minlength: 10;" + }, + "rogers.com": { + "password-rules": "minlength: 8; required: lower, upper; required: digit; required: [!@#$];" + }, + "ruc.dk": { + "password-rules": "minlength: 6; maxlength: 8; required: lower, upper; required: [-!#%&(){}*+;%/<=>?_];" + }, + "runescape.com": { + "password-rules": "minlength: 5; maxlength: 20; required: lower; required: upper; required: digit;" + }, + "ruten.com.tw": { + "password-rules": "minlength: 6; maxlength: 15; required: lower, upper;" + }, + "salslimo.com": { + "password-rules": "minlength: 8; maxlength: 50; required: upper; required: lower; required: digit; required: [!@#$&*];" + }, + "santahelenasaude.com.br": { + "password-rules": "minlength: 8; maxlength: 15; required: lower; required: upper; required: digit; required: [-!@#$%&*_+=<>];" + }, + "santander.de": { + "password-rules": "minlength: 8; maxlength: 12; required: lower, upper; required: digit; allowed: [-!#$%&'()*,.:;=?^{}];" + }, + "sbisec.co.jp": { + "password-rules": "minlength: 10; maxlength: 20; allowed: upper,lower,digit;" + }, + "secure-arborfcu.org": { + "password-rules": "minlength: 8; maxlength: 15; required: lower; required: upper; required: digit; required: [!#$%&'()+,.:?@[_`~]];" + }, + "secure.orclinic.com": { + "password-rules": "minlength: 6; maxlength: 15; required: lower; required: digit; allowed: ascii-printable;" + }, + "secure.snnow.ca": { + "password-rules": "minlength: 7; maxlength: 16; required: digit; allowed: lower, upper;" + }, + "secure.wa.aaa.com": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; allowed: ascii-printable;" + }, + "sephora.com": { + "password-rules": "minlength: 6; maxlength: 12;" + }, + "serviziconsolari.esteri.it": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; required: special;" + }, + "servizioelettriconazionale.it": { + "password-rules": "minlength: 8; maxlength: 20; required: lower; required: upper; required: digit; required: [!#$%&*?@^_~];" + }, + "sfwater.org": { + "password-rules": "minlength: 10; maxlength: 30; required: digit; allowed: lower, upper, [!@#$%*()_+^}{:;?.];" + }, + "signin.ea.com": { + "password-rules": "minlength: 8; maxlength: 64; required: lower, upper; required: digit; allowed: [-!@#^&*=+;:];" + }, + "southwest.com": { + "password-rules": "minlength: 8; maxlength: 16; required: upper; required: digit; allowed: lower, [!@#$%^*(),.;:/\\];" + }, + "speedway.com": { + "password-rules": "minlength: 4; maxlength: 8; required: digit;" + }, + "spirit.com": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; required: [!@#$%^&*()];" + }, + "splunk.com": { + "password-rules": "minlength: 8; maxlength: 64; required: lower; required: upper; required: digit; required: [-!@#$%&*_+=<>];" + }, + "ssa.gov": { + "password-rules": "required: lower; required: upper; required: digit; required: [~!@#$%^&*];" + }, + "store.nvidia.com": { + "password-rules": "minlength: 8; maxlength: 32; required: lower; required: upper; required: digit; required: [-!@#$%^*~:;&><[{}|_+=?]];" + }, + "store.steampowered.com": { + "password-rules": "minlength: 6; required: lower; required: upper; required: digit; allowed: [~!@#$%^&*];" + }, + "successfactors.eu": { + "password-rules": "minlength: 8; maxlength: 18; required: lower; required: upper; required: digit,[-!\"#$%&'()*+,.:;<=>?@[^_`{|}~]];" + }, + "sulamericaseguros.com.br": { + "password-rules": "minlength: 6; maxlength: 6;" + }, + "sunlife.com": { + "password-rules": "minlength: 8; maxlength: 10; required: digit; required: lower, upper;" + }, + "t-mobile.net": { + "password-rules": "minlength: 8; maxlength: 16;" + }, + "target.com": { + "password-rules": "minlength: 8; maxlength: 20; required: lower, upper; required: digit, [-!\"#$%&'()*+,./:;=?@[\\^_`{|}~];" + }, + "telekom-dienste.de": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; required: [#$%&()*+,./<=>?@_{|}~];" + }, + "thameswater.co.uk": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; required: special;" + }, + "tix.soundrink.com": { + "password-rules": "minlength: 6; maxlength: 16;" + }, + "training.confluent.io": { + "password-rules": "minlength: 6; maxlength: 16; required: lower; required: upper; required: digit; allowed: [!#$%*@^_~];" + }, + "twitter.com": { + "password-rules": "minlength: 8;" + }, + "ubisoft.com": { + "password-rules": "minlength: 8; maxlength: 16; required: lower; required: upper; required: digit; required: [-]; required: [!@#$%^&*()+];" + }, + "udel.edu": { + "password-rules": "minlength: 12; maxlength: 30; required: lower; required: upper; required: digit; required: [!@#$%^&*()+];" + }, + "user.ornl.gov": { + "password-rules": "minlength: 8; maxlength: 30; max-consecutive: 3; required: lower, upper; required: digit; allowed: [!#$%./_];" + }, + "usps.com": { + "password-rules": "minlength: 8; maxlength: 50; max-consecutive: 2; required: lower; required: upper; required: digit; allowed: [-!\"#&'()+,./?@];" + }, + "vanguard.com": { + "password-rules": "minlength: 6; maxlength: 20; required: lower; required: upper; required: digit; required: digit;" + }, + "vanguardinvestor.co.uk": { + "password-rules": "minlength: 8; maxlength: 50; required: lower; required: upper; required: digit; required: digit;" + }, + "ventrachicago.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit, [!@#$%^];" + }, + "verizonwireless.com": { + "password-rules": "minlength: 8; maxlength: 20; required: lower, upper; required: digit; allowed: unicode;" + }, + "vetsfirstchoice.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; allowed: [?!@$%^+=&];" + }, + "virginmobile.ca": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: [!#$@];" + }, + "visa.com": { + "password-rules": "minlength: 6; maxlength: 32;" + }, + "visabenefits-auth.axa-assistance.us": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: [!\"#$%&()*,.:<>?@^{|}];" + }, + "vivo.com.br": { + "password-rules": "maxlength: 6; max-consecutive: 3; allowed: digit;" + }, + "walkhighlands.co.uk": { + "password-rules": "minlength: 9; maxlength: 15; required: lower; required: upper; required: digit; allowed: special;" + }, + "walmart.com": { + "password-rules": "allowed: lower, upper, digit, [-(~!@#$%^&*_+=`|(){}[:;\"'<>,.?]];" + }, + "waze.com": { + "password-rules": "minlength: 8; maxlength: 64; required: lower, upper, digit;" + }, + "wccls.org": { + "password-rules": "minlength: 4; maxlength: 16; allowed: lower, upper, digit;" + }, + "web.de": { + "password-rules": "minlength: 8; maxlength: 40; allowed: lower, upper, digit, [-<=>~!|()@#{}$%,.?^'&*_+`:;\"[]];" + }, + "wegmans.com": { + "password-rules": "minlength: 8; required: digit; required: upper,lower; required: [!#$%&*+=?@^];" + }, + "weibo.com": { + "password-rules": "minlength: 6; maxlength: 16;" + }, + "wsj.com": { + "password-rules": "minlength: 5; maxlength: 15; required: digit; allowed: lower, upper, [-~!@#$^*_=`|(){}[:;\"'<>,.?]];" + }, + "xfinity.com": { + "password-rules": "minlength: 8; maxlength: 16; required: lower, upper; required: digit;" + }, + "xvoucher.com": { + "password-rules": "minlength: 11; required: upper; required: digit; required: [!@#$%&_];" + }, + "yatra.com": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: [!#$%&'()+,.:?@[_`~]];" + }, + "zdf.de": { + "password-rules": "minlength: 8; required: upper; required: digit; allowed: lower, special;" + }, + "zoom.us": { + "password-rules": "minlength: 8; maxlength: 32; max-consecutive: 6; required: lower; required: upper; required: digit;" + } +} \ No newline at end of file diff --git a/packages/password/scripts/rules.js b/packages/password/scripts/rules.js new file mode 100644 index 000000000..59f1bbc1b --- /dev/null +++ b/packages/password/scripts/rules.js @@ -0,0 +1,99 @@ +const {join} = require('path') +const {writeFileSync} = require('fs') +const outputPath = join(__dirname, '..', 'rules.json') +const REMOTE_URL = 'https://raw.githubusercontent.com/apple/password-manager-resources/main/quirks/password-rules.json' + +/** + * This file contains utilities for keeping our password rules in sync. + */ + +/** + * @param {typeof import("../rules.json")} prev + * @param {typeof import("../rules.json")} next + * @returns {string[]} + */ +function summary (prev, next) { + const lines = [] + + for (let [domain, value] of Object.entries(prev)) { + if (domain in next) { + if (value['password-rules'] !== next[domain]['password-rules']) { + lines.push(`${domain} rules differ`) + lines.push(`\tcurrent: ${value['password-rules']}`) + lines.push(`\tremote: ${next[domain]['password-rules']}`) + } + } else { + lines.push(`${domain} no longer in remote`) + } + } + + for (let [domain, value] of Object.entries(next)) { + if (!(domain in prev)) { + lines.push(`${domain} not present in current`) + lines.push(`\trules: ${value['password-rules']}`) + } + } + + return lines +} + +/** + * @param {typeof import("../rules.json")} rules + */ +function update (rules) { + writeFileSync(outputPath, JSON.stringify(rules, null, 2)) +} + +/** + * @returns {Promise} + */ +function download () { + const https = require('https') + return new Promise((resolve, reject) => { + const chunks = [] + https.get(REMOTE_URL, (res) => { + res.on('data', (d) => { + chunks.push(d.toString()) + }) + }).on('error', (e) => { + reject(e) + }).on('close', () => { + resolve(JSON.parse(chunks.join(''))) + }) + }) +} + +/** + * @param {string[]} lines + */ +function intoMarkdown (lines) { + const header = '## Note: Password rules outdated' + const mainBody = '```\n' + lines.join('\n') + '\n```' + const updateTitle = '**You can update the rules with the following command**' + const updateCommand = '```sh\ncd packages/password && npm run rules:update\n```' + const footer = `Once you've updated the rules, commit the changes.` + return [header, mainBody, updateTitle, updateCommand, footer].join('\n') +} + +if (process.argv.includes('--write-rules-json')) { + download() + .then((remoteRules) => { + const current = require('../rules.json') + const lines = summary(current, remoteRules) + if (lines.length) { + update(remoteRules) + console.log('rules updated') + } else { + console.log('nothing to update') + } + }).catch(e => { + console.error(e) + process.exit(1) + }) +} + +module.exports.update = update +module.exports.summary = summary +module.exports.download = download +module.exports.intoMarkdown = intoMarkdown +module.exports.REMOTE_URL = REMOTE_URL diff --git a/packages/password/tests/apple.password.test.js b/packages/password/tests/apple.password.test.js new file mode 100644 index 000000000..035dbe1ae --- /dev/null +++ b/packages/password/tests/apple.password.test.js @@ -0,0 +1,81 @@ +const { Password } = require('../lib/apple.password') +const fc = require('fast-check') +const {ParserError} = require('../lib/rules-parser') + +describe('password implementation, internal API', () => { + it('should expose generateOrThrow', () => { + const pw = Password.generateOrThrow('maxlength: 10') + expect(pw.length).toBe(10) + }) + it('should expose generateOrThrow & throw', () => { + expect.assertions(1) + try { + Password.generateOrThrow('anything incorrect') + } catch (e) { + expect(e).toBeInstanceOf(ParserError) + } + }) + it('should expose generateDefault', () => { + const defaultPw = Password.generateDefault() + expect(defaultPw.length).toBe(Password.defaults.defaultPasswordLength) + }) + it('should produce passwords with an entropy score of over 80', () => { + const password = new Password() + const {entropy} = password.parse(Password.defaults.defaultPasswordRules) + expect(entropy).toBeGreaterThanOrEqual(80) + }) + it('should produce positive integers from ranges _randomNumberWithUniformDistribution', () => { + fc.assert( + fc.property(fc.integer({min: 1}), data => { + const password = new Password() + const result = password._randomNumberWithUniformDistribution(data) + return result >= 0 + }) + ) + }) + it('should produce boolean _passwordHasNotExceededConsecutiveCharLimit', () => { + fc.assert( + fc.property(fc.string(), fc.integer(), (str, int) => { + const password = new Password() + const result = password._passwordHasNotExceededConsecutiveCharLimit(str, int) + return typeof result === 'boolean' + }) + ) + }) + it('should produce string from _canonicalizedScanSetFromCharacters', () => { + fc.assert( + fc.property(fc.array(fc.string()), (strArray) => { + const password = new Password() + const result = password._canonicalizedScanSetFromCharacters(strArray) + return typeof result === 'string' + }) + ) + }) + it('should produce string from _classicPassword', () => { + fc.assert( + fc.property(fc.integer({min: 1, max: 60}), fc.string(), (int, str) => { + const password = new Password() + const result = password._classicPassword(int, str) + return typeof result === 'string' + }) + ) + }) + it('should produce boolean from _passwordHasNotExceededRepeatedCharLimit', () => { + fc.assert( + fc.property(fc.integer({min: 1, max: 60}), fc.string(), (limit, str) => { + const password = new Password() + const result = password._passwordHasNotExceededRepeatedCharLimit(str, limit) + return typeof result === 'boolean' + }) + ) + }) + it('should produce boolean from _passwordContainsRequiredCharacters', () => { + fc.assert( + fc.property(fc.string(), fc.array(fc.string()), (pw, strArray) => { + const password = new Password() + const result = password._passwordContainsRequiredCharacters(pw, strArray) + return typeof result === 'boolean' + }) + ) + }) +}) diff --git a/packages/password/tests/generate.test.js b/packages/password/tests/generate.test.js new file mode 100644 index 000000000..ef161fd9b --- /dev/null +++ b/packages/password/tests/generate.test.js @@ -0,0 +1,178 @@ +const { constants, _selectPasswordRules, HostnameInputError, ParserError, generate } = require('../') +const vendorRules = require('../rules.json') +const fc = require('fast-check') + +function testUniqueTimes (domain, passwordRules, num = 10) { + const pws = [] + for (let i = 0; i < num; i++) { + // these 3 domains have rulesets so weak that collisions are likely + if (domain === 'vivo.com.br') continue + if (domain === 'allianz.com.br') continue + if (domain === 'packageconciergeadmin.com') continue + const pw = generate({input: passwordRules}) + pws.push(pw) + } + const asSet = new Set(pws) + expect(asSet.size).toBe(pws.length) + return pws +} + +describe('password generation', () => { + describe('public api', () => { + it('creates rules with no arguments', () => { + const defaultPw = generate() + expect(defaultPw.length).toBeGreaterThanOrEqual(constants.MIN_LENGTH) + expect(defaultPw.length).toBeLessThanOrEqual(constants.MAX_LENGTH) + }) + it('creates from default rules', () => { + const defaultPw = generate({input: constants.DEFAULT_PASSWORD_RULES}) + expect(defaultPw.length).toBeGreaterThanOrEqual(constants.MIN_LENGTH) + expect(defaultPw.length).toBeLessThanOrEqual(constants.MAX_LENGTH) + }) + it('handles any value for `input`', () => { + fc.assert( + fc.property(fc.anything(), (anything) => { + // @ts-ignore - this is deliberate + const pw = generate({ input: anything }) + return typeof pw === 'string' + }) + ) + }) + it('handles any value for `domain`', () => { + fc.assert( + fc.property(fc.anything(), (anything) => { + // @ts-ignore - this is deliberate + const pw = generate({ domain: anything }) + return typeof pw === 'string' + }) + ) + }) + it('handles any value for `onError`', () => { + fc.assert( + fc.property(fc.anything(), (anything) => { + // @ts-ignore - this is deliberate + const pw = generate({ onError: anything }) + return typeof pw === 'string' + }) + ) + }) + it('handles any value for `options`', () => { + fc.assert( + fc.property(fc.anything(), (anything) => { + // @ts-ignore - this is deliberate + const pw = generate(anything) + return typeof pw === 'string' + }) + ) + }) + it('creates from vendor rules', () => { + const password = generate({ + domain: 'example.com', + rules: { + 'example.com': { + 'password-rules': 'minlength: 4; maxlength: 4;' + } + } + }) + expect(password.length).toBe(4) + }) + it.each([ + { args: { input: 'invalid input' }, expectedErrorClass: ParserError }, + { args: { domain: 'localhost:8080' }, expectedErrorClass: HostnameInputError }, + { args: { domain: 'https://example.com' }, expectedErrorClass: HostnameInputError } + ])('can receive errors', ({args, expectedErrorClass}) => { + expect.assertions(1) + generate({ + ...args, + rules: vendorRules, + onError (e) { + expect(e).toBeInstanceOf(expectedErrorClass) + } + }) + }) + it.each([ + { input: 'minlength: 30; maxlength: 40; required: upper; required: lower; required: [$]', test: (pws) => pws.every(pw => pw.includes('$')) }, + { input: 'minlength: 20; maxlength: 30; required: upper; required: lower;' }, + { input: 'required: upper;' } + ])('generates from known inputs', ({input, test}) => { + const pws = testUniqueTimes('none', input) + if (test) { + expect(test(pws)).toBeTruthy() + } + }) + it('uses DDG default password rules when inputs are not in the required format', () => { + fc.assert( + fc.property(fc.string(), data => { + const pw = generate({input: data}) + return typeof pw === 'string' && + pw.length >= constants.MIN_LENGTH && + pw.length <= constants.MAX_LENGTH + }) + ) + }) + }) + describe('using vendor list', () => { + it('_selectPasswordRules throws when a full URL is given', () => { + expect.assertions(1) + try { + _selectPasswordRules('http://example.com', vendorRules) + } catch (e) { + expect(e).toBeInstanceOf(HostnameInputError) + } + }) + it('_selectPasswordRules throws when a host is given (with port)', () => { + expect.assertions(1) + try { + _selectPasswordRules('localhost:8080', vendorRules) + } catch (e) { + expect(e).toBeInstanceOf(HostnameInputError) + } + }) + it('_selectPasswordRules throws when a URL cannot be constructed from input', () => { + expect.assertions(1) + try { + _selectPasswordRules('', vendorRules) + } catch (e) { + expect(e).toBeInstanceOf(HostnameInputError) + } + }) + it('_selectPasswordRules returns undefined for a valid host with no match', () => { + expect(_selectPasswordRules('example.com', {})).toBeUndefined() + }) + it('_selectPasswordRules returns rules when its a direct match', () => { + const actual = _selectPasswordRules('example.com', { + 'example.com': { + 'password-rules': 'minlength: 20' + } + }) + + expect(actual).toBe('minlength: 20') + }) + it.each([ + 'app.example.com', + 'app.app.app.app.example.com', + 'www.example.com' + ])('_selectPasswordRules returns rules when its a subdomain match', (input) => { + const actual = _selectPasswordRules(input, { + 'example.com': { + 'password-rules': 'minlength: 20' + } + }) + expect(actual).toBe('minlength: 20') + }) + }) + if (process.env.PASSWORD_STRESS_TEST) { + describe('with valid inputs...', () => { + let testCases = Object + .entries(vendorRules) + .map(([domain, value]) => ({domain, value})) + + it.each(testCases)('100 unique passwords for `$domain` ..', ({domain, value}) => { + testUniqueTimes(domain, value['password-rules'], 100) + }) + it.each(testCases.slice(0, 5))('10_000 unique passwords for `$domain` ..', ({domain, value}) => { + testUniqueTimes(domain, value['password-rules'], 10_000) + }) + }) + } +}) diff --git a/scripts/check-for-changes.sh b/scripts/check-for-changes.sh new file mode 100644 index 000000000..2c8b6d9af --- /dev/null +++ b/scripts/check-for-changes.sh @@ -0,0 +1,2 @@ +git update-index --refresh +git diff-index --quiet HEAD -- diff --git a/scripts/copy-assets.js b/scripts/copy-assets.js new file mode 100644 index 000000000..5acf86488 --- /dev/null +++ b/scripts/copy-assets.js @@ -0,0 +1,37 @@ +const {readFileSync, writeFileSync, copyFileSync} = require('fs') +const {join} = require('path') +const cwd = join(__dirname, '..') +const filepath = (path) => join(cwd, path) + +copyAutofillCSS() +copyAutofillScriptToExtension() + +function copyAutofillCSS () { + const css = require('../src/UI/styles/autofill-tooltip-styles.js') + writeFileSync(filepath('dist/autofill.css'), css.trim() + '\n') + writeFileSync(filepath('integration-test/extension/public/css/autofill.css'), css.trim() + '\n') + + copyFileSync(filepath('src/UI/styles/autofill-host-styles.css'), filepath('dist/autofill-host-styles_chrome.css')) + copyFirefoxCSSFile(filepath('src/UI/styles/autofill-host-styles.css'), filepath('dist/autofill-host-styles_firefox.css')) +} + +function copyFirefoxCSSFile (pathIn, pathOut) { + let css = readFileSync(pathIn, 'utf8') + + // Firefox and Chrome treat relative url differently in injected scripts. This fixes it. + const chromePublicDir = 'chrome-extension://__MSG_@@extension_id__/public/' + css = css.replaceAll(chromePublicDir, '../') + + writeFileSync(pathOut, css) +} + +function copyAutofillScriptToExtension () { + const source = 'let isDDGTestMode = false' + const replacement = 'let isDDGTestMode = true' + const autofill = readFileSync(filepath('dist/autofill.js'), 'utf8') + if (!autofill.includes(source)) { + throw new Error('cannot find source for replacement, expected: ' + source) + } + const replaced = autofill.replace(source, replacement) + writeFileSync(filepath('integration-test/extension/autofill.js'), replaced) +} diff --git a/src/DeviceInterface.d.ts b/src/DeviceInterface.d.ts deleted file mode 100644 index 5c48f95c9..000000000 --- a/src/DeviceInterface.d.ts +++ /dev/null @@ -1,46 +0,0 @@ -interface CredentialsObject { - id: Number, - username: String, - password?: String, - lastUpdated: String, -} - -interface IdentityObject { - id: Number, - title: String, - firstName?: String, - middleName?: String, - lastName?: String, - birthdayDay?: Number, - birthdayMonth?: Number, - birthdayYear?: Number, - addressStreet?: String, - addressStreet2?: String, - addressCity?: String, - addressProvince?: String, - addressPostalCode?: String, - addressCountryCode?: String, - phone?: String, - emailAddress?: String, -} - -interface CreditCardObject { - id: Number, - title: String, - displayNumber: String, - cardName?: String, - cardNumber?: String, - cardSecurityCode?: String, - expirationMonth?: Number, - expirationYear?: Number, -} - -interface PMData { - credentials: [ CredentialsObject ], - creditCards: [ CreditCardObject ], - identities: [ IdentityObject ], -} - -type APIResponse = Promise<{ success: [Type], error?: String }> - - diff --git a/src/DeviceInterface.js b/src/DeviceInterface.js index 0f095d2d0..715b0b066 100644 --- a/src/DeviceInterface.js +++ b/src/DeviceInterface.js @@ -1,374 +1,17 @@ -const EmailAutofill = require('./UI/EmailAutofill') -const DataAutofill = require('./UI/DataAutofill') const { - isApp, - notifyWebApp, isDDGApp, - isAndroid, - isDDGDomain, - sendAndWaitForAnswer, - setValue, - formatAddress, isMobileApp + isAndroid } = require('./autofill-utils') -const { - wkSend, - wkSendAndWait -} = require('./appleDeviceUtils/appleDeviceUtils') -const {scanForInputs, forms} = require('./scanForInputs.js') -const getInputConfig = require('./Form/inputTypeConfig') - -const SIGN_IN_MSG = { signMeIn: true } - -const attachTooltip = function (form, input) { - if (isMobileApp) { - form.activeInput = input - this.getAlias().then((alias) => { - if (alias) form.autofillEmail(alias) - else form.activeInput.focus() - }) - } else { - if (form.tooltip) return - - form.activeInput = input - const inputType = getInputConfig(input).type - form.tooltip = inputType === 'emailNew' - ? new EmailAutofill(input, form, this) - : new DataAutofill(input, form, this) - form.intObs.observe(input) - window.addEventListener('pointerdown', form.removeTooltip, {capture: true}) - window.addEventListener('input', form.removeTooltip, {once: true}) - } -} - -let attempts = 0 - -class InterfacePrototype { - /** @type {{privateAddress: String, personalAddress: String}} */ - #addresses = {} - get hasLocalAddresses () { - return !!(this.#addresses?.privateAddress && this.#addresses?.personalAddress) - } - getLocalAddresses () { - return this.#addresses - } - storeLocalAddresses (addresses) { - this.#addresses = addresses - } - - /** @type { PMData } */ - #data = { - credentials: [], - creditCards: [], - identities: [] - } - - /** - * Stores init data coming from the device - * @param { PMData } data - */ - storeLocalData (data) { - data.credentials.forEach((cred) => delete cred.password) - data.creditCards.forEach((cc) => delete cc.cardNumber && delete cc.cardSecurityCode) - this.#data = data - } - get hasLocalCredentials () { - return this.#data.credentials.length > 0 - } - getLocalCredentials () { - return this.#data.credentials.map(cred => delete cred.password && cred) - } - get hasLocalIdentities () { - return this.#data.identities.length > 0 - } - getLocalIdentities () { - return this.#data.identities - } - get hasLocalCreditCards () { - return this.#data.creditCards.length > 0 - } - getLocalCreditCards () { - return this.#data.creditCards - } - - init () { - this.attachTooltip = attachTooltip.bind(this) - const start = () => { - this.addDeviceListeners() - this.setupAutofill() - } - if (document.readyState === 'complete') { - start() - } else { - window.addEventListener('load', start) - } - } - setupAutofill () {} - getAddresses () {} - refreshAlias () {} - async trySigningIn () { - if (isDDGDomain()) { - if (attempts < 10) { - attempts++ - const data = await sendAndWaitForAnswer(SIGN_IN_MSG, 'addUserData') - // This call doesn't send a response, so we can't know if it succeeded - this.storeUserData(data) - this.setupAutofill({shouldLog: true}) - } else { - console.warn('max attempts reached, bailing') - } - } - } - storeUserData () {} - addDeviceListeners () {} - addLogoutListener () {} - attachTooltip () {} - isDeviceSignedIn () {} - getAlias () {} - // PM endpoints - storeCredentials () {} - getAccounts () {} - getAutofillCredentials () {} - openManagePasswords () {} -} - -class ExtensionInterface extends InterfacePrototype { - constructor () { - super() - - this.isDeviceSignedIn = () => this.hasLocalAddresses - - this.setupAutofill = ({shouldLog} = {shouldLog: false}) => { - this.getAddresses().then(addresses => { - if (this.hasLocalAddresses) { - notifyWebApp({ deviceSignedIn: {value: true, shouldLog} }) - scanForInputs(this) - } else { - this.trySigningIn() - } - }) - } - - this.getAddresses = () => new Promise(resolve => chrome.runtime.sendMessage( - {getAddresses: true}, - (data) => { - this.storeLocalAddresses(data) - return resolve(data) - } - )) - - this.refreshAlias = () => chrome.runtime.sendMessage( - {refreshAlias: true}, - (addresses) => this.storeLocalAddresses(addresses) - ) - - this.trySigningIn = () => { - if (isDDGDomain()) { - sendAndWaitForAnswer(SIGN_IN_MSG, 'addUserData') - .then(data => this.storeUserData(data)) - } - } - - this.storeUserData = (data) => chrome.runtime.sendMessage(data) - - this.addDeviceListeners = () => { - // Add contextual menu listeners - let activeEl = null - document.addEventListener('contextmenu', e => { - activeEl = e.target - }) - - chrome.runtime.onMessage.addListener((message, sender) => { - if (sender.id !== chrome.runtime.id) return - - switch (message.type) { - case 'ddgUserReady': - this.setupAutofill({shouldLog: true}) - break - case 'contextualAutofill': - setValue(activeEl, formatAddress(message.alias)) - activeEl.classList.add('ddg-autofilled') - this.refreshAlias() - - // If the user changes the alias, remove the decoration - activeEl.addEventListener( - 'input', - (e) => e.target.classList.remove('ddg-autofilled'), - {once: true} - ) - break - default: - break - } - }) - } - - this.addLogoutListener = (handler) => { - // Cleanup on logout events - chrome.runtime.onMessage.addListener((message, sender) => { - if (sender.id === chrome.runtime.id && message.type === 'logout') { - handler() - } - }) - } - } -} - -class AndroidInterface extends InterfacePrototype { - constructor () { - super() - - this.getAlias = () => sendAndWaitForAnswer(() => - window.EmailInterface.showTooltip(), 'getAliasResponse') - .then(({alias}) => alias) - - this.isDeviceSignedIn = () => { - // isDeviceSignedIn is only available on DDG domains... - if (isDDGDomain()) return window.EmailInterface.isSignedIn() === 'true' - - // ...on other domains we assume true because the script wouldn't exist otherwise - return true - } - - this.setupAutofill = ({shouldLog} = {shouldLog: false}) => { - if (this.isDeviceSignedIn()) { - notifyWebApp({ deviceSignedIn: {value: true, shouldLog} }) - scanForInputs(this) - } else { - this.trySigningIn() - } - } - - this.storeUserData = ({addUserData: {token, userName, cohort}}) => - window.EmailInterface.storeCredentials(token, userName, cohort) - } -} - -class AppleDeviceInterface extends InterfacePrototype { - constructor () { - super() - - this.setupAutofill = async ({shouldLog} = {shouldLog: false}) => { - if (isDDGDomain()) { - // Tell the web app whether we're in the app - notifyWebApp({isApp}) - } - - if (isApp) { - await this.getAutofillInitData() - } - - const signedIn = await this._checkDeviceSignedIn() - if (signedIn) { - if (isApp) { - await this.getAddresses() - } - notifyWebApp({ deviceSignedIn: {value: true, shouldLog} }) - forms.forEach(form => form.redecorateAllInputs()) - } else { - this.trySigningIn() - } - - scanForInputs(this) - } - - this.getAddresses = async () => { - if (!isApp) return this.getAlias() - - const {addresses} = await wkSendAndWait('emailHandlerGetAddresses') - this.storeLocalAddresses(addresses) - return addresses - } - - this.getAlias = async () => { - const {alias} = await wkSendAndWait( - 'emailHandlerGetAlias', - { - requiresUserPermission: !isApp, - shouldConsumeAliasIfProvided: !isApp - } - ) - return formatAddress(alias) - } - - this.refreshAlias = () => wkSend('emailHandlerRefreshAlias') - - this._checkDeviceSignedIn = async () => { - const {isAppSignedIn} = await wkSendAndWait('emailHandlerCheckAppSignedInStatus') - this.isDeviceSignedIn = () => !!isAppSignedIn - return !!isAppSignedIn - } - - this.storeUserData = ({addUserData: {token, userName, cohort}}) => - wkSend('emailHandlerStoreToken', { token, username: userName, cohort }) - - /** - * PM endpoints - */ - - /** - * Sends credentials to the native layer - * @param {{username: String, password: String}} credentials - */ - this.storeCredentials = (credentials) => - wkSend('pmHandlerStoreCredentials', credentials) - - /** - * Gets the init data from the device - * @returns {APIResponse} - */ - this.getAutofillInitData = () => - wkSendAndWait('pmHandlerGetAutofillInitData') - .then((response) => { - this.storeLocalData(response.success) - return response - }) - - /** - * Gets credentials ready for autofill - * @param {Number} id - the credential id - * @returns {APIResponse} - */ - this.getAutofillCredentials = (id) => - wkSendAndWait('pmHandlerGetAutofillCredentials', { id }) - - /** - * Opens the native UI for managing passwords - */ - this.openManagePasswords = () => wkSend('pmHandlerOpenManagePasswords') - - /** - * Opens the native UI for managing identities - */ - this.openManageIdentities = () => wkSend('pmHandlerOpenManageIdentities') - - /** - * Opens the native UI for managing credit cards - */ - this.openManageCreditCards = () => wkSend('pmHandlerOpenManageCreditCards') - - /** - * Gets a single identity obj once the user requests it - * @param {Number} id - * @returns {APIResponse} - */ - this.getAutofillIdentity = (id) => - wkSendAndWait('pmHandlerGetIdentity', { id }) - - /** - * Gets a single complete credit card obj once the user requests it - * @param {Number} id - * @returns {APIResponse} - */ - this.getAutofillCreditCard = (id) => - wkSendAndWait('pmHandlerGetCreditCard', { id }) - } -} +const AndroidInterface = require('./DeviceInterface/AndroidInterface') +const ExtensionInterface = require('./DeviceInterface/ExtensionInterface') +const AppleDeviceInterface = require('./DeviceInterface/AppleDeviceInterface') -const DeviceInterface = (() => { +// Exports a device interface instance +const deviceInterface = (() => { if (isDDGApp) { return isAndroid ? new AndroidInterface() : new AppleDeviceInterface() } return new ExtensionInterface() })() -module.exports = DeviceInterface +module.exports = deviceInterface diff --git a/src/DeviceInterface/AndroidInterface.js b/src/DeviceInterface/AndroidInterface.js new file mode 100644 index 000000000..36f389cd8 --- /dev/null +++ b/src/DeviceInterface/AndroidInterface.js @@ -0,0 +1,45 @@ +const InterfacePrototype = require('./InterfacePrototype.js') +const { + isDDGDomain, sendAndWaitForAnswer +} = require('../autofill-utils') +const {scanForInputs} = require('../scanForInputs.js') + +class AndroidInterface extends InterfacePrototype { + async getAlias () { + const { alias } = await sendAndWaitForAnswer(() => { + return window.EmailInterface.showTooltip() + }, 'getAliasResponse') + return alias + } + + isDeviceSignedIn () { + // isDeviceSignedIn is only available on DDG domains... + if (isDDGDomain()) return window.EmailInterface.isSignedIn() === 'true' + + // ...on other domains we assume true because the script wouldn't exist otherwise + return true + } + + async setupAutofill () { + if (this.isDeviceSignedIn()) { + const cleanup = scanForInputs(this).init() + this.addLogoutListener(cleanup) + } + } + + getUserData () { + let userData = null + + try { + userData = JSON.parse(window.EmailInterface.getUserData()) + } catch (e) {} + + return Promise.resolve(userData) + } + + storeUserData ({addUserData: {token, userName, cohort}}) { + return window.EmailInterface.storeCredentials(token, userName, cohort) + } +} + +module.exports = AndroidInterface diff --git a/src/DeviceInterface/AppleDeviceInterface.js b/src/DeviceInterface/AppleDeviceInterface.js new file mode 100644 index 000000000..a0b1996b2 --- /dev/null +++ b/src/DeviceInterface/AppleDeviceInterface.js @@ -0,0 +1,309 @@ +const InterfacePrototype = require('./InterfacePrototype.js') +const {wkSend, wkSendAndWait} = require('../appleDeviceUtils/appleDeviceUtils') +const { + isApp, + isTopFrame, + supportsTopFrame, + formatDuckAddress, + autofillEnabled +} = require('../autofill-utils') +const {scanForInputs, forms} = require('../scanForInputs.js') +const {processConfig} = require('@duckduckgo/content-scope-scripts/src/apple-utils') + +/** + * @implements {FeatureToggles} + */ +class AppleDeviceInterface extends InterfacePrototype { + /** @type {FeatureToggleNames[]} */ + #supportedFeatures = ['password.generation']; + + /* @type {Timeout | undefined} */ + pollingTimeout + + async isEnabled () { + return autofillEnabled(processConfig) + } + + constructor () { + super() + if (isTopFrame) { + this.stripCredentials = false + window.addEventListener('mouseMove', this) + } else { + // This is always added as a child frame needs to be informed of a parent frame scroll + window.addEventListener('scroll', this) + } + } + + postInit () { + if (!isTopFrame) return + this.setupTopFrame() + } + + async setupTopFrame () { + const topContextData = this.getTopContextData() + if (!topContextData) throw new Error('unreachable, topContextData should be available') + // Provide dummy values, they're not used + const getPosition = () => { + return { + x: 0, + y: 0, + height: 50, + width: 50 + } + } + const tooltip = this.createTooltip(getPosition, topContextData) + + this.setActiveTooltip(tooltip) + } + + /** + * Poll the native listener until the user has selected a credential. + * Message return types are: + * - 'stop' is returned whenever the message sent doesn't match the native last opened tooltip. + * - This also is triggered when the close event is called and prevents any edge case continued polling. + * - 'ok' is when the user has selected a credential and the value can be injected into the page. + * - 'none' is when the tooltip is open in the native window however hasn't been entered. + * @returns {Promise} + */ + async listenForSelectedCredential () { + // Prevent two timeouts from happening + clearTimeout(this.pollingTimeout) + + const response = await wkSendAndWait('getSelectedCredentials') + switch (response.type) { + case 'none': + // Parent hasn't got a selected credential yet + this.pollingTimeout = setTimeout(() => { + this.listenForSelectedCredential() + }, 100) + return + case 'ok': + return this.activeFormSelectedDetail(response.data, response.configType) + case 'stop': + // Parent wants us to stop polling + + break + } + } + + handleEvent (event) { + switch (event.type) { + case 'mouseMove': + this.processMouseMove(event) + break + case 'scroll': + this.removeTooltip() + break + default: + super.handleEvent(event) + } + } + + processMouseMove (event) { + this.currentTooltip?.focus(event.detail.x, event.detail.y) + } + + async setupAutofill () { + if (isApp) { + await this.getAutofillInitData() + } + + const signedIn = await this._checkDeviceSignedIn() + if (signedIn) { + if (isApp) { + await this.getAddresses() + } + forms.forEach(form => form.redecorateAllInputs()) + } + + const cleanup = scanForInputs(this).init() + this.addLogoutListener(cleanup) + } + + getUserData () { + return wkSendAndWait('emailHandlerGetUserData') + } + + async getAddresses () { + if (!isApp) return this.getAlias() + + const {addresses} = await wkSendAndWait('emailHandlerGetAddresses') + this.storeLocalAddresses(addresses) + return addresses + } + + async refreshAlias () { + await wkSendAndWait('emailHandlerRefreshAlias') + // On macOS we also update the addresses stored locally + if (isApp) this.getAddresses() + } + + async _checkDeviceSignedIn () { + const {isAppSignedIn} = await wkSendAndWait('emailHandlerCheckAppSignedInStatus') + this.isDeviceSignedIn = () => !!isAppSignedIn + return !!isAppSignedIn + } + + async setSize (details) { + await wkSend('setSize', details) + } + + /** + * @param {import("../Form/Form").Form} form + * @param {HTMLInputElement} input + * @param {() => { x: number; y: number; height: number; width: number; }} getPosition + * @param {{ x: number; y: number; }} click + * @param {TopContextData} topContextData + */ + attachTooltipInner (form, input, getPosition, click, topContextData) { + if (!isTopFrame && supportsTopFrame) { + // TODO currently only mouse initiated events are supported + if (!click) { + return + } + this.showTopTooltip(click, getPosition(), topContextData) + return + } + super.attachTooltipInner(form, input, getPosition, click, topContextData) + } + + /** + * @param {{ x: number; y: number; }} click + * @param {{ x: number; y: number; height: number; width: number; }} inputDimensions + * @param {TopContextData} [data] + */ + async showTopTooltip (click, inputDimensions, data) { + let diffX = Math.floor(click.x - inputDimensions.x) + let diffY = Math.floor(click.y - inputDimensions.y) + + const details = { + inputTop: diffY, + inputLeft: diffX, + inputHeight: Math.floor(inputDimensions.height), + inputWidth: Math.floor(inputDimensions.width), + serializedInputContext: JSON.stringify(data) + } + + await wkSend('showAutofillParent', details) + + // Start listening for the user initiated credential + this.listenForSelectedCredential() + } + + async removeTooltip () { + if (!supportsTopFrame) return super.removeTooltip() + await wkSend('closeAutofillParent', {}) + } + + storeUserData ({addUserData: {token, userName, cohort}}) { + return wkSend('emailHandlerStoreToken', { token, username: userName, cohort }) + } + + /** + * PM endpoints + */ + + /** + * Sends credentials to the native layer + * @param {{username: string, password: string}} credentials + */ + storeCredentials (credentials) { + return wkSend('pmHandlerStoreCredentials', credentials) + } + + /** + * Gets the init data from the device + * @returns {APIResponse} + */ + async getAutofillInitData () { + const response = await wkSendAndWait('pmHandlerGetAutofillInitData') + this.storeLocalData(response.success) + return response + } + + /** + * Gets credentials ready for autofill + * @param {Number} id - the credential id + * @returns {APIResponse} + */ + getAutofillCredentials (id) { + return wkSendAndWait('pmHandlerGetAutofillCredentials', { id }) + } + + /** + * Opens the native UI for managing passwords + */ + openManagePasswords () { + return wkSend('pmHandlerOpenManagePasswords') + } + + /** + * Opens the native UI for managing identities + */ + openManageIdentities () { + return wkSend('pmHandlerOpenManageIdentities') + } + + /** + * Opens the native UI for managing credit cards + */ + openManageCreditCards () { + return wkSend('pmHandlerOpenManageCreditCards') + } + + /** + * Gets a single identity obj once the user requests it + * @param {Number} id + * @returns {Promise<{success: IdentityObject|undefined}>} + */ + getAutofillIdentity (id) { + const identity = this.getLocalIdentities().find(({id: identityId}) => `${identityId}` === `${id}`) + return Promise.resolve({success: identity}) + } + + /** + * Gets a single complete credit card obj once the user requests it + * @param {Number} id + * @returns {APIResponse} + */ + getAutofillCreditCard (id) { + return wkSendAndWait('pmHandlerGetCreditCard', { id }) + } + + // Used to encode data to send back to the child autofill + async selectedDetail (detailIn, configType) { + if (isTopFrame) { + let detailsEntries = Object.entries(detailIn).map(([key, value]) => { + return [key, String(value)] + }) + const data = Object.fromEntries(detailsEntries) + wkSend('selectedDetail', { data, configType }) + } else { + this.activeFormSelectedDetail(detailIn, configType) + } + } + + async getCurrentInputType () { + const {inputType} = this.getTopContextData() || {} + return inputType + } + + async getAlias () { + const {alias} = await wkSendAndWait( + 'emailHandlerGetAlias', + { + requiresUserPermission: !isApp, + shouldConsumeAliasIfProvided: !isApp + } + ) + return formatDuckAddress(alias) + } + + /** @param {FeatureToggleNames} name */ + supportsFeature (name) { + return this.#supportedFeatures.includes(name) + } +} + +module.exports = AppleDeviceInterface diff --git a/src/DeviceInterface/ExtensionInterface.js b/src/DeviceInterface/ExtensionInterface.js new file mode 100644 index 000000000..600aaf1b4 --- /dev/null +++ b/src/DeviceInterface/ExtensionInterface.js @@ -0,0 +1,123 @@ +const InterfacePrototype = require('./InterfacePrototype.js') +const { + SIGN_IN_MSG, + isDDGDomain, + sendAndWaitForAnswer, setValue, + formatDuckAddress, + autofillEnabled +} = require('../autofill-utils') +const {scanForInputs} = require('../scanForInputs.js') + +class ExtensionInterface extends InterfacePrototype { + async isEnabled () { + if (!autofillEnabled()) return false + return new Promise(resolve => { + // Check if the site is marked to skip autofill + chrome.runtime.sendMessage( + { + registeredTempAutofillContentScript: true, + documentUrl: window.location.href + }, + (response) => { + if (!response?.site?.brokenFeatures?.includes('autofill')) { + resolve(true) + } + resolve(false) + } + ) + }) + } + + isDeviceSignedIn () { + return this.hasLocalAddresses + } + + setupAutofill () { + return this.getAddresses().then(_addresses => { + if (this.hasLocalAddresses) { + const cleanup = scanForInputs(this).init() + this.addLogoutListener(cleanup) + } + }) + } + + getAddresses () { + return new Promise(resolve => chrome.runtime.sendMessage( + {getAddresses: true}, + (data) => { + this.storeLocalAddresses(data) + return resolve(data) + } + )) + } + + getUserData () { + return new Promise(resolve => chrome.runtime.sendMessage( + {getUserData: true}, + (data) => resolve(data) + )) + } + + refreshAlias () { + return chrome.runtime.sendMessage( + {refreshAlias: true}, + (addresses) => this.storeLocalAddresses(addresses) + ) + } + + async trySigningIn () { + if (isDDGDomain()) { + const data = await sendAndWaitForAnswer(SIGN_IN_MSG, 'addUserData') + this.storeUserData(data) + } + } + + storeUserData (data) { + return chrome.runtime.sendMessage(data) + } + + addDeviceListeners () { + // Add contextual menu listeners + let activeEl = null + document.addEventListener('contextmenu', e => { + activeEl = e.target + }) + + chrome.runtime.onMessage.addListener((message, sender) => { + if (sender.id !== chrome.runtime.id) return + + switch (message.type) { + case 'ddgUserReady': + this.setupAutofill().then(() => { + this.setupSettingsPage({shouldLog: true}) + }) + break + case 'contextualAutofill': + setValue(activeEl, formatDuckAddress(message.alias)) + activeEl.classList.add('ddg-autofilled') + this.refreshAlias() + + // If the user changes the alias, remove the decoration + activeEl.addEventListener( + 'input', + (e) => e.target.classList.remove('ddg-autofilled'), + {once: true} + ) + break + default: + break + } + }) + } + + addLogoutListener (handler) { + // Cleanup on logout events + chrome.runtime.onMessage.addListener((message, sender) => { + if (sender.id === chrome.runtime.id && message.type === 'logout') { + handler() + } + }) + } +} + +module.exports = ExtensionInterface diff --git a/src/DeviceInterface/InterfacePrototype.js b/src/DeviceInterface/InterfacePrototype.js new file mode 100644 index 000000000..bc401e3b4 --- /dev/null +++ b/src/DeviceInterface/InterfacePrototype.js @@ -0,0 +1,527 @@ +const { + ADDRESS_DOMAIN, + SIGN_IN_MSG, + isApp, + isMobileApp, + isDDGDomain, + sendAndWaitForAnswer, + formatDuckAddress, + autofillEnabled, + notifyWebApp +} = require('../autofill-utils') +const {getInputType, getSubtypeFromType} = require('../Form/matching') +const { + formatFullName +} = require('../Form/formatters') +const EmailAutofill = require('../UI/EmailAutofill') +const DataAutofill = require('../UI/DataAutofill') +const {getInputConfigFromType} = require('../Form/inputTypeConfig') +const listenForGlobalFormSubmission = require('../Form/listenForFormSubmission') +const {forms} = require('../scanForInputs') +const {fromPassword, GENERATED_ID} = require('../InputTypes/Credentials') +const {PasswordGenerator} = require('../PasswordGenerator') + +// This may get replaced by a test script +let isDDGTestMode = false + +/** + * @implements {FeatureToggles} + */ +class InterfacePrototype { + mode = isDDGTestMode ? 'test' : 'production'; + attempts = 0 + /** @type {import("../Form/Form").Form | null} */ + currentAttached = null + /** @type {import("../UI/Tooltip") | null} */ + currentTooltip = null + stripCredentials = true + + /** @type {PasswordGenerator} */ + passwordGenerator = new PasswordGenerator(); + + /** @type {{privateAddress: string, personalAddress: string}} */ + #addresses = { + privateAddress: '', + personalAddress: '' + } + get hasLocalAddresses () { + return !!(this.#addresses?.privateAddress && this.#addresses?.personalAddress) + } + getLocalAddresses () { + return this.#addresses + } + storeLocalAddresses (addresses) { + this.#addresses = addresses + // When we get new duck addresses, add them to the identities list + const identities = this.getLocalIdentities() + const privateAddressIdentity = identities.find(({id}) => id === 'privateAddress') + // If we had previously stored them, just update the private address + if (privateAddressIdentity) { + privateAddressIdentity.emailAddress = formatDuckAddress(addresses.privateAddress) + } else { + // Otherwise, add both addresses + this.#data.identities = this.addDuckAddressesToIdentities(identities) + } + } + + /** @type { PMData } */ + #data = { + credentials: [], + creditCards: [], + identities: [], + topContextData: undefined + } + + /** + * @returns {Promise} + */ + async getCurrentInputType () { + throw new Error('Not implemented') + } + + addDuckAddressesToIdentities (identities) { + if (!this.hasLocalAddresses) return identities + + const newIdentities = [] + let { privateAddress, personalAddress } = this.getLocalAddresses() + privateAddress = formatDuckAddress(privateAddress) + personalAddress = formatDuckAddress(personalAddress) + + // Get the duck addresses in identities + const duckEmailsInIdentities = identities.reduce( + (duckEmails, { emailAddress: email }) => + email.includes(ADDRESS_DOMAIN) ? duckEmails.concat(email) : duckEmails, + [] + ) + + // Only add the personal duck address to identities if the user hasn't + // already manually added it + if (!duckEmailsInIdentities.includes(personalAddress)) { + newIdentities.push({ + id: 'personalAddress', + emailAddress: personalAddress, + title: 'Blocks Email Trackers' + }) + } + + newIdentities.push({ + id: 'privateAddress', + emailAddress: privateAddress, + title: 'Blocks Email Trackers and hides Your Address' + }) + + return [...identities, ...newIdentities] + } + + /** + * Stores init data coming from the device + * @param { InboundPMData } data + */ + storeLocalData (data) { + if (this.stripCredentials) { + data.credentials.forEach((cred) => delete cred.password) + data.creditCards.forEach((cc) => delete cc.cardNumber && delete cc.cardSecurityCode) + } + // Store the full name as a separate field to simplify autocomplete + const updatedIdentities = data.identities.map((identity) => ({ + ...identity, + fullName: formatFullName(identity) + })) + // Add addresses + this.#data.identities = this.addDuckAddressesToIdentities(updatedIdentities) + this.#data.creditCards = data.creditCards + this.#data.credentials = data.credentials + + // Top autofill only + if (data.serializedInputContext) { + try { + this.#data.topContextData = JSON.parse(data.serializedInputContext) + } catch (e) { + console.error(e) + this.removeTooltip() + } + } + } + getTopContextData () { + return this.#data.topContextData + } + get hasLocalCredentials () { + return this.#data.credentials.length > 0 + } + getLocalCredentials () { + return this.#data.credentials.map(cred => { + const { password, ...rest } = cred + return rest + }) + } + get hasLocalIdentities () { + return this.#data.identities.length > 0 + } + getLocalIdentities () { + return this.#data.identities + } + get hasLocalCreditCards () { + return this.#data.creditCards.length > 0 + } + /** @return {CreditCardObject[]} */ + getLocalCreditCards () { + return this.#data.creditCards + } + + async startInit () { + window.addEventListener('pointerdown', this, true) + + listenForGlobalFormSubmission() + this.addDeviceListeners() + await this.setupAutofill() + await this.setupSettingsPage() + this.postInit() + } + + postInit () {} + + async isEnabled () { + return autofillEnabled() + } + + async init () { + const isEnabled = await this.isEnabled() + if (!isEnabled) return + if (document.readyState === 'complete') { + this.startInit() + } else { + window.addEventListener('load', () => { + this.startInit() + }) + } + } + + // Global listener for event delegation + pointerDownListener (e) { + if (!e.isTrusted) return + + // @ts-ignore + if (e.target.nodeName === 'DDG-AUTOFILL') { + e.preventDefault() + e.stopImmediatePropagation() + + const activeTooltip = this.getActiveTooltip() + activeTooltip?.dispatchClick() + } else { + this.removeTooltip() + } + + if (!isApp) return + + // Check for clicks on submit buttons + const matchingForm = [...forms.values()].find( + (form) => { + const btns = [...form.submitButtons] + // @ts-ignore + if (btns.includes(e.target)) return true + + // @ts-ignore + if (btns.find((btn) => btn.contains(e.target))) return true + } + ) + matchingForm?.submitHandler() + } + + /** + * @param {IdentityObject|CreditCardObject|CredentialsObject|{email:string, id: string}} data + * @param {string} type + */ + async selectedDetail (data, type) { + this.activeFormSelectedDetail(data, type) + } + + /** + * @param {IdentityObject|CreditCardObject|CredentialsObject|{email:string, id: string}} data + * @param {string} type + */ + activeFormSelectedDetail (data, type) { + const form = this.currentAttached + if (!form) { + return + } + if (data.id === 'privateAddress') { + this.refreshAlias() + } + if (type === 'email' && 'email' in data) { + form.autofillEmail(data.email) + } else { + form.autofillData(data, type) + } + this.removeTooltip() + } + + /** + * @param {()=>void} getPosition + * @param {TopContextData} topContextData + */ + createTooltip (getPosition, topContextData) { + const config = getInputConfigFromType(topContextData.inputType) + + // Attach close listeners + window.addEventListener('input', () => this.removeTooltip(), {once: true}) + + if (isApp) { + // collect the data for each item to display + const data = this.dataForAutofill(config, topContextData.inputType, topContextData) + + // convert the data into tool tip item renderers + const asRenderers = data.map(d => config.tooltipItem(d)) + + // construct the autofill + return new DataAutofill(config, topContextData.inputType, getPosition, this) + .render(config, asRenderers, { + onSelect: (id) => this.onSelect(config, data, id) + }) + } else { + return new EmailAutofill(config, topContextData.inputType, getPosition, this) + } + } + + /** + * Before the DataAutofill opens, we collect the data based on the config.type + * @param {InputTypeConfigs} config + * @param {import('../Form/matching').SupportedTypes} inputType + * @param {TopContextData} [data] + * @returns {(CredentialsObject|CreditCardObject|IdentityObject)[]} + */ + dataForAutofill (config, inputType, data) { + const subtype = getSubtypeFromType(inputType) + if (config.type === 'identities') { + return this.getLocalIdentities().filter(identity => !!identity[subtype]) + } + if (config.type === 'creditCard') { + return this.getLocalCreditCards() + } + if (config.type === 'credentials') { + if (data) { + if (Array.isArray(data.credentials) && data.credentials.length > 0) { + return data.credentials + } else { + return this.getLocalCredentials() + } + } + } + return [] + } + + /** + * @param {import("../Form/Form").Form} form + * @param {HTMLInputElement} input + * @param {{ (): { x: number; y: number; height: number; width: number; }; (): void; }} getPosition + * @param {{ x: number; y: number; }} click + */ + attachTooltip (form, input, getPosition, click) { + form.activeInput = input + this.currentAttached = form + const inputType = getInputType(input) + + if (isMobileApp) { + this.getAlias().then((alias) => { + if (alias) form.autofillEmail(alias) + else form.activeInput?.focus() + }) + return + } + + /** @type {TopContextData} */ + const topContextData = { + inputType + } + + // A list of checks to determine if we need to generate a password + const checks = [ + inputType === 'credentials.password', + this.supportsFeature('password.generation'), + form.isSignup + ] + + // if all checks pass, generate and save a password + if (checks.every(Boolean)) { + const password = this.passwordGenerator.generate({ + input: input.getAttribute('passwordrules'), + domain: window.location.hostname + }) + + // append the new credential to the topContextData so that the top autofill can display it + topContextData.credentials = [fromPassword(password)] + } + + this.attachTooltipInner(form, input, getPosition, click, topContextData) + } + + /** + * If the device was capable of generating password, and it + * previously did so for the form in question, then offer to + * save the credentials + * + * @param {{ formElement?: HTMLFormElement; }} options + */ + shouldPromptToStoreCredentials (options) { + if (!options.formElement) return false + if (!this.supportsFeature('password.generation')) return false + + // if we previously generated a password, allow it to be saved + if (this.passwordGenerator.generated) { + return true + } + + return false + } + + /** + * When an item was selected, we then call back to the device + * to fetch the full suite of data needed to complete the autofill + * + * @param {InputTypeConfigs} config + * @param {(CreditCardObject|IdentityObject|CredentialsObject)[]} items + * @param {string|number} id + */ + onSelect (config, items, id) { + id = String(id) + const matchingData = items.find(item => String(item.id) === id) + if (!matchingData) throw new Error('unreachable (fatal)') + + const dataPromise = (() => { + switch (config.type) { + case 'creditCard': return this.getAutofillCreditCard(id) + case 'identities': return this.getAutofillIdentity(id) + case 'credentials': { + if (id === GENERATED_ID) { + return Promise.resolve({ success: matchingData }) + } + return this.getAutofillCredentials(id) + } + default: throw new Error('unreachable!') + } + })() + + // wait for the data back from the device + dataPromise.then(response => { + if (response.success) { + return this.selectedDetail(response.success, config.type) + } else { + return Promise.reject(new Error('none-success response')) + } + }).catch(e => { + console.error(e) + return this.removeTooltip() + }) + } + + /** + * @param {import("../Form/Form").Form} form + * @param {any} input + * @param {{ (): { x: number; y: number; height: number; width: number; }; (): void; }} getPosition + * @param {{ x: number; y: number; }} _click + * @param {TopContextData} data + */ + attachTooltipInner (form, input, getPosition, _click, data) { + if (this.currentTooltip) return + this.currentTooltip = this.createTooltip(getPosition, data) + form.showingTooltip(input) + } + + async removeTooltip () { + if (this.currentTooltip) { + this.currentTooltip.remove() + this.currentTooltip = null + this.currentAttached = null + } + } + + getActiveTooltip () { + return this.currentTooltip + } + + setActiveTooltip (tooltip) { + this.currentTooltip = tooltip + } + handleEvent (event) { + switch (event.type) { + case 'pointerdown': + this.pointerDownListener(event) + break + } + } + + async setupSettingsPage ({shouldLog} = {shouldLog: false}) { + if (isDDGDomain()) { + notifyWebApp({isApp}) + + if (this.isDeviceSignedIn()) { + let userData + try { + userData = await this.getUserData() + } catch (e) {} + + const hasUserData = userData && !userData.error && Object.entries(userData).length > 0 + notifyWebApp({ + deviceSignedIn: { + value: true, + shouldLog, + userData: hasUserData ? userData : undefined + } + }) + } else { + this.trySigningIn() + } + } + } + + async setupAutofill () {} + getAddresses () {} + /** + * @returns {Promise>} + */ + getUserData () { return Promise.resolve(null) } + refreshAlias () {} + async trySigningIn () { + if (isDDGDomain()) { + if (this.attempts < 10) { + this.attempts++ + const data = await sendAndWaitForAnswer(SIGN_IN_MSG, 'addUserData') + // This call doesn't send a response, so we can't know if it succeeded + this.storeUserData(data) + await this.setupAutofill() + await this.setupSettingsPage({shouldLog: true}) + } else { + console.warn('max attempts reached, bailing') + } + } + } + storeUserData (_data) {} + + addDeviceListeners () {} + /** @param {() => void} _fn */ + addLogoutListener (_fn) {} + isDeviceSignedIn () { return false } + /** + * @returns {Promise} + */ + async getAlias () { + return null + } + // PM endpoints + storeCredentials (_opts) {} + getAccounts () {} + /** @returns {APIResponse} */ + getAutofillCredentials (_id) { throw new Error('unimplemented') } + /** @returns {APIResponse} */ + async getAutofillCreditCard (_id) { throw new Error('unimplemented') } + /** @returns {Promise<{success: IdentityObject|undefined}>} */ + async getAutofillIdentity (_id) { throw new Error('unimplemented') } + + openManagePasswords () {} + + /** @param {FeatureToggleNames} _name */ + supportsFeature (_name) { + return false + } +} + +module.exports = InterfacePrototype diff --git a/src/Form/Form.js b/src/Form/Form.js index b2be02b0d..477a88bc6 100644 --- a/src/Form/Form.js +++ b/src/Form/Form.js @@ -1,138 +1,185 @@ const FormAnalyzer = require('./FormAnalyzer') -const {SUBMIT_BUTTON_SELECTOR, FIELD_SELECTOR} = require('./selectors') -const {addInlineStyles, removeInlineStyles, setValue, isEventWithinDax, isMobileApp} = require('../autofill-utils') -const {getInputSubtype, setInputType, getInputMainType, - formatCCYear, getUnifiedExpiryDate} = require('./input-classifiers') +const {addInlineStyles, removeInlineStyles, setValue, isEventWithinDax, isMobileApp, isApp, getDaxBoundingBox} = require('../autofill-utils') +const {getInputSubtype, getInputMainType} = require('./matching') const {getIconStylesAutofilled, getIconStylesBase} = require('./inputStyles') const {ATTR_AUTOFILL} = require('../constants') -const getInputConfig = require('./inputTypeConfig.js') +const {getInputConfig} = require('./inputTypeConfig.js') +const {getUnifiedExpiryDate, formatCCYear, getCountryName} = require('./formatters') +const {Matching} = require('./matching') +const {matchingConfiguration} = require('./matching-configuration') class Form { - constructor (form, input, DeviceInterface) { + /** @type {import("./matching").Matching} */ + matching; + /** @type {HTMLFormElement} */ + form; + /** @type {HTMLInputElement | null} */ + activeInput; + /** @type {boolean | null} */ + isSignup; + /** + * @param {HTMLFormElement} form + * @param {HTMLInputElement|HTMLSelectElement} input + * @param {import("../DeviceInterface/InterfacePrototype")} deviceInterface + * @param {Matching} [matching] + */ + constructor (form, input, deviceInterface, matching) { this.form = form - this.formAnalyzer = new FormAnalyzer(form, input) + this.matching = matching || new Matching(matchingConfiguration) + this.formAnalyzer = new FormAnalyzer(form, input, matching) this.isLogin = this.formAnalyzer.isLogin this.isSignup = this.formAnalyzer.isSignup - this.Device = DeviceInterface - this.attachTooltip = DeviceInterface.attachTooltip + this.device = deviceInterface - /** @type Object<'all' | SupportedMainTypes, Set> */ + /** @type Record<'all' | SupportedMainTypes, Set> */ this.inputs = { all: new Set(), - emailNew: new Set(), credentials: new Set(), creditCard: new Set(), + identities: new Set(), unknown: new Set() } this.touched = new Set() this.listeners = new Set() - this.tooltip = null this.activeInput = null + // We set this to true to skip event listeners while we're autofilling + this.isAutofilling = false this.handlerExecuted = false this.shouldPromptToStoreCredentials = true - this.submitHandler = () => { - if (this.handlerExecuted) return - - const credentials = this.getValues() - if (credentials.password) { - // ask to store credentials and/or fireproof - if (this.shouldPromptToStoreCredentials) { - this.Device.storeCredentials(credentials) - } - this.handlerExecuted = true + /** + * @type {IntersectionObserver | null} + */ + this.intObs = new IntersectionObserver((entries) => { + for (const entry of entries) { + if (!entry.isIntersecting) this.removeTooltip() } + }) + this.categorizeInputs() + } + + submitHandler () { + if (this.handlerExecuted) return + + const credentials = this.getValues() + + // do nothing if password was absent + if (!credentials.password) return + + // checks to determine if we should offer to store credentials and/or fireproof + const checks = [ + this.shouldPromptToStoreCredentials, + this.device.shouldPromptToStoreCredentials({ + formElement: this.form + }) + ] + + // if *any* of the checks are truthy, proceed to offer + if (checks.some(Boolean)) { + this.device.storeCredentials(credentials) } - this.getValues = () => { - const credentials = [...this.inputs.credentials, ...this.inputs.emailNew].reduce((output, input) => { - const subtype = getInputSubtype(input) + // mark this form as being handled + // TODO(Shane): is this correct, what happens if a failed submission is retried? + this.handlerExecuted = true + } + + getValues () { + const credentials = [...this.inputs.credentials, ...this.inputs.identities].reduce((output, input) => { + const subtype = getInputSubtype(input) + if (['username', 'password', 'emailAddress'].includes(subtype)) { output[subtype] = input.value || output[subtype] - return output - }, {username: '', password: ''}) - // If we don't have a username, let's try and save the email if available. - if (credentials.emailNew && !credentials.username) { - credentials.username = credentials.emailNew } - delete credentials.emailNew - return credentials + return output + }, {username: '', password: ''}) + // If we don't have a username, let's try and save the email if available. + if (credentials.emailAddress && !credentials.username) { + credentials.username = credentials.emailAddress } + delete credentials.emailAddress + return credentials + } + + hasValues () { + const {password} = this.getValues() + return !!password + } - this.hasValues = () => { - const {username, password} = this.getValues() - return !!(username && password) + removeTooltip () { + const tooltip = this.device.getActiveTooltip() + if ( + this.isAutofilling || + !tooltip + ) { + return } + this.device.removeTooltip() + this.intObs?.disconnect() + } - this.intObs = new IntersectionObserver((entries) => { - for (const entry of entries) { - if (!entry.isIntersecting) this.removeTooltip() - } - }) + showingTooltip (input) { + this.intObs?.observe(input) + } - this.removeTooltip = (e) => { - if ( - !this.tooltip || - (e && e.target === this.tooltip.host) - ) { - return - } - this.tooltip.remove() - this.tooltip = null - this.intObs.disconnect() - window.removeEventListener('pointerdown', this.removeTooltip, {capture: true}) - } - this.removeInputHighlight = (input) => { - removeInlineStyles(input, getIconStylesAutofilled(input)) - input.classList.remove('ddg-autofilled') - this.addAutofillStyles(input) - } - this.removeAllHighlights = (e, dataType) => { - // This ensures we are not removing the highlight ourselves when autofilling more than once - if (e && !e.isTrusted) return + removeInputHighlight (input) { + removeInlineStyles(input, getIconStylesAutofilled(input, this)) + input.classList.remove('ddg-autofilled') + this.addAutofillStyles(input) + } - // If the user has changed the value, we prompt to update the stored creds - this.shouldPromptToStoreCredentials = true + removeAllHighlights (e, dataType) { + // This ensures we are not removing the highlight ourselves when autofilling more than once + if (e && !e.isTrusted) return - this.execOnInputs(this.removeInputHighlight, dataType) - } - this.removeInputDecoration = (input) => { - removeInlineStyles(input, getIconStylesBase(input)) - input.removeAttribute(ATTR_AUTOFILL) - } - this.removeAllDecorations = () => { - this.execOnInputs(this.removeInputDecoration) - this.listeners.forEach(({el, type, fn}) => el.removeEventListener(type, fn)) - } - this.redecorateAllInputs = () => { - this.removeAllDecorations() - this.execOnInputs((input) => this.decorateInput(input)) - } - this.resetAllInputs = () => { - this.execOnInputs((input) => { - setValue(input, '') - this.removeInputHighlight(input) - }) - if (this.activeInput) this.activeInput.focus() - } - this.dismissTooltip = () => { - this.removeTooltip() - } - this.categorizeInputs() + // If the user has changed the value, we prompt to update the stored creds + this.shouldPromptToStoreCredentials = true - return this + this.execOnInputs((input) => this.removeInputHighlight(input), dataType) + } + + removeInputDecoration (input) { + removeInlineStyles(input, getIconStylesBase(input, this)) + input.removeAttribute(ATTR_AUTOFILL) + } + removeAllDecorations () { + this.execOnInputs((input) => this.removeInputDecoration(input)) + this.listeners.forEach(({el, type, fn}) => el.removeEventListener(type, fn)) + } + redecorateAllInputs () { + this.removeAllDecorations() + this.execOnInputs((input) => this.decorateInput(input)) + } + resetAllInputs () { + this.execOnInputs((input) => { + setValue(input, '') + this.removeInputHighlight(input) + }) + if (this.activeInput) this.activeInput.focus() + } + dismissTooltip () { + this.removeTooltip() + } + // This removes all listeners to avoid memory leaks and weird behaviours + destroy () { + this.removeAllDecorations() + this.removeTooltip() + this.intObs = null } categorizeInputs () { - this.form.querySelectorAll(FIELD_SELECTOR).forEach(input => this.addInput(input)) + const selector = this.matching.cssSelector('FORM_INPUTS_SELECTOR') + this.form.querySelectorAll(selector).forEach(input => this.addInput(input)) } get submitButtons () { - return [...this.form.querySelectorAll(SUBMIT_BUTTON_SELECTOR)] + const selector = this.matching.cssSelector('SUBMIT_BUTTON_SELECTOR') + return [...this.form.querySelectorAll(selector)] .filter((button) => { - const content = button.textContent - const ariaLabel = button.getAttribute('aria-label') - const title = button.title + const content = button.textContent || '' + const ariaLabel = button.getAttribute('aria-label') || '' + // @ts-ignore + const title = button.title || '' // trying to exclude the little buttons to show and hide passwords return !/password|show|toggle|reveal|hide/i.test(content + ariaLabel + title) }) @@ -142,7 +189,7 @@ class Form { const inputs = this.inputs[inputType] for (const input of inputs) { const {shouldDecorate} = getInputConfig(input) - if (shouldDecorate(this.isLogin, this.Device)) fn(input) + if (shouldDecorate(input, this)) fn(input) } } @@ -151,7 +198,7 @@ class Form { this.inputs.all.add(input) - setInputType(input, this) + this.matching.setInputType(input, this.form, { isLogin: this.isLogin }) const mainInputType = getInputMainType(input) this.inputs[mainInputType].add(input) @@ -175,20 +222,20 @@ class Form { } addAutofillStyles (input) { - const styles = getIconStylesBase(input) + const styles = getIconStylesBase(input, this) addInlineStyles(input, styles) } decorateInput (input) { const config = getInputConfig(input) - if (!config.shouldDecorate(this.isLogin, this.Device)) return this + if (!config.shouldDecorate(input, this)) return this input.setAttribute(ATTR_AUTOFILL, 'true') - const hasIcon = !!config.getIconBase() + const hasIcon = !!config.getIconBase(input, this) if (hasIcon) { - this.addAutofillStyles(input, config) + this.addAutofillStyles(input) this.addListener(input, 'mousemove', (e) => { if (isEventWithinDax(e, e.target)) { e.target.style.setProperty('cursor', 'pointer', 'important') @@ -198,81 +245,142 @@ class Form { }) } + function getMainClickCoords (e) { + if (!e.isTrusted) return + const isMainMouseButton = e.button === 0 + if (!isMainMouseButton) return + return { + x: e.clientX, + y: e.clientY + } + } + + // Store the click to a label so we can use the click when the field is focused + let storedClick = new WeakMap() + let timeout = null + const handlerLabel = (e) => { + // Look for e.target OR it's closest parent to be a HTMLLabelElement + const control = e.target.closest('label').control + if (!control) return + storedClick.set(control, getMainClickCoords(e)) + clearTimeout(timeout) + // Remove the stored click if the timer expires + timeout = setTimeout(() => { + storedClick = new WeakMap() + }, 1000) + } + const handler = (e) => { - if (this.tooltip) return + if (this.device.getActiveTooltip() || this.isAutofilling) return + + const input = e.target + let click = null + const getPosition = () => { + // In extensions, the tooltip is centered on the Dax icon + return isApp ? input.getBoundingClientRect() : getDaxBoundingBox(input) + } // Checks for mousedown event if (e.type === 'pointerdown') { - if (!e.isTrusted) return - const isMainMouseButton = e.button === 0 - if (!isMainMouseButton) return + click = getMainClickCoords(e) + if (!click) return + } else if (storedClick) { + // Reuse a previous click if one exists for this element + click = storedClick.get(input) + storedClick.delete(input) } - if (this.shouldOpenTooltip(e, e.target)) { - if (isEventWithinDax(e, e.target) || isMobileApp) { + if (this.shouldOpenTooltip(e, input)) { + if (isEventWithinDax(e, input) || isMobileApp) { e.preventDefault() e.stopImmediatePropagation() } - this.touched.add(e.target) - this.attachTooltip(this, e.target) + this.touched.add(input) + this.device.attachTooltip(this, input, getPosition, click) } } - const events = ['pointerdown'] - if (!isMobileApp) events.push('focus') - events.forEach((ev) => this.addListener(input, ev, handler, true)) + if (input.nodeName !== 'SELECT') { + const events = ['pointerdown'] + if (!isMobileApp) events.push('focus') + input.labels.forEach((label) => { + this.addListener(label, 'pointerdown', handlerLabel) + }) + events.forEach((ev) => this.addListener(input, ev, handler)) + } return this } shouldOpenTooltip (e, input) { - const inputType = getInputMainType(input) - if (inputType !== 'emailNew') return true + if (isApp) return true + const inputType = getInputMainType(input) return (!this.touched.has(input) && this.areAllInputsEmpty(inputType)) || isEventWithinDax(e, input) } - autofillInput = (input, string, dataType) => { - setValue(input, string) + autofillInput (input, string, dataType) { + // @ts-ignore + const activeInputSubtype = getInputSubtype(this.activeInput) + const inputSubtype = getInputSubtype(input) + const isEmailAutofill = activeInputSubtype === 'emailAddress' && inputSubtype === 'emailAddress' + + // Don't override values for identities, unless it's the current input or we're autofilling email + if ( + dataType === 'identities' && // only for identities + input.nodeName !== 'SELECT' && input.value !== '' && // if the input is not empty + this.activeInput !== input && // and this is not the active input + !isEmailAutofill // and we're not auto-filling email + ) return // do not overwrite the value + + const successful = setValue(input, string) + + if (!successful) return + input.classList.add('ddg-autofilled') - addInlineStyles(input, getIconStylesAutofilled(input)) + addInlineStyles(input, getIconStylesAutofilled(input, this)) - // If the user changes the alias, remove the decoration + // If the user changes the value, remove the decoration input.addEventListener('input', (e) => this.removeAllHighlights(e, dataType), {once: true}) } - autofillEmail (alias, dataType = 'emailNew') { + autofillEmail (alias, dataType = 'identities') { + this.isAutofilling = true this.execOnInputs( (input) => this.autofillInput(input, alias, dataType), dataType ) - if (this.tooltip) { - this.removeTooltip() - } + this.isAutofilling = false + this.removeTooltip() } autofillData (data, dataType) { this.shouldPromptToStoreCredentials = false + this.isAutofilling = true this.execOnInputs((input) => { const inputSubtype = getInputSubtype(input) let autofillData = data[inputSubtype] if (inputSubtype === 'expiration') { - autofillData = getUnifiedExpiryDate(input, data.expirationMonth, data.expirationYear, this.form) + autofillData = getUnifiedExpiryDate(input, data.expirationMonth, data.expirationYear, this) } if (inputSubtype === 'expirationYear' && input.nodeName === 'INPUT') { - autofillData = formatCCYear(input, autofillData, this.form) + autofillData = formatCCYear(input, autofillData, this) + } + + if (inputSubtype === 'addressCountryCode') { + autofillData = getCountryName(input, data) } if (autofillData) this.autofillInput(input, autofillData, dataType) }, dataType) - if (this.tooltip) { - this.removeTooltip() - } + this.isAutofilling = false + + this.removeTooltip() } } -module.exports = Form +module.exports.Form = Form diff --git a/src/Form/Form.test.js b/src/Form/Form.test.js new file mode 100644 index 000000000..ff1ee4754 --- /dev/null +++ b/src/Form/Form.test.js @@ -0,0 +1,96 @@ +const InterfacePrototype = require('../DeviceInterface/InterfacePrototype') + +afterEach(() => { + document.body.innerHTML = '' +}) + +describe('Test the form class reading values correctly', () => { + const testCases = [ + { + testCase: 'form with username', + form: ` +
+ + + +
` + }, + { + testCase: 'form with email', + form: ` +
+ + + +
` + }, + { + testCase: 'form with both email and username fields', + form: ` +
+ + + + +
` + }, + { + testCase: 'form with empty fields', + form: ` +
+ + + +
`, + expHasValues: false, + expValues: {username: '', password: ''} + }, + { + testCase: 'form with only the password filled', + form: ` +
+ + + +
`, + expHasValues: true, + expValues: {username: '', password: 'testPassword'} + }, + { + testCase: 'form with only the username filled', + form: ` +
+ + + +
`, + expHasValues: false, + expValues: {username: 'testUsername', password: ''} + } + ] + + test.each(testCases)('Test $testCase', ( + { + form, + expHasValues = true, + expValues = { + username: 'testUsername', + password: 'testPassword' + } + }) => { + document.body.innerHTML = form + // When we require autofill, the script scores the fields in the DOM + const {forms, scanForInputs} = require('../scanForInputs') + + scanForInputs(new InterfacePrototype()).findEligibleInputs(document) + + const formEl = document.querySelector('form') + if (!formEl) throw new Error('unreachable') + const formClass = forms.get(formEl) + const hasValues = formClass?.hasValues() + const formValues = formClass?.getValues() + + expect(hasValues).toBe(expHasValues) + expect(formValues).toMatchObject(expValues) + }) +}) diff --git a/src/Form/FormAnalyzer.js b/src/Form/FormAnalyzer.js index 305f0c27a..72bdfbb93 100644 --- a/src/Form/FormAnalyzer.js +++ b/src/Form/FormAnalyzer.js @@ -1,8 +1,20 @@ -const {PASSWORD_SELECTOR, SUBMIT_BUTTON_SELECTOR} = require('./selectors') +const {removeExcessWhitespace, Matching} = require('./matching') +const {TEXT_LENGTH_CUTOFF} = require('../constants') +const {matchingConfiguration} = require('./matching-configuration') class FormAnalyzer { - constructor (form, input) { + /** @type HTMLFormElement */ + form; + /** @type Matching */ + matching; + /** + * @param {HTMLFormElement} form + * @param {HTMLInputElement|HTMLSelectElement} input + * @param {Matching} [matching] + */ + constructor (form, input, matching) { this.form = form + this.matching = matching || new Matching(matchingConfiguration) this.autofillSignal = 0 this.signals = [] @@ -44,9 +56,9 @@ class FormAnalyzer { shouldCheckUnifiedForm = false, // Should check for login/signup forms shouldBeConservative = false // Should use the conservative signup regex }) { - const negativeRegex = new RegExp(/sign(ing)?.?in(?!g)|log.?in/i) + const negativeRegex = new RegExp(/sign(ing)?.?in(?!g)|log.?in|unsubscri/i) const positiveRegex = new RegExp( - /sign(ing)?.?up|join|regist(er|ration)|newsletter|subscri(be|ption)|contact|create|start|settings|preferences|profile|update|checkout|guest|purchase|buy|order|schedule|estimate|request/i + /sign(ing)?.?up|join|\bregist(er|ration)|newsletter|\bsubscri(be|ption)|contact|create|start|settings|preferences|profile|update|checkout|guest|purchase|buy|order|schedule|estimate|request/i ) const conservativePositiveRegex = new RegExp(/sign.?up|join|register|newsletter|subscri(be|ption)|settings|preferences|profile|update/i) const strictPositiveRegex = new RegExp(/sign.?up|join|register|settings|preferences|profile|update/i) @@ -93,11 +105,12 @@ class FormAnalyzer { evaluatePageHeadings () { const headings = document.querySelectorAll('h1, h2, h3, [class*="title"], [id*="title"]') if (headings) { - headings.forEach(({innerText}) => { + headings.forEach(({textContent}) => { + textContent = removeExcessWhitespace(textContent || '') this.updateSignal({ - string: innerText, + string: textContent, strength: 0.5, - signalType: `heading: ${innerText}`, + signalType: `heading: ${textContent}`, shouldCheckUnifiedForm: true, shouldBeConservative: true }) @@ -116,9 +129,11 @@ class FormAnalyzer { `) buttons.forEach(button => { // if the button has a form, it's not related to our input, because our input has no form here - if (!button.form && !button.closest('form')) { - this.evaluateElement(button) - this.evaluateElAttributes(button, 0.5) + if (button instanceof HTMLButtonElement) { + if (!button.form && !button.closest('form')) { + this.evaluateElement(button) + this.evaluateElAttributes(button, 0.5) + } } }) } @@ -130,18 +145,20 @@ class FormAnalyzer { getText (el) { // for buttons, we don't care about descendants, just get the whole text as is // this is important in order to give proper attribution of the text to the button - if (this.elementIs(el, 'BUTTON')) return el.innerText + if (this.elementIs(el, 'BUTTON')) return removeExcessWhitespace(el.textContent) if (this.elementIs(el, 'INPUT') && ['submit', 'button'].includes(el.type)) return el.value - return Array.from(el.childNodes).reduce((text, child) => - this.elementIs(child, '#text') ? text + ' ' + child.textContent : text, '') + return removeExcessWhitespace( + Array.from(el.childNodes).reduce((text, child) => + this.elementIs(child, '#text') ? text + ' ' + child.textContent : text, '') + ) } evaluateElement (el) { const string = this.getText(el) - if (el.matches(PASSWORD_SELECTOR)) { + if (el.matches(this.matching.cssSelector('password'))) { // These are explicit signals by the web author, so we weigh them heavily this.updateSignal({ string: el.getAttribute('autocomplete') || '', @@ -151,9 +168,13 @@ class FormAnalyzer { } // check button contents - if (el.matches(SUBMIT_BUTTON_SELECTOR)) { + if (el.matches(this.matching.cssSelector('SUBMIT_BUTTON_SELECTOR'))) { // If we're sure this is a submit button, it's a stronger signal - const strength = el.getAttribute('type') === 'submit' ? 20 : 2 + const strength = + el.getAttribute('type') === 'submit' || + /primary|submit/i.test(el.className) || + el.offsetHeight * el.offsetWidth >= 10000 + ? 20 : 2 this.updateSignal({string, strength, signalType: `submit: ${string}`}) } // if a link points to relevant urls or contain contents outside the page… @@ -166,7 +187,7 @@ class FormAnalyzer { } else { // any other case // only consider the el if it's a small text to avoid noisy disclaimers - if (el.innerText?.length < 50) { + if (removeExcessWhitespace(el.textContent)?.length < TEXT_LENGTH_CUTOFF) { this.updateSignal({string, strength: 1, signalType: `generic: ${string}`, shouldCheckUnifiedForm: true}) } } diff --git a/src/Form/InputClassifiersTypes.d.ts b/src/Form/InputClassifiersTypes.d.ts deleted file mode 100644 index 6e1611aae..000000000 --- a/src/Form/InputClassifiersTypes.d.ts +++ /dev/null @@ -1,33 +0,0 @@ -interface Matcher { - type: string, - selector: string, - regex: RegExp, - negativeRegex?: RegExp -} - -type SupportedMainTypes = - | 'emailNew' - | 'credentials' - | 'creditCard' - | 'unknown' - -type SupportedSubTypes = - | SupportedMainTypes - | 'credentials.username' - | 'credentials.password' - | 'creditCards.cardName' - | 'creditCards.cardNumber' - | 'creditCards.cardSecurityCode' - | 'creditCards.expirationMonth' - | 'creditCards.expirationYear' - | 'creditCards.expiration' - -interface InputTypeConfig { - type: SupportedMainTypes, - getIconFilled: () => string, - getIconBase: () => string, - shouldDecorate: (boolean, InterfacePrototype) => boolean, - dataType: 'Addresses' | 'Credentials' | 'CreditCards' | 'Identities' | '', - displayTitlePropName: string, - displaySubtitlePropName: string, -} diff --git a/src/Form/countryNames.js b/src/Form/countryNames.js new file mode 100644 index 000000000..af0473481 --- /dev/null +++ b/src/Form/countryNames.js @@ -0,0 +1,255 @@ +// Country names object using 2-letter country codes to reference country name +// ISO 3166 Alpha-2 Format: [2 letter Country Code]: [Country Name] +// Sorted alphabetical by country name (special characters on bottom) +// Source: https://gist.github.com/incredimike/1469814#file-variouscountrylistformats-js-L272 +module.exports = { + 'AF': 'Afghanistan', + 'AL': 'Albania', + 'DZ': 'Algeria', + 'AS': 'American Samoa', + 'AD': 'Andorra', + 'AO': 'Angola', + 'AI': 'Anguilla', + 'AQ': 'Antarctica', + 'AG': 'Antigua and Barbuda', + 'AR': 'Argentina', + 'AM': 'Armenia', + 'AW': 'Aruba', + 'AU': 'Australia', + 'AT': 'Austria', + 'AZ': 'Azerbaijan', + 'BS': 'Bahamas (the)', + 'BH': 'Bahrain', + 'BD': 'Bangladesh', + 'BB': 'Barbados', + 'BY': 'Belarus', + 'BE': 'Belgium', + 'BZ': 'Belize', + 'BJ': 'Benin', + 'BM': 'Bermuda', + 'BT': 'Bhutan', + 'BO': 'Bolivia (Plurinational State of)', + 'BQ': 'Bonaire, Sint Eustatius and Saba', + 'BA': 'Bosnia and Herzegovina', + 'BW': 'Botswana', + 'BV': 'Bouvet Island', + 'BR': 'Brazil', + 'IO': 'British Indian Ocean Territory (the)', + 'BN': 'Brunei Darussalam', + 'BG': 'Bulgaria', + 'BF': 'Burkina Faso', + 'BI': 'Burundi', + 'CV': 'Cabo Verde', + 'KH': 'Cambodia', + 'CM': 'Cameroon', + 'CA': 'Canada', + 'KY': 'Cayman Islands (the)', + 'CF': 'Central African Republic (the)', + 'TD': 'Chad', + 'CL': 'Chile', + 'CN': 'China', + 'CX': 'Christmas Island', + 'CC': 'Cocos (Keeling) Islands (the)', + 'CO': 'Colombia', + 'KM': 'Comoros (the)', + 'CD': 'Congo (the Democratic Republic of the)', + 'CG': 'Congo (the)', + 'CK': 'Cook Islands (the)', + 'CR': 'Costa Rica', + 'HR': 'Croatia', + 'CU': 'Cuba', + 'CW': 'Curaçao', + 'CY': 'Cyprus', + 'CZ': 'Czechia', + 'CI': "Côte d'Ivoire", + 'DK': 'Denmark', + 'DJ': 'Djibouti', + 'DM': 'Dominica', + 'DO': 'Dominican Republic (the)', + 'EC': 'Ecuador', + 'EG': 'Egypt', + 'SV': 'El Salvador', + 'GQ': 'Equatorial Guinea', + 'ER': 'Eritrea', + 'EE': 'Estonia', + 'SZ': 'Eswatini', + 'ET': 'Ethiopia', + 'FK': 'Falkland Islands (the) [Malvinas]', + 'FO': 'Faroe Islands (the)', + 'FJ': 'Fiji', + 'FI': 'Finland', + 'FR': 'France', + 'GF': 'French Guiana', + 'PF': 'French Polynesia', + 'TF': 'French Southern Territories (the)', + 'GA': 'Gabon', + 'GM': 'Gambia (the)', + 'GE': 'Georgia', + 'DE': 'Germany', + 'GH': 'Ghana', + 'GI': 'Gibraltar', + 'GR': 'Greece', + 'GL': 'Greenland', + 'GD': 'Grenada', + 'GP': 'Guadeloupe', + 'GU': 'Guam', + 'GT': 'Guatemala', + 'GG': 'Guernsey', + 'GN': 'Guinea', + 'GW': 'Guinea-Bissau', + 'GY': 'Guyana', + 'HT': 'Haiti', + 'HM': 'Heard Island and McDonald Islands', + 'VA': 'Holy See (the)', + 'HN': 'Honduras', + 'HK': 'Hong Kong', + 'HU': 'Hungary', + 'IS': 'Iceland', + 'IN': 'India', + 'ID': 'Indonesia', + 'IR': 'Iran (Islamic Republic of)', + 'IQ': 'Iraq', + 'IE': 'Ireland', + 'IM': 'Isle of Man', + 'IL': 'Israel', + 'IT': 'Italy', + 'JM': 'Jamaica', + 'JP': 'Japan', + 'JE': 'Jersey', + 'JO': 'Jordan', + 'KZ': 'Kazakhstan', + 'KE': 'Kenya', + 'KI': 'Kiribati', + 'KP': "Korea (the Democratic People's Republic of)", + 'KR': 'Korea (the Republic of)', + 'KW': 'Kuwait', + 'KG': 'Kyrgyzstan', + 'LA': "Lao People's Democratic Republic (the)", + 'LV': 'Latvia', + 'LB': 'Lebanon', + 'LS': 'Lesotho', + 'LR': 'Liberia', + 'LY': 'Libya', + 'LI': 'Liechtenstein', + 'LT': 'Lithuania', + 'LU': 'Luxembourg', + 'MO': 'Macao', + 'MG': 'Madagascar', + 'MW': 'Malawi', + 'MY': 'Malaysia', + 'MV': 'Maldives', + 'ML': 'Mali', + 'MT': 'Malta', + 'MH': 'Marshall Islands (the)', + 'MQ': 'Martinique', + 'MR': 'Mauritania', + 'MU': 'Mauritius', + 'YT': 'Mayotte', + 'MX': 'Mexico', + 'FM': 'Micronesia (Federated States of)', + 'MD': 'Moldova (the Republic of)', + 'MC': 'Monaco', + 'MN': 'Mongolia', + 'ME': 'Montenegro', + 'MS': 'Montserrat', + 'MA': 'Morocco', + 'MZ': 'Mozambique', + 'MM': 'Myanmar', + 'NA': 'Namibia', + 'NR': 'Nauru', + 'NP': 'Nepal', + 'NL': 'Netherlands (the)', + 'NC': 'New Caledonia', + 'NZ': 'New Zealand', + 'NI': 'Nicaragua', + 'NE': 'Niger (the)', + 'NG': 'Nigeria', + 'NU': 'Niue', + 'NF': 'Norfolk Island', + 'MP': 'Northern Mariana Islands (the)', + 'NO': 'Norway', + 'OM': 'Oman', + 'PK': 'Pakistan', + 'PW': 'Palau', + 'PS': 'Palestine, State of', + 'PA': 'Panama', + 'PG': 'Papua New Guinea', + 'PY': 'Paraguay', + 'PE': 'Peru', + 'PH': 'Philippines (the)', + 'PN': 'Pitcairn', + 'PL': 'Poland', + 'PT': 'Portugal', + 'PR': 'Puerto Rico', + 'QA': 'Qatar', + 'MK': 'Republic of North Macedonia', + 'RO': 'Romania', + 'RU': 'Russian Federation (the)', + 'RW': 'Rwanda', + 'RE': 'Réunion', + 'BL': 'Saint Barthélemy', + 'SH': 'Saint Helena, Ascension and Tristan da Cunha', + 'KN': 'Saint Kitts and Nevis', + 'LC': 'Saint Lucia', + 'MF': 'Saint Martin (French part)', + 'PM': 'Saint Pierre and Miquelon', + 'VC': 'Saint Vincent and the Grenadines', + 'WS': 'Samoa', + 'SM': 'San Marino', + 'ST': 'Sao Tome and Principe', + 'SA': 'Saudi Arabia', + 'SN': 'Senegal', + 'RS': 'Serbia', + 'SC': 'Seychelles', + 'SL': 'Sierra Leone', + 'SG': 'Singapore', + 'SX': 'Sint Maarten (Dutch part)', + 'SK': 'Slovakia', + 'SI': 'Slovenia', + 'SB': 'Solomon Islands', + 'SO': 'Somalia', + 'ZA': 'South Africa', + 'GS': 'South Georgia and the South Sandwich Islands', + 'SS': 'South Sudan', + 'ES': 'Spain', + 'LK': 'Sri Lanka', + 'SD': 'Sudan (the)', + 'SR': 'Suriname', + 'SJ': 'Svalbard and Jan Mayen', + 'SE': 'Sweden', + 'CH': 'Switzerland', + 'SY': 'Syrian Arab Republic', + 'TW': 'Taiwan', + 'TJ': 'Tajikistan', + 'TZ': 'Tanzania, United Republic of', + 'TH': 'Thailand', + 'TL': 'Timor-Leste', + 'TG': 'Togo', + 'TK': 'Tokelau', + 'TO': 'Tonga', + 'TT': 'Trinidad and Tobago', + 'TN': 'Tunisia', + 'TR': 'Turkey', + 'TM': 'Turkmenistan', + 'TC': 'Turks and Caicos Islands (the)', + 'TV': 'Tuvalu', + 'UG': 'Uganda', + 'UA': 'Ukraine', + 'AE': 'United Arab Emirates (the)', + 'GB': 'United Kingdom of Great Britain and Northern Ireland (the)', + 'UM': 'United States Minor Outlying Islands (the)', + 'US': 'United States of America (the)', + 'UY': 'Uruguay', + 'UZ': 'Uzbekistan', + 'VU': 'Vanuatu', + 'VE': 'Venezuela (Bolivarian Republic of)', + 'VN': 'Viet Nam', + 'VG': 'Virgin Islands (British)', + 'VI': 'Virgin Islands (U.S.)', + 'WF': 'Wallis and Futuna', + 'EH': 'Western Sahara', + 'YE': 'Yemen', + 'ZM': 'Zambia', + 'ZW': 'Zimbabwe', + 'AX': 'Åland Islands' +} diff --git a/src/Form/formatters.js b/src/Form/formatters.js new file mode 100644 index 000000000..b3db18caa --- /dev/null +++ b/src/Form/formatters.js @@ -0,0 +1,119 @@ +const {matchInPlaceholderAndLabels, checkPlaceholderAndLabels} = require('./matching') +const COUNTRY_NAMES = require('./countryNames') + +// Matches strings like mm/yy, mm-yyyy, mm-aa +const DATE_SEPARATOR_REGEX = /\w\w\s?(?[/\s.\-_—–])\s?\w\w/i +// Matches 4 non-digit repeated characters (YYYY or AAAA) or 4 digits (2022) +const FOUR_DIGIT_YEAR_REGEX = /(\D)\1{3}|\d{4}/i + +/** + * Format the cc year to best adapt to the input requirements (YY vs YYYY) + * @param {HTMLInputElement} input + * @param {number} year + * @param {import("./Form").Form} form + * @returns {number} + */ +const formatCCYear = (input, year, form) => { + const selector = form.matching.cssSelector('FORM_INPUTS_SELECTOR') + if ( + input.maxLength === 4 || + checkPlaceholderAndLabels(input, FOUR_DIGIT_YEAR_REGEX, form.form, selector) + ) return year + + return year - 2000 +} + +/** + * Get a unified expiry date with separator + * @param {HTMLInputElement} input + * @param {number} month + * @param {number} year + * @param {import("./Form").Form} form + * @returns {string} + */ +const getUnifiedExpiryDate = (input, month, year, form) => { + const formattedYear = formatCCYear(input, year, form) + const paddedMonth = `${month}`.padStart(2, '0') + const cssSelector = form.matching.cssSelector('FORM_INPUTS_SELECTOR') + const separator = matchInPlaceholderAndLabels(input, DATE_SEPARATOR_REGEX, form.form, cssSelector)?.groups?.separator || '/' + + return `${paddedMonth}${separator}${formattedYear}` +} + +const formatFullName = ({firstName = '', middleName = '', lastName = ''}) => + `${firstName} ${middleName ? middleName + ' ' : ''}${lastName}`.trim() + +/** + * Tries to look up a human-readable country name from the country code + * @param {string} locale + * @param {string} addressCountryCode + * @return {string} - Returns the country code if we can't find a name + */ +const getCountryDisplayName = (locale, addressCountryCode) => { + try { + const regionNames = new Intl.DisplayNames([locale], { type: 'region' }) + return regionNames.of(addressCountryCode) + } catch (e) { + return COUNTRY_NAMES[addressCountryCode] || addressCountryCode + } +} + +/** + * Tries to infer the element locale or returns 'en' + * @param {HTMLInputElement | HTMLSelectElement} el + * @return {string | 'en'} + */ +const inferElementLocale = (el) => + el.lang || el.form?.lang || document.body.lang || document.documentElement.lang || 'en' + +/** + * Tries to format the country code into a localised country name + * @param {HTMLInputElement | HTMLSelectElement} el + * @param {{addressCountryCode?: string}} options + */ +const getCountryName = (el, options = {}) => { + const {addressCountryCode} = options + if (!addressCountryCode) return '' + + // Try to infer the field language or fallback to en + const elLocale = inferElementLocale(el) + const localisedCountryName = getCountryDisplayName(elLocale, addressCountryCode) + + // If it's a select el we try to find a suitable match to autofill + if (el.nodeName === 'SELECT') { + const englishCountryName = getCountryDisplayName('en', addressCountryCode) + // This regex matches both the localised and English country names + const countryNameRegex = new RegExp(String.raw`${ + localisedCountryName.replaceAll(' ', '.?') + }|${ + englishCountryName.replaceAll(' ', '.?') + }`, 'i') + const countryCodeRegex = new RegExp(String.raw`\b${addressCountryCode}\b`, 'i') + + // We check the country code first because it's more accurate + if (el instanceof HTMLSelectElement) { + for (const option of el.options) { + if (countryCodeRegex.test(option.value)) { + return option.value + } + } + + for (const option of el.options) { + if ( + countryNameRegex.test(option.value) || + countryNameRegex.test(option.innerText) + ) return option.value + } + } + } + + return localisedCountryName +} + +module.exports = { + formatCCYear, + getUnifiedExpiryDate, + formatFullName, + getCountryDisplayName, + getCountryName +} diff --git a/src/Form/input-classifiers.js b/src/Form/input-classifiers.js deleted file mode 100644 index 2ae9d1048..000000000 --- a/src/Form/input-classifiers.js +++ /dev/null @@ -1,250 +0,0 @@ -const { - CC_FIELD_SELECTOR, DATE_SEPARATOR_REGEX, CC_MATCHERS_LIST, - PASSWORD_MATCHER, EMAIL_MATCHER, USERNAME_MATCHER, FOUR_DIGIT_YEAR_REGEX -} = require('./selectors') -const {ATTR_INPUT_TYPE} = require('../constants') - -/** - * Tests that a string matches a regex while not matching another - * @param {String} string - * @param {RegExp} regex - * @param {RegExp} negativeRegex - * @return {boolean} - */ -const testAgainstRegexes = (string = '', regex, negativeRegex) => - regex.test(string) && !negativeRegex?.test(string) - -/** - * Get text from all explicit labels - * @param {HTMLInputElement} el - * @return {String} - */ -const getExplicitLabelsText = (el) => { - const text = [...(el.labels || [])].reduce((text, label) => `${text} ${label.textContent}`, '') - const ariaLabel = el.getAttribute('aria-label') || '' - const labelledByText = document.getElementById(el.getAttribute('aria-labelled'))?.textContent || '' - return `${text} ${ariaLabel} ${labelledByText}` -} - -/** - * Get all text close to the input (useful when no labels are defined) - * @param {HTMLInputElement} el - * @param {HTMLFormElement} form - * @return {string} - */ -const getRelatedText = (el, form) => { - const container = getLargestMeaningfulContainer(el, form) - return container.textContent -} - -/** - * Find a container for the input field that won't contain other inputs (useful to get elements related to the field) - * @param {HTMLElement} el - * @param {HTMLFormElement} form - * @return {HTMLElement} - */ -const getLargestMeaningfulContainer = (el, form) => { - const parentElement = el.parentElement - if (!parentElement || el === form) return el - - const inputsInScope = parentElement.querySelectorAll('input, select, textarea') - // To avoid noise, ensure that our input is the only in scope - if (inputsInScope.length === 1) { - return getLargestMeaningfulContainer(parentElement, form) - } - return el -} - -/** - * Tries to infer input type, with checks in decreasing order of reliability - * @type (el: HTMLInputElement, form: HTMLFormElement, Matcher) => Boolean - */ -const checkMatch = (el, form, {selector, regex, negativeRegex}) => { - if (selector && el.matches(selector)) return true - - if (!regex) return false - - return testAgainstRegexes(getExplicitLabelsText(el), regex, negativeRegex) || - testAgainstRegexes(el.id, regex, negativeRegex) || - testAgainstRegexes(el.placeholder, regex, negativeRegex) || - testAgainstRegexes(getRelatedText(el, form), regex, negativeRegex) -} - -/** - * Tries to infer if input is for password - * @type (el: HTMLInputElement, form: HTMLFormElement) => Boolean - */ -const isPassword = (el, form) => - checkMatch(el, form, PASSWORD_MATCHER) - -/** - * Tries to infer if input is for email - * @type (el: HTMLInputElement, form: HTMLFormElement) => Boolean - */ -const isEmail = (el, form) => - checkMatch(el, form, EMAIL_MATCHER) - -/** - * Tries to infer if input is for username - * @type (el: HTMLInputElement, form: HTMLFormElement) => Boolean - */ -const isUserName = (el, form) => - checkMatch(el, form, USERNAME_MATCHER) - -/** - * Tries to infer if it's a credit card form - * @param {HTMLFormElement} form - * @returns {boolean} - */ -const isCCForm = (form) => { - const hasCCSelectorChild = form.querySelector(CC_FIELD_SELECTOR) - // If the form contains one of the specific selectors, we have high confidence - if (hasCCSelectorChild) return true - - // Read form attributes to find a signal - const hasCCAttribute = [...form.attributes].some(({name, value}) => - /(credit|payment).?card/i.test(`${name}=${value}`) - ) - if (hasCCAttribute) return true - - // Match form textContent against common cc fields (includes hidden labels) - const textMatches = form.textContent.match(/(credit)?card(.?number)?|ccv|security.?code|cvv|cvc|csc/ig) - - // We check for more than one to minimise false positives - return textMatches?.length > 1 -} - -/** - * Get a CC subtype based on selectors and regexes - * @param {HTMLInputElement} el - * @param {HTMLFormElement} form - * @return {string} - */ -const getCCFieldSubtype = (el, form) => - CC_MATCHERS_LIST.find((sel) => checkMatch(el, form, sel))?.type - -/** - * Tries to infer the input type - * @param {HTMLInputElement} input - * @param {Form} form - * @returns {SupportedSubTypes} - */ -const inferInputType = (input, form) => { - const presetType = input.getAttribute(ATTR_INPUT_TYPE) - if (presetType) return presetType - - const formEl = form.form - - // For CC forms we run aggressive matches, so we want to make sure we only - // run them on actual CC forms to avoid false positives and expensive loops - if (isCCForm(formEl)) { - const subtype = getCCFieldSubtype(input, formEl) - if (subtype) return `creditCard.${subtype}` - } - - if (isPassword(input, formEl)) return 'credentials.password' - - if (isEmail(input, formEl)) return form.isLogin ? 'credentials.username' : 'emailNew' - - if (isUserName(input, formEl)) return 'credentials.username' - - return 'unknown' -} - -/** - * Sets the input type as a data attribute to the element and returns it - * @param {HTMLInputElement} input - * @param {Form} form - * @returns {SupportedSubTypes} - */ -const setInputType = (input, form) => { - const type = inferInputType(input, form) - input.setAttribute(ATTR_INPUT_TYPE, type) - return type -} - -/** - * Retrieves the input main type - * @param {HTMLInputElement} input - * @returns {SupportedSubTypes} - */ -const getInputMainType = (input) => - input.getAttribute(ATTR_INPUT_TYPE)?.split('.')[0] || - 'unknown' - -/** - * Retrieves the input subtype - * @param {HTMLInputElement} input - * @returns {SupportedSubTypes} - */ -const getInputSubtype = (input) => - input.getAttribute(ATTR_INPUT_TYPE)?.split('.')[1] || - input.getAttribute(ATTR_INPUT_TYPE)?.split('.')[0] || - 'unknown' - -/** - * Find a regex match for a given input - * @param {HTMLInputElement} input - * @param {RegExp} regex - * @param {HTMLFormElement} form - * @returns {RegExpMatchArray|null} - */ -const matchInPlaceholderAndLabels = (input, regex, form) => - input.placeholder?.match(regex) || - getExplicitLabelsText(input).match(regex) || - getRelatedText(input, form).match(regex) - -/** - * Check if a given input matches a regex - * @param {HTMLInputElement} input - * @param {RegExp} regex - * @param {HTMLFormElement} form - * @returns {boolean} - */ -const checkPlaceholderAndLabels = (input, regex, form) => - !!matchInPlaceholderAndLabels(input, regex, form) - -/** - * Format the cc year to best adapt to the input requirements (YY vs YYYY) - * @param {HTMLInputElement} input - * @param {number} year - * @param {HTMLFormElement} form - * @returns {number} - */ -const formatCCYear = (input, year, form) => { - if ( - input.maxLength === 4 || - checkPlaceholderAndLabels(input, FOUR_DIGIT_YEAR_REGEX, form) - ) return year - - return year - 2000 -} - -/** - * Get a unified expiry date with separator - * @param {HTMLInputElement} input - * @param {number} month - * @param {number} year - * @param {HTMLFormElement} form - * @returns {string} - */ -const getUnifiedExpiryDate = (input, month, year, form) => { - const formattedYear = formatCCYear(input, year, form) - const paddedMonth = `${month}`.padStart(2, '0') - const separator = matchInPlaceholderAndLabels(input, DATE_SEPARATOR_REGEX, form)?.groups?.separator || '/' - - return `${paddedMonth}${separator}${formattedYear}` -} - -module.exports = { - isPassword, - isEmail, - isUserName, - getCCFieldSubtype, - inferInputType, - setInputType, - getInputMainType, - getInputSubtype, - formatCCYear, - getUnifiedExpiryDate -} diff --git a/src/Form/input-classifiers.test.js b/src/Form/input-classifiers.test.js index 9c0abd477..86a3771c8 100644 --- a/src/Form/input-classifiers.test.js +++ b/src/Form/input-classifiers.test.js @@ -1,24 +1,47 @@ -const {getCCFieldSubtype, getUnifiedExpiryDate} = require('./input-classifiers') +const fs = require('fs') +const path = require('path') + +const {getUnifiedExpiryDate} = require('./formatters') +const {scanForInputs} = require('../scanForInputs') +const {Matching, getInputSubtype} = require('./matching') +const {matchingConfiguration} = require('./matching-configuration') +const {Form} = require('./Form') +const InterfacePrototype = require('../DeviceInterface/InterfacePrototype') + +const CSS_MATCHERS_LIST = matchingConfiguration.matchers.lists['cc'].map(matcherName => { + return matchingConfiguration.matchers.fields[matcherName] +}) + +/** + * @param {HTMLInputElement} el + * @param {HTMLFormElement} form + * @returns {string|undefined} + */ +const getCCFieldSubtype = (el, form) => { + const matching = new Matching(matchingConfiguration) + return matching.subtypeFromMatchers(CSS_MATCHERS_LIST, el, form) +} const renderInputWithLabel = () => { const input = document.createElement('input') input.id = 'inputId' const label = document.createElement('label') label.setAttribute('for', 'inputId') - const form = document.createElement('form') - form.append(input, label) - document.body.append(form) - return {input, label, form} + const formElement = document.createElement('form') + formElement.append(input, label) + document.body.append(formElement) + const form = new Form(formElement, input, new InterfacePrototype()) + return { input, label, formElement: formElement, form } } const testRegexForCCLabels = (cases) => { Object.entries(cases).forEach(([expectedType, arr]) => { arr.forEach(({text, shouldMatch = true}) => { it(`"${text}" should ${shouldMatch ? '' : 'not '}match regex for ${expectedType}`, () => { - const {input, label, form} = renderInputWithLabel() + const {input, label, formElement} = renderInputWithLabel() label.textContent = text - const subtype = getCCFieldSubtype(input, form) + const subtype = getCCFieldSubtype(input, formElement) if (shouldMatch) { expect(subtype).toBe(expectedType) } else { @@ -30,53 +53,11 @@ const testRegexForCCLabels = (cases) => { } afterEach(() => { - document.body.innerHTML = null + document.body.innerHTML = '' }) describe('Input Classifiers', () => { - it('should match the selector for cardNumber', () => { - const {input, form} = renderInputWithLabel() - input.autocomplete = 'cc-number' - expect(getCCFieldSubtype(input, form)).toBe('cardNumber') - }) - - it('should match text in a nearby span', () => { - // Poor markup without a form proper labels and attributes - const markup = ` -
-
- Card Number - -
-
- MM-YYYY - -
-
- Security code - -
-
- Random unrelated field - - -
- -
` - document.body.innerHTML = markup - const form = document.querySelector('.form') - const inputs = document.querySelectorAll('input') - - expect(getCCFieldSubtype(inputs[0], form)).toBe('cardNumber') - expect(getCCFieldSubtype(inputs[1], form)).toBe('expiration') - expect(getUnifiedExpiryDate(inputs[1], 8, 2025, form)).toBe('08-2025') - expect(getCCFieldSubtype(inputs[2], form)).toBe('cardSecurityCode') - expect(getCCFieldSubtype(inputs[3], form)).toBeUndefined() - }) - - const ccLabeltestCases = { + const ccLabelTestCases = { cardName: [ {text: 'credit card name'}, {text: 'name on card'}, @@ -88,7 +69,6 @@ describe('Input Classifiers', () => { {text: 'Credit Card Number'}, {text: 'number on card'}, {text: 'card owner', shouldMatch: false} - ], expirationMonth: [ {text: 'expiry month'}, @@ -112,7 +92,7 @@ describe('Input Classifiers', () => { {text: 'card expiry mo', shouldMatch: false} ] } - testRegexForCCLabels(ccLabeltestCases) + testRegexForCCLabels(ccLabelTestCases) describe('Unified Expiration Date', () => { describe.each([ @@ -127,7 +107,7 @@ describe('Input Classifiers', () => { { text: 'mm - yy', expectedResult: '08-25' }, { text: 'mm yy', expectedResult: '08 25' }, { text: 'ie: 08.22', expectedResult: '08.25' } - ])('when checking for $text', ({ text, expectedResult }) => { + ])('when checking for "$text"', ({ text, expectedResult }) => { let elements beforeEach(() => { @@ -151,3 +131,57 @@ describe('Input Classifiers', () => { }) }) }) + +const testCases = require('./test-cases/index') +describe.each(testCases)('Test $html fields', (testCase) => { + const { html, expectedFailures = [], title = '__test__' } = testCase + + const testTextString = expectedFailures.length > 0 + ? `should contain ${expectedFailures.length} known failure(s): ${JSON.stringify(expectedFailures)}` + : `should NOT contain failures` + + it(testTextString, () => { + const testContent = fs.readFileSync(path.resolve(__dirname, './test-cases', html), 'utf-8') + + document.body.innerHTML = testContent + document.title = title + + scanForInputs(new InterfacePrototype(), new Map()).findEligibleInputs(document) + + /** + * @type {NodeListOf} + */ + const manuallyScoredFields = document.querySelectorAll('[data-manual-scoring]') + + const scores = Array.from(manuallyScoredFields).map(field => { + const { manualScoring, ddgInputtype, ...rest } = field.dataset + // @ts-ignore + field.style = '' + return { + attrs: { + name: field.name, + id: field.id, + dataset: rest + }, + html: field.outerHTML, + inferredType: getInputSubtype(field), + manualScore: field.getAttribute('data-manual-scoring') + } + }) + let bad = scores.filter(x => x.inferredType !== x.manualScore) + let failed = bad.map(x => x.manualScore) + + if (bad.length !== expectedFailures.length) { + for (let score of bad) { + console.log( + 'manualType: ' + JSON.stringify(score.manualScore), + '\ninferredType: ' + JSON.stringify(score.inferredType), + '\nid: ', JSON.stringify(score.attrs.id), + '\nname: ', JSON.stringify(score.attrs.name), + '\nHTML: ', score.html + ) + } + } + expect(failed).toStrictEqual(expectedFailures) + }) +}) diff --git a/src/Form/inputStyles.js b/src/Form/inputStyles.js index 71b800363..9522d963e 100644 --- a/src/Form/inputStyles.js +++ b/src/Form/inputStyles.js @@ -1,36 +1,63 @@ -const getInputConfig = require('./inputTypeConfig.js') +const {getInputConfig} = require('./inputTypeConfig.js') + +/** + * Returns the css-ready base64 encoding of the icon for the given input + * @param {HTMLInputElement} input + * @param {import("./Form").Form} form + * @param {'base' | 'filled'} type + * @return {string} + */ +const getIcon = (input, form, type = 'base') => { + const config = getInputConfig(input) + if (type === 'base') { + return config.getIconBase(input, form) + } + if (type === 'filled') { + return config.getIconFilled(input, form) + } + return '' +} + +/** + * Returns an object with styles to be applied inline + * @param {HTMLInputElement} input + * @param {String} icon + * @return {Object} + */ +const getBasicStyles = (input, icon) => ({ + // Height must be > 0 to account for fields initially hidden + 'background-size': `auto ${input.offsetHeight <= 30 && input.offsetHeight > 0 ? '100%' : '26px'}`, + 'background-position': 'center right', + 'background-repeat': 'no-repeat', + 'background-origin': 'content-box', + 'background-image': `url(${icon})`, + 'transition': 'background 0s' +}) /** * Get inline styles for the injected icon, base state * @param {HTMLInputElement} input + * @param {import("./Form").Form} form * @return {Object} */ -const getIconStylesBase = (input) => { - const config = getInputConfig(input) - const icon = config.getIconBase() +const getIconStylesBase = (input, form) => { + const icon = getIcon(input, form) if (!icon) return {} - return { - // Height must be > 0 to account for fields initially hidden - 'background-size': `auto ${input.offsetHeight <= 30 && input.offsetHeight > 0 ? '100%' : '26px'}`, - 'background-position': 'center right', - 'background-repeat': 'no-repeat', - 'background-origin': 'content-box', - 'background-image': `url(${icon})`, - 'transition': 'background 0s' - } + return getBasicStyles(input, icon) } /** * Get inline styles for the injected icon, autofilled state * @param {HTMLInputElement} input + * @param {import("./Form").Form} form + * @return {Object} */ -const getIconStylesAutofilled = (input) => { - const config = getInputConfig(input) - const icon = config.getIconBase() +const getIconStylesAutofilled = (input, form) => { + const icon = getIcon(input, form, 'filled') - const iconStyle = icon ? {'background-image': `url(${icon}`} : {} + const iconStyle = icon ? getBasicStyles(input, icon) : {} return { ...iconStyle, diff --git a/src/Form/inputTypeConfig.js b/src/Form/inputTypeConfig.js index eaaa76c49..ea3029c4a 100644 --- a/src/Form/inputTypeConfig.js +++ b/src/Form/inputTypeConfig.js @@ -1,71 +1,122 @@ -const {isDDGApp, isMobileApp} = require('../autofill-utils') +const {isDDGApp, isApp} = require('../autofill-utils') const {daxBase64} = require('./logo-svg') const ddgPasswordIcons = require('../UI/img/ddgPasswordIcon') -const {getInputMainType} = require('./input-classifiers') +const {getInputType, getMainTypeFromType, getInputSubtype} = require('./matching') +const {CredentialsTooltipItem} = require('../InputTypes/Credentials') +const {CreditCardTooltipItem} = require('../InputTypes/CreditCard') +const {IdentityTooltipItem} = require('../InputTypes/Identity') // In Firefox web_accessible_resources could leak a unique user identifier, so we avoid it here const isFirefox = navigator.userAgent.includes('Firefox') const getDaxImg = isDDGApp || isFirefox ? daxBase64 : chrome.runtime.getURL('img/logo-small.svg') /** - * A map of config objects. These help by centralising here some of the complexity - * @type {Object} + * Get the icon for the identities (currently only Dax for emails) + * @param {HTMLInputElement} input + * @param {import("./Form").Form} form + * @return {string} */ -const inputTypeConfig = { - emailNew: { - type: 'emailNew', - getIconBase: () => getDaxImg, - getIconFilled: () => getDaxImg, - shouldDecorate: (isLogin, device) => { - if (isMobileApp) return device.isDeviceSignedIn() +const getIdentitiesIcon = (input, {device}) => { + const subtype = getInputSubtype(input) + if (subtype === 'emailAddress' && device.isDeviceSignedIn()) return getDaxImg - return device.hasLocalAddresses - }, - dataType: 'Addresses', - displayTitlePropName: '', - displaySubtitlePropName: '', - autofillMethod: '' - }, + return '' +} + +/** + * A map of config objects. These help by centralising here some complexity + * @type {InputTypeConfig} + */ +const inputTypeConfig = { + /** @type {CredentialsInputTypeConfig} */ credentials: { type: 'credentials', getIconBase: () => ddgPasswordIcons.ddgPasswordIconBase, getIconFilled: () => ddgPasswordIcons.ddgPasswordIconFilled, - shouldDecorate: (isLogin, device) => isLogin && device.hasLocalCredentials, + shouldDecorate: (input, {isLogin, device}) => { + // if we are on a 'login' page, continue to use old logic, eg: just checking if there's a + // saved password + if (isLogin) { + return device.hasLocalCredentials + } + + // at this point, it's not a 'login' attempt, so we could offer to provide a password? + if (device.supportsFeature('password.generation')) { + const subtype = getInputSubtype(input) + if (subtype === 'password') { + return true + } + } + + return false + }, dataType: 'Credentials', - displayTitlePropName: 'username', - displaySubtitlePropName: '•••••••••••••••', - autofillMethod: 'getAutofillCredentials' + tooltipItem: (data) => new CredentialsTooltipItem(data) }, + /** @type {CreditCardInputTypeConfig} */ creditCard: { type: 'creditCard', getIconBase: () => '', getIconFilled: () => '', - shouldDecorate: (isLogin, device) => device.hasLocalCreditCards, + shouldDecorate: (_input, {device}) => device.hasLocalCreditCards, dataType: 'CreditCards', - displayTitlePropName: 'title', - displaySubtitlePropName: 'displayNumber', - autofillMethod: 'getAutofillCreditCard' + tooltipItem: (data) => new CreditCardTooltipItem(data) + }, + /** @type {IdentitiesInputTypeConfig} */ + identities: { + type: 'identities', + getIconBase: getIdentitiesIcon, + getIconFilled: getIdentitiesIcon, + shouldDecorate: (input, {device}) => { + const subtype = getInputSubtype(input) + + if (isApp) { + return Boolean(device.getLocalIdentities()?.some((identity) => !!identity[subtype])) + } + + if (subtype === 'emailAddress') { + return Boolean(device.isDeviceSignedIn()) + } + + return false + }, + dataType: 'Identities', + tooltipItem: (data) => new IdentityTooltipItem(data) }, + /** @type {UnknownInputTypeConfig} */ unknown: { type: 'unknown', getIconBase: () => '', getIconFilled: () => '', shouldDecorate: () => false, dataType: '', - displayTitlePropName: '', - displaySubtitlePropName: '', - autofillMethod: '' + tooltipItem: (_data) => { + throw new Error('unreachable') + } } } /** * Retrieves configs from an input el * @param {HTMLInputElement} input - * @returns {InputTypeConfig} + * @returns {InputTypeConfigs} */ const getInputConfig = (input) => { - const inputType = getInputMainType(input) - return inputTypeConfig[inputType || 'unknown'] + const inputType = getInputType(input) + return getInputConfigFromType(inputType) } -module.exports = getInputConfig +/** + * Retrieves configs from an input type + * @param {import('./matching').SupportedTypes | string} inputType + * @returns {InputTypeConfigs} + */ +const getInputConfigFromType = (inputType) => { + const inputMainType = getMainTypeFromType(inputType) + return inputTypeConfig[inputMainType] +} + +module.exports = { + getInputConfig, + getInputConfigFromType +} diff --git a/src/Form/label-util.js b/src/Form/label-util.js new file mode 100644 index 000000000..672b63d05 --- /dev/null +++ b/src/Form/label-util.js @@ -0,0 +1,41 @@ +const EXCLUDED_TAGS = ['SCRIPT', 'NOSCRIPT', 'OPTION', 'STYLE'] + +/** + * Extract all strings of an element's children to an array. + * "element.textContent" is a string which is merged of all children nodes, + * which can cause issues with things like script tags etc. + * + * @param {HTMLElement} element + * A DOM element to be extracted. + * @returns {string[]} + * All strings in an element. + */ +const extractLabelStrings = (element) => { + const strings = [] + const _extractLabelStrings = el => { + if (EXCLUDED_TAGS.includes(el.tagName)) { + return + } + + // only take the string when it's an explicit text node + if (el.nodeType === el.TEXT_NODE || !el.childNodes.length) { + let trimmedText = el.textContent.trim() + if (trimmedText) { + strings.push(trimmedText) + } + return + } + + for (let node of el.childNodes) { + let nodeType = node.nodeType + if (nodeType !== node.ELEMENT_NODE && nodeType !== node.TEXT_NODE) { + continue + } + _extractLabelStrings(node) + } + } + _extractLabelStrings(element) + return strings +} + +module.exports.extractLabelStrings = extractLabelStrings diff --git a/src/Form/listenForFormSubmission.js b/src/Form/listenForFormSubmission.js index 3dc991864..3ad0b164e 100644 --- a/src/Form/listenForFormSubmission.js +++ b/src/Form/listenForFormSubmission.js @@ -5,8 +5,14 @@ const listenForGlobalFormSubmission = () => { if (!isApp) return try { + window.addEventListener('submit', (e) => + // @ts-ignore + forms.get(e.target)?.submitHandler(), + true) + const observer = new PerformanceObserver((list) => { const entries = list.getEntries().filter((entry) => + // @ts-ignore why does TS not know about `entry.initiatorType`? ['fetch', 'xmlhttprequest'].includes(entry.initiatorType) && entry.name.match(/login|sign-in|signin|session/) ) diff --git a/src/Form/matching-configuration.js b/src/Form/matching-configuration.js new file mode 100644 index 000000000..3c90facc3 --- /dev/null +++ b/src/Form/matching-configuration.js @@ -0,0 +1,842 @@ +const css = require('./selectors-css') + +/** + * This is here to mimic what Remote Configuration might look like + * later on. + * + * @type {MatchingConfiguration} + */ +const matchingConfiguration = { + /** @type {MatcherConfiguration} */ + matchers: { + fields: { + email: { + type: 'email', + strategies: { + cssSelector: 'email', + ddgMatcher: 'email', + vendorRegex: 'email' + } + }, + password: { + type: 'password', + strategies: { + cssSelector: 'password', + ddgMatcher: 'password' + } + }, + username: { + type: 'username', + strategies: { + cssSelector: 'username', + ddgMatcher: 'username' + } + }, + firstName: { + type: 'firstName', + strategies: { + cssSelector: 'firstName', + ddgMatcher: 'firstName', + vendorRegex: 'given-name' + } + }, + middleName: { + type: 'middleName', + strategies: { + cssSelector: 'middleName', + ddgMatcher: 'middleName', + vendorRegex: 'additional-name' + } + }, + lastName: { + type: 'lastName', + strategies: { + cssSelector: 'lastName', + ddgMatcher: 'lastName', + vendorRegex: 'family-name' + } + }, + fullName: { + type: 'fullName', + strategies: { + cssSelector: 'fullName', + ddgMatcher: 'fullName', + vendorRegex: 'name' + } + }, + phone: { + type: 'phone', + strategies: { + cssSelector: 'phone', + ddgMatcher: 'phone', + vendorRegex: 'tel' + } + }, + addressStreet: { + type: 'addressStreet', + strategies: { + cssSelector: 'addressStreet', + ddgMatcher: 'addressStreet', + vendorRegex: 'address-line1' + } + }, + addressStreet2: { + type: 'addressStreet2', + strategies: { + cssSelector: 'addressStreet2', + ddgMatcher: 'addressStreet2', + vendorRegex: 'address-line2' + } + }, + addressCity: { + type: 'addressCity', + strategies: { + cssSelector: 'addressCity', + ddgMatcher: 'addressCity', + vendorRegex: 'address-level2' + } + }, + addressProvince: { + type: 'addressProvince', + strategies: { + cssSelector: 'addressProvince', + ddgMatcher: 'addressProvince', + vendorRegex: 'address-level1' + } + }, + addressPostalCode: { + type: 'addressPostalCode', + strategies: { + cssSelector: 'addressPostalCode', + ddgMatcher: 'addressPostalCode', + vendorRegex: 'postal-code' + } + }, + addressCountryCode: { + type: 'addressCountryCode', + strategies: { + cssSelector: 'addressCountryCode', + ddgMatcher: 'addressCountryCode', + vendorRegex: 'country' + } + }, + birthdayDay: { + type: 'birthdayDay', + strategies: { + cssSelector: 'birthdayDay' + } + }, + birthdayMonth: { + type: 'birthdayMonth', + strategies: { + cssSelector: 'birthdayMonth' + } + }, + birthdayYear: { + type: 'birthdayYear', + strategies: { + cssSelector: 'birthdayYear' + } + }, + cardName: { + type: 'cardName', + strategies: { + cssSelector: 'cardName', + ddgMatcher: 'cardName', + vendorRegex: 'cc-name' + } + }, + cardNumber: { + type: 'cardNumber', + strategies: { + cssSelector: 'cardNumber', + ddgMatcher: 'cardNumber', + vendorRegex: 'cc-number' + } + }, + cardSecurityCode: { + type: 'cardSecurityCode', + strategies: { + cssSelector: 'cardSecurityCode', + ddgMatcher: 'cardSecurityCode' + } + }, + expirationMonth: { + type: 'expirationMonth', + strategies: { + cssSelector: 'expirationMonth', + ddgMatcher: 'expirationMonth', + vendorRegex: 'cc-exp-month' + } + }, + expirationYear: { + type: 'expirationYear', + strategies: { + cssSelector: 'expirationYear', + ddgMatcher: 'expirationYear', + vendorRegex: 'cc-exp-year' + } + }, + expiration: { + type: 'expiration', + strategies: { + cssSelector: 'expiration', + ddgMatcher: 'expiration', + vendorRegex: 'cc-exp' + } + } + }, + lists: { + email: ['email'], + password: ['password'], + username: ['username'], + cc: ['cardName', 'cardNumber', 'cardSecurityCode', 'expirationMonth', 'expirationYear', 'expiration'], + id: [ + 'firstName', + 'middleName', + 'lastName', + 'fullName', + 'phone', + 'addressStreet', + 'addressStreet2', + 'addressCity', + 'addressProvince', + 'addressPostalCode', + 'addressCountryCode', + 'birthdayDay', + 'birthdayMonth', + 'birthdayYear' + ] + } + }, + strategies: { + /** @type {CssSelectorConfiguration} */ + cssSelector: { + selectors: { + + // Generic + FORM_INPUTS_SELECTOR: css.__secret_do_not_use.FORM_INPUTS_SELECTOR, + SUBMIT_BUTTON_SELECTOR: css.__secret_do_not_use.SUBMIT_BUTTON_SELECTOR, + GENERIC_TEXT_FIELD: css.__secret_do_not_use.GENERIC_TEXT_FIELD, + + // user + email: css.__secret_do_not_use.email, + password: css.__secret_do_not_use.password, + username: css.__secret_do_not_use.username, + + // CC + cardName: css.__secret_do_not_use.cardName, + cardNumber: css.__secret_do_not_use.cardNumber, + cardSecurityCode: css.__secret_do_not_use.cardSecurityCode, + expirationMonth: css.__secret_do_not_use.expirationMonth, + expirationYear: css.__secret_do_not_use.expirationYear, + expiration: css.__secret_do_not_use.expiration, + + // Identities + firstName: css.__secret_do_not_use.firstName, + middleName: css.__secret_do_not_use.middleName, + lastName: css.__secret_do_not_use.lastName, + fullName: css.__secret_do_not_use.fullName, + phone: css.__secret_do_not_use.phone, + addressStreet: css.__secret_do_not_use.addressStreet1, + addressStreet2: css.__secret_do_not_use.addressStreet2, + addressCity: css.__secret_do_not_use.addressCity, + addressProvince: css.__secret_do_not_use.addressProvince, + addressPostalCode: css.__secret_do_not_use.addressPostalCode, + addressCountryCode: css.__secret_do_not_use.addressCountryCode, + birthdayDay: css.__secret_do_not_use.birthdayDay, + birthdayMonth: css.__secret_do_not_use.birthdayMonth, + birthdayYear: css.__secret_do_not_use.birthdayYear + } + }, + /** @type {DDGMatcherConfiguration} */ + ddgMatcher: { + matchers: { + email: {match: '.mail', forceUnknown: 'search'}, + password: {match: 'password', forceUnknown: 'captcha'}, + username: {match: 'user((.)?(name|id|login))?$', forceUnknown: 'search'}, + + // CC + cardName: {match: '(card.*name|name.*card)|(card.*holder|holder.*card)|(card.*owner|owner.*card)'}, + cardNumber: {match: 'card.*number|number.*card'}, + cardSecurityCode: {match: 'security.?code|card.?verif|cvv|csc|cvc'}, + expirationMonth: { + match: '(card|\\bcc\\b)?.?(exp(iry|iration)?)?.?(month|\\bmm\\b(?![.\\s/-]yy))', + forceUnknown: 'mm[/\\s.\\-_—–]' + }, + expirationYear: {match: '(card|\\bcc\\b)?.?(exp(iry|iration)?)?.?(year|yy)', skip: 'mm[/\\s.\\-_—–]'}, + expiration: { + match: '(\\bmm\\b|\\b\\d\\d\\b)[/\\s.\\-_—–](\\byy|\\bjj|\\baa|\\b\\d\\d)|\\bexp|\\bvalid(idity| through| until)', + forceUnknown: 'invalid' + }, + + // Identities + firstName: {match: '(first|given|fore).?name'}, + middleName: {match: '(middle|additional).?name'}, + lastName: {match: '(last|family|sur)[^i]?name'}, + fullName: {match: '^(full.?|whole\\s)?name\\b', forceUnknown: 'company|org'}, + phone: {match: 'phone', forceUnknown: 'code|pass'}, + addressStreet: { match: 'address', forceUnknown: 'email|\\bip\\b|duck|log.?in|sign.?in', skip: 'address.*(2|two)' }, + addressStreet2: { + match: 'address.*(2|two)|apartment|\\bapt\\b|\\bflat\\b|\\bline.*(2|two)', + forceUnknown: 'email|\\bip\\b|duck|log.?in|sign.?in' + }, + addressCity: {match: 'city|town', forceUnknown: 'vatican'}, + addressProvince: {match: 'state|province|region|county', forceUnknown: 'united', skip: 'country'}, + addressPostalCode: {match: '\\bzip\\b|postal|post.?code'}, + addressCountryCode: {match: 'country'} + } + }, + /** + * @type {VendorRegexConfiguration} + */ + vendorRegex: { + rules: { + email: null, + tel: null, + organization: null, + 'street-address': null, + 'address-line1': null, + 'address-line2': null, + 'address-line3': null, + 'address-level2': null, + 'address-level1': null, + 'postal-code': null, + country: null, + 'cc-name': null, + name: null, + 'given-name': null, + 'additional-name': null, + 'family-name': null, + 'cc-number': null, + 'cc-exp-month': null, + 'cc-exp-year': null, + 'cc-exp': null, + 'cc-type': null + }, + ruleSets: [ + //= ======================================================================== + // Firefox-specific rules + { + 'address-line1': 'addrline1|address_1', + 'address-line2': 'addrline2|address_2', + 'address-line3': 'addrline3|address_3', + 'address-level1': 'land', // de-DE + 'additional-name': 'apellido.?materno|lastlastname', + 'cc-name': + 'accountholdername' + + '|titulaire', // fr-FR + 'cc-number': '(cc|kk)nr', // de-DE + 'cc-exp-month': '(cc|kk)month', // de-DE + 'cc-exp-year': '(cc|kk)year', // de-DE + 'cc-type': 'type' + + '|kartenmarke' // de-DE + }, + + //= ======================================================================== + // These are the rules used by Bitwarden [0], converted into RegExp form. + // [0] https://github.com/bitwarden/browser/blob/c2b8802201fac5e292d55d5caf3f1f78088d823c/src/services/autofill.service.ts#L436 + { + email: '(^e-?mail$)|(^email-?address$)', + + tel: + '(^phone$)' + + '|(^mobile$)' + + '|(^mobile-?phone$)' + + '|(^tel$)' + + '|(^telephone$)' + + '|(^phone-?number$)', + + organization: + '(^company$)' + + '|(^company-?name$)' + + '|(^organization$)' + + '|(^organization-?name$)', + + 'street-address': + '(^address$)' + + '|(^street-?address$)' + + '|(^addr$)' + + '|(^street$)' + + '|(^mailing-?addr(ess)?$)' + // Modified to not grab lines, below + '|(^billing-?addr(ess)?$)' + // Modified to not grab lines, below + '|(^mail-?addr(ess)?$)' + // Modified to not grab lines, below + '|(^bill-?addr(ess)?$)', // Modified to not grab lines, below + + 'address-line1': + '(^address-?1$)' + + '|(^address-?line-?1$)' + + '|(^addr-?1$)' + + '|(^street-?1$)', + + 'address-line2': + '(^address-?2$)' + + '|(^address-?line-?2$)' + + '|(^addr-?2$)' + + '|(^street-?2$)', + + 'address-line3': + '(^address-?3$)' + + '|(^address-?line-?3$)' + + '|(^addr-?3$)' + + '|(^street-?3$)', + + 'address-level2': + '(^city$)' + + '|(^town$)' + + '|(^address-?level-?2$)' + + '|(^address-?city$)' + + '|(^address-?town$)', + + 'address-level1': + '(^state$)' + + '|(^province$)' + + '|(^provence$)' + + '|(^address-?level-?1$)' + + '|(^address-?state$)' + + '|(^address-?province$)', + + 'postal-code': + '(^postal$)' + + '|(^zip$)' + + '|(^zip2$)' + + '|(^zip-?code$)' + + '|(^postal-?code$)' + + '|(^post-?code$)' + + '|(^address-?zip$)' + + '|(^address-?postal$)' + + '|(^address-?code$)' + + '|(^address-?postal-?code$)' + + '|(^address-?zip-?code$)', + + country: + '(^country$)' + + '|(^country-?code$)' + + '|(^country-?name$)' + + '|(^address-?country$)' + + '|(^address-?country-?name$)' + + '|(^address-?country-?code$)', + + name: '(^name$)|full-?name|your-?name', + + 'given-name': + '(^f-?name$)' + + '|(^first-?name$)' + + '|(^given-?name$)' + + '|(^first-?n$)', + + 'additional-name': + '(^m-?name$)' + + '|(^middle-?name$)' + + '|(^additional-?name$)' + + '|(^middle-?initial$)' + + '|(^middle-?n$)' + + '|(^middle-?i$)', + + 'family-name': + '(^l-?name$)' + + '|(^last-?name$)' + + '|(^s-?name$)' + + '|(^surname$)' + + '|(^family-?name$)' + + '|(^family-?n$)' + + '|(^last-?n$)', + + 'cc-name': + 'cc-?name' + + '|card-?name' + + '|cardholder-?name' + + '|cardholder' + + // "|(^name$)" + // Removed to avoid overwriting "name", above. + '|(^nom$)', + + 'cc-number': + 'cc-?number' + + '|cc-?num' + + '|card-?number' + + '|card-?num' + + '|(^number$)' + + '|(^cc$)' + + '|cc-?no' + + '|card-?no' + + '|(^credit-?card$)' + + '|numero-?carte' + + '|(^carte$)' + + '|(^carte-?credit$)' + + '|num-?carte' + + '|cb-?num', + + 'cc-exp': + '(^cc-?exp$)' + + '|(^card-?exp$)' + + '|(^cc-?expiration$)' + + '|(^card-?expiration$)' + + '|(^cc-?ex$)' + + '|(^card-?ex$)' + + '|(^card-?expire$)' + + '|(^card-?expiry$)' + + '|(^validite$)' + + '|(^expiration$)' + + '|(^expiry$)' + + '|mm-?yy' + + '|mm-?yyyy' + + '|yy-?mm' + + '|yyyy-?mm' + + '|expiration-?date' + + '|payment-?card-?expiration' + + '|(^payment-?cc-?date$)', + + 'cc-exp-month': + '(^exp-?month$)' + + '|(^cc-?exp-?month$)' + + '|(^cc-?month$)' + + '|(^card-?month$)' + + '|(^cc-?mo$)' + + '|(^card-?mo$)' + + '|(^exp-?mo$)' + + '|(^card-?exp-?mo$)' + + '|(^cc-?exp-?mo$)' + + '|(^card-?expiration-?month$)' + + '|(^expiration-?month$)' + + '|(^cc-?mm$)' + + '|(^cc-?m$)' + + '|(^card-?mm$)' + + '|(^card-?m$)' + + '|(^card-?exp-?mm$)' + + '|(^cc-?exp-?mm$)' + + '|(^exp-?mm$)' + + '|(^exp-?m$)' + + '|(^expire-?month$)' + + '|(^expire-?mo$)' + + '|(^expiry-?month$)' + + '|(^expiry-?mo$)' + + '|(^card-?expire-?month$)' + + '|(^card-?expire-?mo$)' + + '|(^card-?expiry-?month$)' + + '|(^card-?expiry-?mo$)' + + '|(^mois-?validite$)' + + '|(^mois-?expiration$)' + + '|(^m-?validite$)' + + '|(^m-?expiration$)' + + '|(^expiry-?date-?field-?month$)' + + '|(^expiration-?date-?month$)' + + '|(^expiration-?date-?mm$)' + + '|(^exp-?mon$)' + + '|(^validity-?mo$)' + + '|(^exp-?date-?mo$)' + + '|(^cb-?date-?mois$)' + + '|(^date-?m$)', + + 'cc-exp-year': + '(^exp-?year$)' + + '|(^cc-?exp-?year$)' + + '|(^cc-?year$)' + + '|(^card-?year$)' + + '|(^cc-?yr$)' + + '|(^card-?yr$)' + + '|(^exp-?yr$)' + + '|(^card-?exp-?yr$)' + + '|(^cc-?exp-?yr$)' + + '|(^card-?expiration-?year$)' + + '|(^expiration-?year$)' + + '|(^cc-?yy$)' + + '|(^cc-?y$)' + + '|(^card-?yy$)' + + '|(^card-?y$)' + + '|(^card-?exp-?yy$)' + + '|(^cc-?exp-?yy$)' + + '|(^exp-?yy$)' + + '|(^exp-?y$)' + + '|(^cc-?yyyy$)' + + '|(^card-?yyyy$)' + + '|(^card-?exp-?yyyy$)' + + '|(^cc-?exp-?yyyy$)' + + '|(^expire-?year$)' + + '|(^expire-?yr$)' + + '|(^expiry-?year$)' + + '|(^expiry-?yr$)' + + '|(^card-?expire-?year$)' + + '|(^card-?expire-?yr$)' + + '|(^card-?expiry-?year$)' + + '|(^card-?expiry-?yr$)' + + '|(^an-?validite$)' + + '|(^an-?expiration$)' + + '|(^annee-?validite$)' + + '|(^annee-?expiration$)' + + '|(^expiry-?date-?field-?year$)' + + '|(^expiration-?date-?year$)' + + '|(^cb-?date-?ann$)' + + '|(^expiration-?date-?yy$)' + + '|(^expiration-?date-?yyyy$)' + + '|(^validity-?year$)' + + '|(^exp-?date-?year$)' + + '|(^date-?y$)', + + 'cc-type': + '(^cc-?type$)' + + '|(^card-?type$)' + + '|(^card-?brand$)' + + '|(^cc-?brand$)' + + '|(^cb-?type$)' + }, + + //= ======================================================================== + // These rules are from Chromium source codes [1]. Most of them + // converted to JS format have the same meaning with the original ones + // except the first line of "address-level1". + // [1] https://source.chromium.org/chromium/chromium/src/+/master:components/autofill/core/common/autofill_regex_constants.cc + { + // ==== Email ==== + email: + 'e.?mail' + + '|courriel' + // fr + '|correo.*electr(o|ó)nico' + // es-ES + '|メールアドレス' + // ja-JP + '|Электронной.?Почты' + // ru + '|邮件|邮箱' + // zh-CN + '|電郵地址' + // zh-TW + '|ഇ-മെയില്‍|ഇലക്ട്രോണിക്.?' + + 'മെയിൽ' + // ml + '|ایمیل|پست.*الکترونیک' + // fa + '|ईमेल|इलॅक्ट्रॉनिक.?मेल' + // hi + '|(\\b|_)eposta(\\b|_)' + // tr + '|(?:이메일|전자.?우편|[Ee]-?mail)(.?주소)?', // ko-KR + + // ==== Telephone ==== + tel: + 'phone|mobile|contact.?number' + + '|telefonnummer' + // de-DE + '|telefono|teléfono' + // es + '|telfixe' + // fr-FR + '|電話' + // ja-JP + '|telefone|telemovel' + // pt-BR, pt-PT + '|телефон' + // ru + '|मोबाइल' + // hi for mobile + '|(\\b|_|\\*)telefon(\\b|_|\\*)' + // tr + '|电话' + // zh-CN + '|മൊബൈല്‍' + // ml for mobile + '|(?:전화|핸드폰|휴대폰|휴대전화)(?:.?번호)?', // ko-KR + + // ==== Address Fields ==== + organization: + 'company|business|organization|organisation' + + // '|(?, + lists: Record +} + +type MatcherTypeNames = + | 'email' + | 'password' + | 'username' + | 'cardName' + | 'cardNumber' + | 'cardSecurityCode' + | 'expirationMonth' + | 'expirationYear' + | 'expiration' + | 'firstName' + | 'middleName' + | 'lastName' + | 'fullName' + | 'phone' + | 'addressStreet' + | 'addressStreet2' + | 'addressCity' + | 'addressProvince' + | 'addressPostalCode' + | 'addressCountryCode' + | 'birthdayDay' + | 'birthdayMonth' + | 'birthdayYear' + +type Strategy = + | CSSSelectorStrategy + | VendorRegexStrategy + | DDGMatcherStrategy + +interface CSSSelectorStrategy { + kind: 'cssSelector' + selectorName: keyof RequiredCssSelectors | string +} + +interface VendorRegexStrategy { + kind: 'vendorRegex' + regexName: keyof VendorRegexRules | string; +} + +interface DDGMatcherStrategy { + kind: 'ddgMatcher' + matcherName: MatcherTypeNames | string +} + +type MatchableStrings = + | "nameAttr" + | "labelText" + | "placeholderAttr" + | "relatedText" + +type MatchingResult = { + matched: boolean + proceed?: boolean +} + +type SupportedMainTypes = + | 'credentials' + | 'creditCard' + | 'identities' + | 'unknown' + +interface InputTypeConfigBase { + type: SupportedMainTypes, + getIconFilled: (input: HTMLInputElement, form: import("../Form/Form").Form) => string, + getIconBase: (input: HTMLInputElement, form: import("../Form/Form").Form) => string, + shouldDecorate: (input: HTMLInputElement, form: import("../Form/Form").Form) => boolean, + dataType: 'Addresses' | 'Credentials' | 'CreditCards' | 'Identities' | '', + tooltipItem(data: any): TooltipItemRenderer; +} + +interface CredentialsInputTypeConfig extends InputTypeConfigBase { + tooltipItem(data: CredentialsObject): TooltipItemRenderer; +} +interface CreditCardInputTypeConfig extends InputTypeConfigBase { + tooltipItem(data: CreditCardObject): TooltipItemRenderer; +} +interface IdentitiesInputTypeConfig extends InputTypeConfigBase { + tooltipItem(data: IdentityObject): TooltipItemRenderer; +} +interface UnknownInputTypeConfig extends InputTypeConfigBase { +} + +type InputTypeConfigs = + | CredentialsInputTypeConfig + | CreditCardInputTypeConfig + | IdentitiesInputTypeConfig + | UnknownInputTypeConfig + +type InputTypeConfig = Record + +interface CssSelectorConfiguration { + selectors: RequiredCssSelectors | Record +} + +interface VendorRegexConfiguration { + rules: Record + ruleSets: Record[] +} + +interface DDGMatcherConfiguration { + matchers: Record +} + +interface DDGMatcher { + match?: string; + forceUnknown?: string + skip?: string + matchableStrings?: MatchableStrings[] + skipStrings?: MatchableStrings[] + maxDigits?: number +} + +type RequiredCssSelectors = { + FORM_INPUTS_SELECTOR: string + SUBMIT_BUTTON_SELECTOR: string + GENERIC_TEXT_FIELD: string +} + +/** + * This is just here to describe the current vendor regexes + */ +interface VendorRegexRules { + email: RegExp, + tel: RegExp, + organization: RegExp, + 'street-address': RegExp, + 'address-line1': RegExp, + 'address-line2': RegExp, + 'address-line3': RegExp, + 'address-level2': RegExp, + 'address-level1': RegExp, + 'postal-code': RegExp, + country: RegExp, + // Note: RegExp place the `cc-name` field for Credit Card first, because + // it is more specific than the `name` field below and we want to check + // for it before we catch the more generic one. + 'cc-name': RegExp, + name: RegExp, + 'given-name': RegExp, + 'additional-name': RegExp, + 'family-name': RegExp, + 'cc-number': RegExp, + 'cc-exp-month': RegExp, + 'cc-exp-year': RegExp, + 'cc-exp': RegExp, + 'cc-type': RegExp +} diff --git a/src/Form/matching.js b/src/Form/matching.js new file mode 100644 index 000000000..e0e309347 --- /dev/null +++ b/src/Form/matching.js @@ -0,0 +1,803 @@ +const {createCacheableVendorRegexes} = require('./vendor-regex') +const {TEXT_LENGTH_CUTOFF, ATTR_INPUT_TYPE} = require('../constants') +const {extractLabelStrings} = require('./label-util') + +/** + * An abstraction around the concept of classifying input fields. + * + * The only state this class keeps is derived from the passed-in MatchingConfiguration. + */ +class Matching { + /** @type {MatchingConfiguration} */ + #config; + + /** @type {CssSelectorConfiguration['selectors']} */ + #cssSelectors; + + /** @type {Record} */ + #ddgMatchers; + + /** + * This acts as an internal cache for the larger vendorRegexes + * @type {{RULES: Record}} + */ + #vendorRegExpCache; + + /** @type {MatcherLists} */ + #matcherLists; + + /** @type {Array} */ + #defaultStrategyOrder = ['cssSelector', 'ddgMatcher', 'vendorRegex'] + + /** + * @param {MatchingConfiguration} config + */ + constructor (config) { + this.#config = config + + const { rules, ruleSets } = this.#config.strategies.vendorRegex + this.#vendorRegExpCache = createCacheableVendorRegexes(rules, ruleSets) + this.#cssSelectors = this.#config.strategies.cssSelector.selectors + this.#ddgMatchers = this.#config.strategies.ddgMatcher.matchers + + this.#matcherLists = { + cc: [], + id: [], + password: [], + username: [], + email: [] + } + + /** + * Convert the raw config data into actual references. + * + * For example this takes `email: ["email"]` and creates + * + * `email: [{type: "email", strategies: {cssSelector: "email", ... etc}]` + */ + for (let [listName, matcherNames] of Object.entries(this.#config.matchers.lists)) { + for (let fieldName of matcherNames) { + if (!this.#matcherLists[listName]) { + this.#matcherLists[listName] = [] + } + this.#matcherLists[listName].push(this.#config.matchers.fields[fieldName]) + } + } + } + + /** + * Try to access a 'vendor regex' by name + * @param {string} regexName + * @returns {RegExp | undefined} + */ + vendorRegex (regexName) { + const match = this.#vendorRegExpCache.RULES[regexName] + if (!match) { + console.warn('Vendor Regex not found for', regexName) + return undefined + } + return match + } + + /** + * Try to access a 'css selector' by name from configuration + * @param {keyof RequiredCssSelectors | string} selectorName + * @returns {string}; + */ + cssSelector (selectorName) { + const match = this.#cssSelectors[selectorName] + if (!match) { + console.warn('CSS selector not found for %s, using a default value', selectorName) + return '' + } + if (Array.isArray(match)) { + return match.join(',') + } + return match + } + + /** + * Try to access a 'ddg matcher' by name from configuration + * @param {keyof RequiredCssSelectors | string} matcherName + * @returns {DDGMatcher | undefined} + */ + ddgMatcher (matcherName) { + const match = this.#ddgMatchers[matcherName] + if (!match) { + console.warn('DDG matcher not found for', matcherName) + return undefined + } + return match + } + + /** + * Try to access a list of matchers by name - these are the ones collected in the constructor + * @param {keyof MatcherLists} listName + * @return {Matcher[]} + */ + matcherList (listName) { + const matcherList = this.#matcherLists[listName] + if (!matcherList) { + console.warn('MatcherList not found for ', listName) + return [] + } + return matcherList + } + + /** + * Convert a list of matchers into a single CSS selector. + * + * This will consider all matchers in the list and if it + * contains a CSS Selector it will be added to the final output + * + * @param {keyof MatcherLists} listName + * @returns {string | undefined} + */ + joinCssSelectors (listName) { + const matcherList = this.matcherList(listName) + if (!matcherList) { + console.warn('Matcher list not found for', listName) + return undefined + } + + /** + * @type {string[]} + */ + const selectors = [] + + for (let matcher of matcherList) { + if (matcher.strategies.cssSelector) { + const css = this.cssSelector(matcher.strategies.cssSelector) + if (css) { + selectors.push(css) + } + } + } + + return selectors.join(', ') + } + + /** + * Tries to infer the input type for an input + * + * @param {HTMLInputElement|HTMLSelectElement} input + * @param {HTMLFormElement} formEl + * @param {{isLogin?: boolean}} [opts] + * @returns {SupportedTypes} + */ + inferInputType (input, formEl, opts = {}) { + const presetType = getInputType(input) + if (presetType !== 'unknown') return presetType + + // For CC forms we run aggressive matches, so we want to make sure we only + // run them on actual CC forms to avoid false positives and expensive loops + if (this.isCCForm(formEl)) { + const ccMatchers = this.matcherList('cc') + const subtype = this.subtypeFromMatchers(ccMatchers, input, formEl) + if (subtype && isValidCreditCardSubtype(subtype)) { + return `creditCard.${subtype}` + } + } + + if (input instanceof HTMLInputElement) { + if (this.isPassword(input, formEl)) { + return 'credentials.password' + } + + if (this.isEmail(input, formEl)) { + return opts.isLogin ? 'credentials.username' : 'identities.emailAddress' + } + + if (this.isUserName(input, formEl)) { + return 'credentials.username' + } + } + + const idMatchers = this.matcherList('id') + const idSubtype = this.subtypeFromMatchers(idMatchers, input, formEl) + if (idSubtype && isValidIdentitiesSubtype(idSubtype)) { + return `identities.${idSubtype}` + } + + return 'unknown' + } + + /** + * Sets the input type as a data attribute to the element and returns it + * @param {HTMLInputElement} input + * @param {HTMLFormElement} formEl + * @param {{isLogin?: boolean}} [opts] + * @returns {SupportedSubTypes | string} + */ + setInputType (input, formEl, opts = {}) { + const type = this.inferInputType(input, formEl, opts) + input.setAttribute(ATTR_INPUT_TYPE, type) + return type + } + + /** + * Tries to infer input subtype, with checks in decreasing order of reliability + * @param {Matcher[]} matchers + * @param {HTMLInputElement|HTMLSelectElement} el + * @param {HTMLFormElement} form + * @return {MatcherTypeNames|undefined} + */ + subtypeFromMatchers (matchers, el, form) { + for (let strategyName of this.#defaultStrategyOrder) { + for (let matcher of matchers) { + const lookup = matcher.strategies[strategyName] + if (!lookup) { + continue + } + const result = this.executeMatchingStrategy(strategyName, lookup, el, form) + if (result.matched) { + return matcher.type + } + if (!result.matched && result.proceed === false) { + // If we get here, do not allow subsequent strategies to continue + return undefined + } + } + } + return undefined + } + /** + * Takes a given strategy name, like 'cssSelector' along with a lookup key + * and tries to execute that strategy safely on the input provided + * + * @param {StrategyNames} strategy + * @param {string} lookup + * @param {HTMLInputElement|HTMLSelectElement} el + * @param {HTMLFormElement} form + * @returns {MatchingResult} + */ + executeMatchingStrategy (strategy, lookup, el, form) { + switch (strategy) { + case 'cssSelector': { + const selector = this.cssSelector(lookup) + return this.execCssSelector(selector, el) + } + case 'ddgMatcher': { + const ddgMatcher = this.ddgMatcher(lookup) + if (!ddgMatcher || !ddgMatcher.match) { + return { matched: false } + } + return this.execDDGMatcher(ddgMatcher, el, form) + } + case 'vendorRegex': { + const rule = this.vendorRegex(lookup) + if (!rule) { + return { matched: false } + } + return this.execVendorRegex(rule, el, form) + } + default: return { matched: false } + } + } + + /** + * CSS selector matching just levearages the `.matches` method on elements + * + * @param {string} cssSelector + * @param {HTMLInputElement|HTMLSelectElement} el + * @returns {MatchingResult} + */ + execCssSelector (cssSelector, el) { + return { matched: el.matches(cssSelector) } + } + + /** + * A DDG Matcher can have a `match` regex along with a `not` regex. This is done + * to allow it to be driven by configuration as it avoids needing to invoke custom functions. + * + * todo: maxDigits was added as an edge-case when converting this over to be declarative, but I'm + * unsure if it's actually needed. It's not urgent, but we should consider removing it if that's the case + * + * @param {DDGMatcher} ddgMatcher + * @param {HTMLInputElement|HTMLSelectElement} el + * @param {HTMLFormElement} form + * @returns {MatchingResult} + */ + execDDGMatcher (ddgMatcher, el, form) { + let matchRexExp = safeRegex(ddgMatcher.match || '') + if (!matchRexExp) { + return {matched: false} + } + + let requiredScore = ['match', 'forceUnknown', 'maxDigits'].filter(ddgMatcherProp => ddgMatcherProp in ddgMatcher).length + + /** @type {MatchableStrings[]} */ + const matchableStrings = ddgMatcher.matchableStrings || ['labelText', 'placeholderAttr', 'relatedText'] + + for (let elementString of this.getElementStrings(el, form, {matchableStrings})) { + if (!elementString) continue + elementString = elementString.toLowerCase() + + if (ddgMatcher.skip) { + let skipRegex = safeRegex(ddgMatcher.skip) + if (!skipRegex) { + return { matched: false } + } + if (skipRegex.test(elementString)) { + continue + } + } + + // Scoring to ensure all DDG tests are valid + let score = 0 + + // if the `match` regex fails, moves onto the next string + if (!matchRexExp.test(elementString)) { + continue + } + + // Otherwise, increment the score + score++ + + // If a negated regex was provided, ensure it does not match + // If it DOES match - then we need to prevent any future strategies from continuing + if (ddgMatcher.forceUnknown) { + let notRegex = safeRegex(ddgMatcher.forceUnknown) + if (!notRegex) { + return { matched: false } + } + if (notRegex.test(elementString)) { + return { matched: false, proceed: false } + } else { + // All good here, increment the score + score++ + } + } + + // If a 'maxDigits' rule was provided, validate it + if (ddgMatcher.maxDigits) { + const digitLength = elementString.replace(/[^0-9]/g, '').length + if (digitLength > ddgMatcher.maxDigits) { + return { matched: false } + } else { + score++ + } + } + + if (score === requiredScore) { + return { matched: true } + } + } + return { matched: false } + } + + /** + * If we get here, a firefox/vendor regex was given and we can execute it on the element + * strings + * @param {RegExp} regex + * @param {HTMLInputElement|HTMLSelectElement} el + * @param {HTMLFormElement} form + * @return {MatchingResult} + */ + execVendorRegex (regex, el, form) { + for (let elementString of this.getElementStrings(el, form)) { + if (!elementString) continue + elementString = elementString.toLowerCase() + if (regex.test(elementString)) { + return { matched: true } + } + } + return { matched: false } + } + + /** + * Yield strings in the order in which they should be checked against. + * + * Note: some strategies may not want to accept all strings, which is + * where `matchableStrings` helps. It defaults to when you see below but can + * be overridden. + * + * For example, `nameAttr` is first, since this has the highest chance of matching + * and then the rest are in decreasing order of value vs cost + * + * A generator function is used here to prevent any potentially expensive + * lookups occurring if they are rare. For example if 90% of all matching never needs + * to look at the output from `relatedText`, then the cost of computing it will be avoided. + * + * @param {HTMLInputElement|HTMLSelectElement} el + * @param {HTMLFormElement} form + * @param {{matchableStrings?: MatchableStrings[]}} [opts] + * @returns {Generator} + */ + * getElementStrings (el, form, opts = {}) { + let { + matchableStrings = ['nameAttr', 'labelText', 'placeholderAttr', 'id', 'relatedText'] + } = opts + for (let matchableString of matchableStrings) { + switch (matchableString) { + case 'nameAttr': { + yield el.name + break + } + case 'labelText': { + yield getExplicitLabelsText(el) + break + } + case 'placeholderAttr': { + if (el instanceof HTMLInputElement) { + yield el.placeholder || '' + } + break + } + case 'id': { + yield el.id + break + } + case 'relatedText': { + yield getRelatedText(el, form, this.cssSelector('FORM_INPUTS_SELECTOR')) + break + } + default: { + // a matchable string that wasn't handled + } + } + } + } + + /** + * Tries to infer if input is for password + * @param {HTMLInputElement} el + * @param {HTMLFormElement} form + */ + isPassword (el, form) { + const pwMatchers = this.matcherList('password') + return !!this.subtypeFromMatchers(pwMatchers, el, form) + } + + /** + * Tries to infer if input is for email + * @param {HTMLInputElement} el + * @param {HTMLFormElement} form + * @return {boolean} + */ + isEmail (el, form) { + const emailMatchers = this.matcherList('email') + return !!this.subtypeFromMatchers(emailMatchers, el, form) + } + + /** + * Tries to infer if input is for username + * @param {HTMLInputElement} el + * @param {HTMLFormElement} form + * @return {boolean} + */ + isUserName (el, form) { + const usernameMatchers = this.matcherList('username') + return !!this.subtypeFromMatchers(usernameMatchers, el, form) + } + + /** + * Tries to infer if it's a credit card form + * @param {HTMLFormElement} formEl + * @returns {boolean} + */ + isCCForm (formEl) { + const ccFieldSelector = this.joinCssSelectors('cc') + if (!ccFieldSelector) { + return false + } + const hasCCSelectorChild = formEl.querySelector(ccFieldSelector) + // If the form contains one of the specific selectors, we have high confidence + if (hasCCSelectorChild) return true + + // Read form attributes to find a signal + const hasCCAttribute = [...formEl.attributes].some(({name, value}) => + /(credit|payment).?card/i.test(`${name}=${value}`) + ) + if (hasCCAttribute) return true + + // Match form textContent against common cc fields (includes hidden labels) + const textMatches = formEl.textContent?.match(/(credit)?card(.?number)?|ccv|security.?code|cvv|cvc|csc/ig) + + // We check for more than one to minimise false positives + return Boolean(textMatches && textMatches.length > 1) + } + + /** + * @type {MatchingConfiguration} + */ + static emptyConfig = { + matchers: { + lists: {}, + fields: {} + }, + strategies: { + 'vendorRegex': { + rules: {}, + ruleSets: [] + }, + 'ddgMatcher': { + matchers: {} + }, + 'cssSelector': { + selectors: {} + } + } + } +} + +/** + * @returns {SupportedTypes} + */ +function getInputType (input) { + const attr = input.getAttribute(ATTR_INPUT_TYPE) + if (isValidSupportedType(attr)) { + return attr + } + return 'unknown' +} + +/** + * Retrieves the main type + * @param {SupportedTypes | string} type + * @returns {SupportedMainTypes} + */ +function getMainTypeFromType (type) { + const mainType = type.split('.')[0] + switch (mainType) { + case 'credentials': + case 'creditCard': + case 'identities': + return mainType + } + return 'unknown' +} + +/** + * Retrieves the input main type + * @param {HTMLInputElement} input + * @returns {SupportedMainTypes} + */ +const getInputMainType = (input) => + getMainTypeFromType(getInputType(input)) + +/** @typedef {supportedIdentitiesSubtypes[number]} SupportedIdentitiesSubTypes */ +const supportedIdentitiesSubtypes = /** @type {const} */ ([ + 'emailAddress', + 'firstName', + 'middleName', + 'lastName', + 'fullName', + 'phone', + 'addressStreet', + 'addressStreet2', + 'addressCity', + 'addressProvince', + 'addressPostalCode', + 'addressCountryCode', + 'birthdayDay', + 'birthdayMonth', + 'birthdayYear' +]) + +/** + * @param {SupportedTypes | any} supportedType + * @returns {supportedType is SupportedIdentitiesSubTypes} + */ +function isValidIdentitiesSubtype (supportedType) { + return supportedIdentitiesSubtypes.includes(supportedType) +} + +/** @typedef {supportedCreditCardSubtypes[number]} SupportedCreditCardSubTypes */ +const supportedCreditCardSubtypes = /** @type {const} */ ([ + 'cardName', + 'cardNumber', + 'cardSecurityCode', + 'expirationMonth', + 'expirationYear', + 'expiration' +]) + +/** + * @param {SupportedTypes | any} supportedType + * @returns {supportedType is SupportedCreditCardSubTypes} + */ +function isValidCreditCardSubtype (supportedType) { + return supportedCreditCardSubtypes.includes(supportedType) +} + +/** @typedef {supportedCredentialsSubtypes[number]} SupportedCredentialsSubTypes */ +const supportedCredentialsSubtypes = /** @type {const} */ ([ + 'password', + 'username' +]) + +/** + * @param {SupportedTypes | any} supportedType + * @returns {supportedType is SupportedCredentialsSubTypes} + */ +function isValidCredentialsSubtype (supportedType) { + return supportedCredentialsSubtypes.includes(supportedType) +} + +/** @typedef {SupportedIdentitiesSubTypes | SupportedCreditCardSubTypes | SupportedCredentialsSubTypes} SupportedSubTypes */ + +/** @typedef {`identities.${SupportedIdentitiesSubTypes}` | `creditCard.${SupportedCreditCardSubTypes}` | `credentials.${SupportedCredentialsSubTypes}` | 'unknown'} SupportedTypes */ +const supportedTypes = [ + ...supportedIdentitiesSubtypes.map((type) => `identities.${type}`), + ...supportedCreditCardSubtypes.map((type) => `creditCard.${type}`), + ...supportedCredentialsSubtypes.map((type) => `credentials.${type}`) +] + +/** + * Retrieves the subtype + * @param {SupportedTypes | string} type + * @returns {SupportedSubTypes | 'unknown'} + */ +function getSubtypeFromType (type) { + const subType = type?.split('.')[1] + const validType = isValidSubtype(subType) + return validType ? subType : 'unknown' +} + +/** + * @param {SupportedSubTypes | any} supportedSubType + * @returns {supportedSubType is SupportedSubTypes} + */ +function isValidSubtype (supportedSubType) { + return isValidIdentitiesSubtype(supportedSubType) || + isValidCreditCardSubtype(supportedSubType) || + isValidCredentialsSubtype(supportedSubType) +} + +/** + * @param {SupportedTypes | any} supportedType + * @returns {supportedType is SupportedTypes} + */ +function isValidSupportedType (supportedType) { + return supportedTypes.includes(supportedType) +} + +/** + * Retrieves the input subtype + * @param {HTMLInputElement|Element} input + * @returns {SupportedSubTypes | 'unknown'} + */ +function getInputSubtype (input) { + const type = getInputType(input) + return getSubtypeFromType(type) +} + +/** + * Remove whitespace of more than 2 in a row and trim the string + * @param string + * @return {string} + */ +const removeExcessWhitespace = (string = '') => { + return string + .replace(/\n/g, ' ') + .replace(/\s{2,}/, ' ').trim() +} + +/** + * Get text from all explicit labels + * @param {HTMLInputElement|HTMLSelectElement} el + * @return {string} + */ +const getExplicitLabelsText = (el) => { + const labelTextCandidates = [] + for (let label of el.labels || []) { + labelTextCandidates.push(...extractLabelStrings(label)) + } + if (el.hasAttribute('aria-label')) { + labelTextCandidates.push(el.getAttribute('aria-label')) + } + + // Try to access another element if it was marked as the label for this input/select + const ariaLabelAttr = el.getAttribute('aria-labelled') || el.getAttribute('aria-labelledby') || '' + const labelledByElement = document.getElementById(ariaLabelAttr) + + if (labelledByElement) { + labelTextCandidates.push(...extractLabelStrings(labelledByElement)) + } + + if (labelTextCandidates.length > 0) { + return removeExcessWhitespace(labelTextCandidates.join(' ')) + } + + return '' +} + +/** + * Get all text close to the input (useful when no labels are defined) + * @param {HTMLInputElement|HTMLSelectElement} el + * @param {HTMLFormElement} form + * @param {string} cssSelector + * @return {string} + */ +const getRelatedText = (el, form, cssSelector) => { + const container = getLargestMeaningfulContainer(el, form, cssSelector) + + // If there is no meaningful container return empty string + if (container === el || container.nodeName === 'SELECT') return '' + + // If the container has a select element, remove its contents to avoid noise + const noisyText = container.querySelector('select')?.textContent || '' + const sanitizedText = removeExcessWhitespace(container.textContent?.replace(noisyText, '')) + // If the text is longer than n chars it's too noisy and likely to yield false positives, so return '' + if (sanitizedText.length < TEXT_LENGTH_CUTOFF) return sanitizedText + return '' +} + +/** + * Find a container for the input field that won't contain other inputs (useful to get elements related to the field) + * @param {HTMLElement} el + * @param {HTMLFormElement} form + * @param {string} cssSelector + * @return {HTMLElement} + */ +const getLargestMeaningfulContainer = (el, form, cssSelector) => { + /* TODO: there could be more than one select el for the same label, in that case we should + change how we compute the container */ + const parentElement = el.parentElement + if (!parentElement || el === form) return el + + const inputsInParentsScope = parentElement.querySelectorAll(cssSelector) + // To avoid noise, ensure that our input is the only in scope + if (inputsInParentsScope.length === 1) { + return getLargestMeaningfulContainer(parentElement, form, cssSelector) + } + return el +} + +/** + * Find a regex match for a given input + * @param {HTMLInputElement} input + * @param {RegExp} regex + * @param {HTMLFormElement} form + * @param {string} cssSelector + * @returns {RegExpMatchArray|null} + */ +const matchInPlaceholderAndLabels = (input, regex, form, cssSelector) => { + return input.placeholder?.match(regex) || + getExplicitLabelsText(input).match(regex) || + getRelatedText(input, form, cssSelector).match(regex) +} + +/** + * Check if a given input matches a regex + * @param {HTMLInputElement} input + * @param {RegExp} regex + * @param {HTMLFormElement} form + * @param {string} cssSelector + * @returns {boolean} + */ +const checkPlaceholderAndLabels = (input, regex, form, cssSelector) => { + return !!matchInPlaceholderAndLabels(input, regex, form, cssSelector) +} + +/** + * Creating Regex instances can throw, so we add this to be + * @param {string} string + * @returns {RegExp | undefined} string + */ +const safeRegex = (string) => { + try { + // This is lower-cased here because giving a `i` on a regex flag is a performance problem in some cases + const input = String(string).toLowerCase().normalize('NFKC') + return new RegExp(input, 'u') + } catch (e) { + console.warn('Could not generate regex from string input', string) + return undefined + } +} + +module.exports = { + getInputType, + getInputSubtype, + getSubtypeFromType, + removeExcessWhitespace, + getInputMainType, + getMainTypeFromType, + getExplicitLabelsText, + getRelatedText, + matchInPlaceholderAndLabels, + checkPlaceholderAndLabels, + safeRegex, + Matching +} diff --git a/src/Form/matching.test.js b/src/Form/matching.test.js new file mode 100644 index 000000000..1d28ca554 --- /dev/null +++ b/src/Form/matching.test.js @@ -0,0 +1,175 @@ +const { Matching } = require('./matching') +const {matchingConfiguration} = require('./matching-configuration') + +const setFormHtml = (html) => { + document.body.innerHTML = ` +
+ ${html} +
+ ` + const formElement = document.querySelector('form') + if (!formElement) throw new Error('unreachable') + const inputs = Array.from(formElement?.querySelectorAll('input') || []) + const selects = Array.from(formElement?.querySelectorAll('select') || []) + const labels = Array.from(formElement?.querySelectorAll('label') || []) + return {formElement, inputs: [...inputs, ...selects], labels} +} + +beforeEach(() => { + document.body.innerHTML = '' +}) + +describe('css-selector matching', () => { + const selectors = matchingConfiguration.strategies.cssSelector.selectors + it.each([ + { html: ``, selector: selectors['email'], matched: true }, + { html: ``, selector: selectors['email'], matched: false } + ])(`$html: '$matched'`, (args) => { + const { html, matched, selector } = args + const { inputs } = setFormHtml(html) + + const matching = new Matching(matchingConfiguration) + const result = matching.execCssSelector(selector, inputs[0]) + expect(result.matched).toBe(matched) + }) +}) + +describe('ddg-matchers matching', () => { + const matchers = matchingConfiguration.strategies.ddgMatcher.matchers + it.each([ + { html: ``, matcher: matchers.email, matched: true }, + { html: ``, matcher: matchers.email, matched: false }, + { html: ``, matcher: matchers.email, matched: false } + ])(`$html: '$matcher': $matched`, (args) => { + const { html, matched, matcher } = args + const { inputs, formElement } = setFormHtml(html) + + const matching = new Matching(matchingConfiguration) + const result = matching.execDDGMatcher(matcher, inputs[0], formElement) + expect(result.matched).toBe(matched) + }) +}) + +describe('vendor-regexes matching', () => { + it.each([ + { html: ``, regexName: 'email', matched: true }, + { html: ``, regexName: 'email', matched: true }, + { html: ``, regexName: 'email', matched: true }, // fr + { html: ``, regexName: 'email', matched: true } // ja-JP + ])(`$html: '$regexName': $matched`, (args) => { + const { html, matched, regexName } = args + const { inputs, formElement } = setFormHtml(html) + + const matching = new Matching(matchingConfiguration) + const regex = matching.vendorRegex(regexName) + if (!regex) throw new Error('unreachable, vendor regex missing') + const result = matching.execVendorRegex(regex, inputs[0], formElement) + expect(result.matched).toBe(matched) + }) +}) + +describe('matching', () => { + it('default config', () => { + const matching = new Matching(Matching.emptyConfig) + const {formElement, inputs} = setFormHtml(``) + const actual = matching.inferInputType(inputs[0], formElement) + expect(actual).toBe('unknown') + }) + it.each([ + { html: ``, subtype: 'identities.emailAddress' }, + { html: ``, subtype: 'identities.phone' }, + { html: ``, subtype: 'identities.phone' }, + { html: ``, subtype: 'identities.lastName' }, + { html: ``, subtype: 'credentials.password' }, + { html: ``, subtype: 'unknown' }, + { html: ``, subtype: 'credentials.username' }, + { html: ``, subtype: 'unknown' }, + { html: ``, subtype: 'creditCard.cardName' }, + { html: ``, subtype: 'creditCard.cardName' }, + { html: ``, subtype: 'creditCard.expirationMonth' }, + { html: ``, subtype: 'identities.addressPostalCode' }, + { html: ``, subtype: 'identities.addressStreet2' }, + { html: ``, subtype: 'identities.addressStreet' }, + { html: ``, subtype: 'identities.emailAddress' }, + { + html: ``, + subtype: 'identities.addressCity' + }, + { + html: `
+ + +
`, + subtype: 'identities.addressStreet2' + }, + { + // This test has a new line between `First` and `name` -> which was previously not matching, but is now 😍 + html: ` + `, + subtype: 'identities.firstName' + }, + { + // This test has a script tag between `First` and `name` -> which was previously not matching, but is now 😍 + html: ` + `, + subtype: 'identities.firstName' + } + + ])(`$html should be '$subtype'`, (args) => { + const { html, subtype } = args + const { formElement, inputs } = setFormHtml(html) + + const matching = new Matching(matchingConfiguration) + const inferred = matching.inferInputType(inputs[0], formElement) + expect(inferred).toBe(subtype) + }) + it('should not continue past a ddg-matcher that has a "not" regex', () => { + const {formElement, inputs} = setFormHtml(``) + const matching = new Matching({ + matchers: { + lists: { + email: ['email'] + }, + fields: { + email: { + type: 'email', + strategies: { + ddgMatcher: 'email-ddg', + vendorRegex: 'email' + } + } + } + }, + strategies: { + 'vendorRegex': { + rules: { + email: null + }, + ruleSets: [ + { + email: 'email-' + } + ] + }, + 'ddgMatcher': { + matchers: { + 'email-ddg': { match: 'email', forceUnknown: 'search' } + } + }, + 'cssSelector': { + selectors: { + 'FORM_INPUTS_SELECTOR': 'input' + } + } + } + }) + const asEmail = matching.inferInputType(inputs[0], formElement) + /** + * This should be 'unknown' because the negated 'search' regex in teh ddg-matcher should prevent + * further strategies like the following vendor one + */ + expect(asEmail).toBe('unknown') + }) +}) diff --git a/src/Form/selectors-css.js b/src/Form/selectors-css.js new file mode 100644 index 000000000..8f1b1dfc9 --- /dev/null +++ b/src/Form/selectors-css.js @@ -0,0 +1,213 @@ +const FORM_INPUTS_SELECTOR = ` +input:not([type=submit]):not([type=button]):not([type=checkbox]):not([type=radio]):not([type=hidden]):not([type=file]), +select` + +const SUBMIT_BUTTON_SELECTOR = ` +input[type=submit], +input[type=button], +button:not([role=switch]):not([role=link]), +[role=button]` + +const email = ` +input:not([type])[name*=mail i], +input[type=""][name*=mail i], +input[type=text][name*=mail i], +input:not([type])[placeholder*=mail i]:not([placeholder*=search i]), +input[type=text][placeholder*=mail i]:not([placeholder*=search i]), +input[type=""][placeholder*=mail i]:not([placeholder*=search i]), +input:not([type])[placeholder*=mail i]:not([placeholder*=search i]), +input[type=email], +input[type=text][aria-label*=mail i]:not([aria-label*=search i]), +input:not([type])[aria-label*=mail i]:not([aria-label*=search i]), +input[type=text][placeholder*=mail i]:not([placeholder*=search i]), +input[autocomplete=email]` + +// We've seen non-standard types like 'user'. This selector should get them, too +const GENERIC_TEXT_FIELD = ` +input:not([type=button]):not([type=checkbox]):not([type=color]):not([type=date]):not([type=datetime-local]):not([type=datetime]):not([type=file]):not([type=hidden]):not([type=month]):not([type=number]):not([type=radio]):not([type=range]):not([type=reset]):not([type=search]):not([type=submit]):not([type=time]):not([type=url]):not([type=week])` + +const password = `input[type=password]:not([autocomplete*=cc]):not([autocomplete=one-time-code])` + +const cardName = ` +input[autocomplete="cc-name"], +input[autocomplete="ccname"], +input[name="ccname"], +input[name="cc-name"], +input[name="ppw-accountHolderName"], +input[id*=cardname i], +input[id*=card-name i], +input[id*=card_name i]` + +const cardNumber = ` +input[autocomplete="cc-number"], +input[autocomplete="ccnumber"], +input[autocomplete="cardnumber"], +input[autocomplete="card-number"], +input[name="ccnumber"], +input[name="cc-number"], +input[name="cardnumber"], +input[name="card-number"], +input[name*=creditCardNumber i], +input[id*=cardnumber i], +input[id*=card-number i], +input[id*=card_number i]` + +const cardSecurityCode = ` +input[autocomplete="cc-csc"], +input[autocomplete="csc"], +input[autocomplete="cc-cvc"], +input[autocomplete="cvc"], +input[name="cvc"], +input[name="cc-cvc"], +input[name="cc-csc"], +input[name="csc"], +input[name="securityCode"]` + +const expirationMonth = ` +[autocomplete="cc-exp-month"], +[name="ccmonth"], +[name="ppw-expirationDate_month"], +[name=cardExpiryMonth], +[name="expiration-month"], +[name*=ExpDate_Month i], +[id*=expiration-month i]` + +const expirationYear = ` +[autocomplete="cc-exp-year"], +[name="ccyear"], +[name="ppw-expirationDate_year"], +[name=cardExpiryYear], +[name="expiration-year"], +[name*=ExpDate_Year i], +[id*=expiration-year i]` + +const expiration = ` +[autocomplete="cc-exp"], +[name="cc-exp"], +[name="exp-date"], +[name="expirationDate"], +input[id*=expiration i]` + +const firstName = ` +[name*=fname i], [autocomplete*=given-name i], +[name*=firstname i], [autocomplete*=firstname i], +[name*=first-name i], [autocomplete*=first-name i], +[name*=first_name i], [autocomplete*=first_name i], +[name*=givenname i], [autocomplete*=givenname i], +[name*=given-name i], +[name*=given_name i], [autocomplete*=given_name i], +[name*=forename i], [autocomplete*=forename i]` + +const middleName = ` +[name*=mname i], [autocomplete*=additional-name i], +[name*=middlename i], [autocomplete*=middlename i], +[name*=middle-name i], [autocomplete*=middle-name i], +[name*=middle_name i], [autocomplete*=middle_name i], +[name*=additionalname i], [autocomplete*=additionalname i], +[name*=additional-name i], +[name*=additional_name i], [autocomplete*=additional_name i]` + +const lastName = ` +[name=lname], [autocomplete*=family-name i], +[name*=lastname i], [autocomplete*=lastname i], +[name*=last-name i], [autocomplete*=last-name i], +[name*=last_name i], [autocomplete*=last_name i], +[name*=familyname i], [autocomplete*=familyname i], +[name*=family-name i], +[name*=family_name i], [autocomplete*=family_name i], +[name*=surname i], [autocomplete*=surname i]` + +const fullName = ` +[name=name], [autocomplete=name], +[name*=fullname i], [autocomplete*=fullname i], +[name*=full-name i], [autocomplete*=full-name i], +[name*=full_name i], [autocomplete*=full_name i], +[name*=your-name i], [autocomplete*=your-name i]` + +const phone = ` +[name*=phone i], [name*=mobile i], [autocomplete=tel]` + +const addressStreet1 = ` +[name=address], [autocomplete=street-address], [autocomplete=address-line1], +[name=street], +[name=ppw-line1]` + +const addressStreet2 = ` +[name=address], [autocomplete=address-line2], +[name=ppw-line2]` + +const addressCity = ` +[name=city], [autocomplete=address-level2], +[name=ppw-city]` + +const addressProvince = ` +[name=province], [name=state], [autocomplete=address-level1]` + +const addressPostalCode = ` +[name=zip], [name=zip2], [name=postal], [autocomplete=postal-code], [autocomplete=zip-code], +[name*=postalCode i], [name*=zipcode i]` + +const addressCountryCode = ` +[name=country], [autocomplete=country], +[name*=countryCode i], [name*=country-code i], +[name*=countryName i], [name*=country-name i]` + +const birthdayDay = ` +[name=bday-day], +[name=birthday_day], [name=birthday-day], +[name=date_of_birth_day], [name=date-of-birth-day], +[name^=birthdate_d], [name^=birthdate-d]` + +const birthdayMonth = ` +[name=bday-month], +[name=birthday_month], [name=birthday-month], +[name=date_of_birth_month], [name=date-of-birth-month], +[name^=birthdate_m], [name^=birthdate-m]` + +const birthdayYear = ` +[name=bday-year], +[name=birthday_year], [name=birthday-year], +[name=date_of_birth_year], [name=date-of-birth-year], +[name^=birthdate_y], [name^=birthdate-y]` + +const username = [ + `${GENERIC_TEXT_FIELD}[autocomplete^=user]`, + // fix for `aa.com` + `input[name="loginId"]` +] + +// todo: these are still used directly right now, mostly in scanForInputs +// todo: ensure these can be set via configuration +module.exports.FORM_INPUTS_SELECTOR = FORM_INPUTS_SELECTOR +module.exports.SUBMIT_BUTTON_SELECTOR = SUBMIT_BUTTON_SELECTOR + +// Exported here for now, to be moved to configuration later +module.exports.__secret_do_not_use = { + GENERIC_TEXT_FIELD, + SUBMIT_BUTTON_SELECTOR, + FORM_INPUTS_SELECTOR, + email: email, + password, + username, + cardName, + cardNumber, + cardSecurityCode, + expirationMonth, + expirationYear, + expiration, + + firstName, + middleName, + lastName, + fullName, + phone, + addressStreet1, + addressStreet2, + addressCity, + addressProvince, + addressPostalCode, + addressCountryCode, + birthdayDay, + birthdayMonth, + birthdayYear +} diff --git a/src/Form/selectors.js b/src/Form/selectors.js deleted file mode 100644 index 0361925c0..000000000 --- a/src/Form/selectors.js +++ /dev/null @@ -1,169 +0,0 @@ -const EMAIL_SELECTOR = ` -input:not([type])[name*=mail i]:not([readonly]):not([disabled]):not([hidden]):not([aria-hidden=true]), -input[type=""][name*=mail i]:not([readonly]):not([disabled]):not([hidden]):not([aria-hidden=true]), -input[type=text][name*=mail i]:not([readonly]):not([disabled]):not([hidden]):not([aria-hidden=true]), -input:not([type])[id*=mail i]:not([readonly]):not([disabled]):not([hidden]):not([aria-hidden=true]), -input[type=""][id*=mail i]:not([readonly]):not([disabled]):not([hidden]):not([aria-hidden=true]), -input:not([type])[placeholder*=mail i]:not([placeholder*=search i]):not([readonly]):not([disabled]):not([hidden]):not([aria-hidden=true]), -input[type=text][placeholder*=mail i]:not([placeholder*=search i]):not([readonly]):not([disabled]):not([hidden]):not([aria-hidden=true]), -input[type=""][placeholder*=mail i]:not([placeholder*=search i]):not([readonly]):not([disabled]):not([hidden]):not([aria-hidden=true]), -input:not([type])[placeholder*=mail i]:not([placeholder*=search i]):not([readonly]):not([disabled]):not([hidden]):not([aria-hidden=true]), -input[type=email]:not([readonly]):not([disabled]):not([hidden]):not([aria-hidden=true]), -input[type=text][aria-label*=mail i]:not([aria-label*=search i]), -input:not([type])[aria-label*=mail i]:not([aria-label*=search i]), -input[type=text][placeholder*=mail i]:not([placeholder*=search i]):not([readonly]), -input[autocomplete=email]:not([readonly]):not([hidden]):not([disabled])` - -/** @type Matcher */ -const EMAIL_MATCHER = { - type: 'email', - selector: EMAIL_SELECTOR, - regex: /.mail/i, - negativeRegex: /search/i -} - -// We've seen non-standard types like 'user'. This selector should get them, too -const GENERIC_TEXT_FIELD = ` -input:not([type=button]):not([type=checkbox]):not([type=color]):not([type=date]):not([type=datetime-local]):not([type=datetime]):not([type=file]):not([type=hidden]):not([type=month]):not([type=number]):not([type=radio]):not([type=range]):not([type=reset]):not([type=search]):not([type=submit]):not([type=tel]):not([type=time]):not([type=url]):not([type=week]):not([readonly]):not([disabled])` - -const PASSWORD_SELECTOR = `input[type=password]:not([autocomplete*=cc]):not([autocomplete=one-time-code])` - -/** @type Matcher */ -const PASSWORD_MATCHER = { - type: 'password', - selector: PASSWORD_SELECTOR, - regex: /password/i, - negativeRegex: /captcha/i -} - -// This is more generic, used only when we have identified a form -const USERNAME_SELECTOR = `${GENERIC_TEXT_FIELD}[autocomplete^=user]` - -/** @type Matcher */ -const USERNAME_MATCHER = { - type: 'username', - selector: USERNAME_SELECTOR, - regex: /user((.)?name)?$/i, - negativeRegex: /search/i -} - -const CC_NAME_SELECTOR = ` -input[autocomplete="cc-name"], -input[autocomplete="ccname"], -input[name="ccname"], -input[name="cc-name"], -input[name="ppw-accountHolderName"], -input[id*=cardname i], -input[id*=card-name i], -input[id*=card_name i]` - -const CC_NUMBER_SELECTOR = ` -input[autocomplete="cc-number"], -input[autocomplete="ccnumber"], -input[autocomplete="cardnumber"], -input[autocomplete="card-number"], -input[name="ccnumber"], -input[name="cc-number"], -input[name="cardnumber"], -input[name="card-number"], -input[name="creditCardNumber"], -input[name="addCreditCardNumber"], -input[id*=cardnumber i], -input[id*=card-number i], -input[id*=card_number i]` - -const CC_CVC_SELECTOR = ` -input[autocomplete="cc-csc"], -input[autocomplete="csc"], -input[autocomplete="cc-cvc"], -input[autocomplete="cvc"], -input[name="cvc"], -input[name="cc-cvc"], -input[name="cc-csc"], -input[name="csc"], -input[name="securityCode"]` - -const CC_MONTH_SELECTOR = ` -[autocomplete="cc-exp-month"], -[name="ccmonth"], -[name="ppw-expirationDate_month"]` - -const CC_YEAR_SELECTOR = ` -[autocomplete="cc-exp-year"], -[name="ccyear"], -[name="ppw-expirationDate_year"]` - -const CC_EXP_SELECTOR = ` -[autocomplete="cc-exp"], -[name="exp-date"], -[name="expirationDate"], -input[id*=expiration i], -select[id*=expiration i]` - -// Matches strings like mm/yy, mm-yyyy, mm-aa -const DATE_SEPARATOR_REGEX = /\w\w\s?(?[/\s.\-_—–])\s?\w\w/i -// Matches 4 non-digit repeated characters (YYYY or AAAA) or 4 digits (2022) -const FOUR_DIGIT_YEAR_REGEX = /(\D)\1{3}|\d{4}/i - -/** - * This is used to map a selector with the data type we store for credit cards - * @type {[Matcher]} - */ -const CC_MATCHERS_LIST = [ - { - type: 'cardName', - selector: CC_NAME_SELECTOR, - regex: /(card.*name|name.*card)|(card.*holder|holder.*card)|(card.*owner|owner.*card)/i - }, - { - type: 'cardNumber', - selector: CC_NUMBER_SELECTOR, - regex: /card.*number|number.*card/i - }, - { - type: 'cardSecurityCode', - selector: CC_CVC_SELECTOR, - regex: /security.?code|cvv|csc|cvc/i - }, - { - type: 'expirationMonth', - selector: CC_MONTH_SELECTOR, - regex: /(card|cc)?.?(exp(iry|iration)?)?.?(month|mm(?![.\s/-]yy))/i, - negativeRegex: /mm[/\s.\-_—–]/i - }, - { - type: 'expirationYear', - selector: CC_YEAR_SELECTOR, - regex: /(card|cc)?.?(exp(iry|iration)?)?.?(ye(ar)?|yy)/i, - negativeRegex: /mm[/\s.\-_—–]/i - }, - { - type: 'expiration', - selector: CC_EXP_SELECTOR, - regex: /(mm|\d\d)[/\s.\-_—–](yy|jj|aa|\d\d)|exp|valid/i, - negativeRegex: /invalid/i - } -] - -const CC_FIELD_SELECTOR = CC_MATCHERS_LIST.map(({selector}) => selector).join(', ') - -const FIELD_SELECTOR = [PASSWORD_SELECTOR, GENERIC_TEXT_FIELD, EMAIL_SELECTOR, CC_FIELD_SELECTOR].join(', ') - -const SUBMIT_BUTTON_SELECTOR = ` -input[type=submit], -input[type=button], -button:not([role=switch]):not([role=link]), -[role=button]` - -module.exports = { - PASSWORD_SELECTOR, - EMAIL_MATCHER, - PASSWORD_MATCHER, - USERNAME_MATCHER, - FOUR_DIGIT_YEAR_REGEX, - CC_MATCHERS_LIST, - DATE_SEPARATOR_REGEX, - CC_FIELD_SELECTOR, - FIELD_SELECTOR, - SUBMIT_BUTTON_SELECTOR -} diff --git a/src/Form/test-cases/aa_login.html b/src/Form/test-cases/aa_login.html new file mode 100644 index 000000000..3448584c9 --- /dev/null +++ b/src/Form/test-cases/aa_login.html @@ -0,0 +1,83 @@ +
+ + + + + + +
+ + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + +
+
+
+
+ + +
+
+
+

+ + Need help logging in? + + +

+
+
diff --git a/src/Form/test-cases/allrecipes_login_signup.html b/src/Form/test-cases/allrecipes_login_signup.html new file mode 100644 index 000000000..bcd811aad --- /dev/null +++ b/src/Form/test-cases/allrecipes_login_signup.html @@ -0,0 +1,39 @@ + +
+
+ + +
+
+
+
+ +
+
+ +
+ + + +
+
+
+
+ +
+
+ + + + + +
+ Uncheck if using a public device. +
+
+ + +
\ No newline at end of file diff --git a/src/Form/test-cases/amazon_address.html b/src/Form/test-cases/amazon_address.html new file mode 100644 index 000000000..cb55a1909 --- /dev/null +++ b/src/Form/test-cases/amazon_address.html @@ -0,0 +1,118 @@ + +
+
+

Add a new address

+
+
+
+
+
+
+ + +
+ +
+
+
+
+
+
+
+
+
Why? + +
+
+
+
+
+
+
+
+
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    + + +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    + +
    + +
    + + +
    \ No newline at end of file diff --git a/src/Form/test-cases/amazon_card.html b/src/Form/test-cases/amazon_card.html new file mode 100644 index 000000000..5e577225d --- /dev/null +++ b/src/Form/test-cases/amazon_card.html @@ -0,0 +1,44 @@ + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    Your card does not have an expiration date
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/amazon_login.html b/src/Form/test-cases/amazon_login.html new file mode 100644 index 000000000..36c9d7c34 --- /dev/null +++ b/src/Form/test-cases/amazon_login.html @@ -0,0 +1,92 @@ +
    + + + + + + + + + +
    +
    +
    +

    + Sign-In +

    + + +
    + + + + + + + + +
    + + + +
    + + + + +
    + By continuing, you agree to Amazon's Conditions of Use and Privacy Notice. +
    + + + + + +
    + + + +
    +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/amazon_signup.html b/src/Form/test-cases/amazon_signup.html new file mode 100644 index 000000000..4caa30b03 --- /dev/null +++ b/src/Form/test-cases/amazon_signup.html @@ -0,0 +1,207 @@ + + + + + + + + + + + + +
    +
    +

    + Create account +

    + + + +
    + + + + + + + +
    + +
    + +
    + + + + + + + + + + + + + + + +
    +
    + +
    + +
    + + + + + +
    +
    +
    + Passwords must be at least 6 characters. +
    +
    +
    + + + + + +
    + +
    + + + + + + + + + +
    + +
    + +
    + + + + + + + + +
    + By creating an account, you agree to Amazon's Conditions of Use and Privacy Notice. +
    + +
    + +
    +
    +
    + +
    + Already have an account? + + Sign-In + +
    + + + +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/apple_checkout.html b/src/Form/test-cases/apple_checkout.html new file mode 100644 index 000000000..0401c01b8 --- /dev/null +++ b/src/Form/test-cases/apple_checkout.html @@ -0,0 +1,459 @@ + + +
    +
    +

    Where should we send your order?

    +
    +
    +
    + +

    Enter your name and address:

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +

    What’s your contact information?

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    We’ll email you a receipt and send order updates to your + mobile phone via SMS or iMessage.
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    The phone number you enter can’t be changed after you place + your order, so please make sure it’s correct.
    +
    +
    +
    +
    +
    +
    +
    +
    Share shipping updates with someone else:
    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + + + +
    +
    +
    +
    +
      + + + + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    Paying with Apple + Card?
    +
    +
    +
    diff --git a/src/Form/test-cases/apple_login.html b/src/Form/test-cases/apple_login.html new file mode 100644 index 000000000..c451f0f1c --- /dev/null +++ b/src/Form/test-cases/apple_login.html @@ -0,0 +1,42 @@ + + \ No newline at end of file diff --git a/src/Form/test-cases/apple_signup.html b/src/Form/test-cases/apple_signup.html new file mode 100644 index 000000000..6b35c56b7 --- /dev/null +++ b/src/Form/test-cases/apple_signup.html @@ -0,0 +1,2773 @@ + +
    +
    + +

    Create Your Apple ID

    +
    One Apple ID is all you need to access all Apple services. +
    + + +
    + + +
    +
    + +
    +
    + + +
    +
    + + + +
    + This will be your new Apple ID. +
    + +
    +
    +
    +
    +
    + + +
    +
    + + +
    +
    + +
    + + + +
    +
    +
    +
    +
    + + +
    +
    + +
    + + +
    + +
    + + + +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    + +
    + + +
    + +
    + + +
    + + + + + + + +
    + +
    +
    +
    +
    + + +
    + +
    + + + +
    + +
    +
    +
    +
    +
    + +
    + + + + + + + + + + + + + + +
    +
    +
    +
    +
    Be sure to enter + a phone number you can always access. It will be used to verify your identity + any time you sign in on a new device or web browser. Messaging or data rates may + apply. +
    +
    +
    +
    +
    + +
    +
    Verify with:
    +
    +
    + + +
    +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    + +
    +
    + + +
    + +
    + + +
    +
    + + +
    + +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + +
    + +
    + Image challenge +
    + + +
    +
    +
    +
    +
    +
    +
    + +
    + + +
    + +
    + + + +
    + +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    + + Your Apple ID information is used to allow you to sign in securely and access your data. Apple records + certain usage data for security, support, and reporting purposes. See how your data is managed. Opens in a new window. +
    + + + + + +
    \ No newline at end of file diff --git a/src/Form/test-cases/asana_search.html b/src/Form/test-cases/asana_search.html new file mode 100644 index 000000000..133e9f19a --- /dev/null +++ b/src/Form/test-cases/asana_search.html @@ -0,0 +1,2 @@ + +
    diff --git a/src/Form/test-cases/asana_tasklist.html b/src/Form/test-cases/asana_tasklist.html new file mode 100644 index 000000000..a41f34bb7 --- /dev/null +++ b/src/Form/test-cases/asana_tasklist.html @@ -0,0 +1,2 @@ + +
    3
    Details
    Mateusz
    diff --git a/src/Form/test-cases/bestbuy_checkout.html b/src/Form/test-cases/bestbuy_checkout.html new file mode 100644 index 000000000..1a64a19cc --- /dev/null +++ b/src/Form/test-cases/bestbuy_checkout.html @@ -0,0 +1,370 @@ + + + +
    +

    Contact Information

    +
    +

    We’ll send your order confirmation to this email and use the following phone number only if we have + questions or problems fulfilling your order.

    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    +
    +

    Credit or Debit Card

    +
    + +
    DISCOVERPlease enter a valid card number.
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + +
    +

    Billing Address

    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    + +
    +
    +
    +

    Want to help us fight childhood cancer?

    +
    +
    St. Jude Children's Research Hospital
    +
    +
    $2 donations can provide IV bags for patients undergoing treatment.
    +
    $5 donations can provide thermometers and snack bags for families.
    +
    $10 donations can provide new toys for play areas and housing facilities. +
    +
    +
    +
    + Choose a donation + amount: +
    +
    +
    +
    + +
    +
    +
    View full Order + Summary +
    +
    +
    +
    +
    +
    By placing your order, you agree to our and our .
    +
    +
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/bestbuy_login.html b/src/Form/test-cases/bestbuy_login.html new file mode 100644 index 000000000..50710d1b2 --- /dev/null +++ b/src/Form/test-cases/bestbuy_login.html @@ -0,0 +1,31 @@ + +
    \ No newline at end of file diff --git a/src/Form/test-cases/bestbuy_signup.html b/src/Form/test-cases/bestbuy_signup.html new file mode 100644 index 000000000..043f6ed75 --- /dev/null +++ b/src/Form/test-cases/bestbuy_signup.html @@ -0,0 +1,116 @@ + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    Hide + Passwords selectedWarning: Pressing this button will + display the password in the Password field +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    By continuing you agree to our Terms and Conditions, our Privacy + Policy, and the My Best Buy® Program Terms., + + Terms and Conditions + + + Privacy Policy + + + My Best Buy Program Terms + +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/britannica_login.html b/src/Form/test-cases/britannica_login.html new file mode 100644 index 000000000..abfdadfb4 --- /dev/null +++ b/src/Form/test-cases/britannica_login.html @@ -0,0 +1,30 @@ + +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/britannica_signup.html b/src/Form/test-cases/britannica_signup.html new file mode 100644 index 000000000..23d453673 --- /dev/null +++ b/src/Form/test-cases/britannica_signup.html @@ -0,0 +1,49 @@ + +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Username is not case sensitive.

    +
    +
    +

    Password must be at least 8 characters long, contain both + uppercase and lowercase letters, contain at least one number, and contain at least one special character. +

    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/chewy_checkout.html b/src/Form/test-cases/chewy_checkout.html new file mode 100644 index 000000000..4a276e687 --- /dev/null +++ b/src/Form/test-cases/chewy_checkout.html @@ -0,0 +1,1031 @@ + + +
    + + + + + +
    +
    +
    +

    Your Shipping + Address

    + +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    + +
    + + + + +
    + + + +
    +
    +
    + + + +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    +
    +
    + + + +
    +
    +
    + +
    +
    +
    +
    +
    +

    + +

    +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    + + +
    +
    +
    +
    +
    +

    Start your first order and + save 35% + ($18.37) today! Plus, save 5% on eligible items on future Autoship + orders. More Info +

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + +
    +
    +

    You'll save an additional $18.37 on this order!

    +
    +
    +
    +
    + + + +
    +

    You can easily change, + cancel, or reschedule shipments at any time.

    +
    +
    +
      +
    • +
      +
      +
      + + + +
      Purina Pro Plan Adult Sensitive Skin & Stomach Salmon & Rice Formula Dry Dog Food, 30-lb bag +
      + +
      +
      + +
      +
    • +
    +
    +
    + +

    Maximum $20 savings on 35% off + Autoship promotion. For Autoship-eligible items only. Some exclusions apply. For + a limited time.

    +
    +
    +
    +
    +
    +
    + + + +
    +
    +

    Your items will only ship once.

    +
    +
    +
    +
    +
    + + +
    +
    +
    + +
    + + + +
    +
    +

    +
    +
    + + + +
    +

    + +
    +
    +
    + + + +
    +
    + +
    +
    +
    +

    +
    Your Payment Information
    +

    + +
    +
    +
    + + +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    + +
    +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    +
    + + + +
    / +
    +
    + + + +
    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    + + + +
    +
    +

    + Billing Address:

    +

    Shipping address + is incomplete

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    + +
    +
    +
    + + + +
    + +
    +
    +
    +
    +
    + +
    + +
    +
    + +

    + Order Total:$52.48

    +
    +
    + +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/chewy_login.html b/src/Form/test-cases/chewy_login.html new file mode 100644 index 000000000..756f093f7 --- /dev/null +++ b/src/Form/test-cases/chewy_login.html @@ -0,0 +1,33 @@ + +
    +
      +
    1. + +
      + +
      +
    2. + +
    3. + +
      + +
      +
    4. +
    5. + + Forgot your password? +
    6. + +
    + + + + + + + +
    \ No newline at end of file diff --git a/src/Form/test-cases/chewy_signup.html b/src/Form/test-cases/chewy_signup.html new file mode 100644 index 000000000..7dd71480b --- /dev/null +++ b/src/Form/test-cases/chewy_signup.html @@ -0,0 +1,57 @@ + +
    +
    +
      +
    • + +
      + +
      +
    • +
    • + +
      + +
      +
    • +
    • + +
      + +
      +
    • +
    • + +
      + +
      +
    • +
    + + +
    +
    + Already have an account? +
    + +
    + + + + + + + +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/cnn_newsletter.html b/src/Form/test-cases/cnn_newsletter.html new file mode 100644 index 000000000..838812070 --- /dev/null +++ b/src/Form/test-cases/cnn_newsletter.html @@ -0,0 +1,11 @@ + + \ No newline at end of file diff --git a/src/Form/test-cases/costco_checkout.html b/src/Form/test-cases/costco_checkout.html new file mode 100644 index 000000000..1d9842640 --- /dev/null +++ b/src/Form/test-cases/costco_checkout.html @@ -0,0 +1,547 @@ + + + + +
    + + + + + + + +
    + + +
    +
    +
    + + + +

    + Shipping Address +

    +
    +
    +
    + + + +
    +
    +
    +
    +
    +
    +
    + Shipping Address +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +

    Street addresses are limited to 30 characters. Try abbreviating + roads and directions (e.g., Ave for Avenue, NW for Northwest).

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    + + + +
    +
    +
    + + +
    +
    +
    + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + + By entering a phone number, you give Costco consent to text and/or call for + purposes regarding this order only. + + + + +
    +
    +
    +
    +
    +
    +
    + +
    + +
    + +
    +
    + + By entering a phone number, you give Costco consent to text and/or call for + purposes regarding this order only. + + + + + + + +
    +
    +
    +
    +
    +
    +
    + +
    + + + + + + + + +
    + +
    + + +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +
    + + CUP: China Union Pay + JCB + Diners Club International + Discover + Mastercard + VISA + +
    +
    + +
    +
    + + + + + + + + + + +
    +
    + +
    +
    +
    + + +
    + +
    + +
    + + + + + + + + + + +
    3 digit security code on the back of your + card.
    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    +
    +
    diff --git a/src/Form/test-cases/costco_login.html b/src/Form/test-cases/costco_login.html new file mode 100644 index 000000000..70d6effbe --- /dev/null +++ b/src/Form/test-cases/costco_login.html @@ -0,0 +1,40 @@ + +
    + + +
    +
    + + + +
    +
    visibility
    +
    + + +
    + + +
    + + +
    + +
    +

    OR

    +
    +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/costco_signup.html b/src/Form/test-cases/costco_signup.html new file mode 100644 index 000000000..343dde456 --- /dev/null +++ b/src/Form/test-cases/costco_signup.html @@ -0,0 +1,29 @@ + + +
    + + + + +
    + +
    +
    + +

  • What is this?
  • + +
    +
    +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/craigslist_account.html b/src/Form/test-cases/craigslist_account.html new file mode 100644 index 000000000..e37afa88b --- /dev/null +++ b/src/Form/test-cases/craigslist_account.html @@ -0,0 +1,56 @@ + \ No newline at end of file diff --git a/src/Form/test-cases/ebay_checkout.html b/src/Form/test-cases/ebay_checkout.html new file mode 100644 index 000000000..2b00a7d89 --- /dev/null +++ b/src/Form/test-cases/ebay_checkout.html @@ -0,0 +1,68 @@ + +
    Your payment is secure. Your card details will not be shared with sellers. + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    Visa, Mastercard, or Discover + +
    +
      +
    • This 3-digit number is on the back of the card next to the signature panel. + +
    • +
    +
    American Express + +
    +
      +
    • This 4-digit number is on the front of the card above the credit card number. + +
    • +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/ebay_login.html b/src/Form/test-cases/ebay_login.html new file mode 100644 index 000000000..4e8131dfd --- /dev/null +++ b/src/Form/test-cases/ebay_login.html @@ -0,0 +1,27 @@ + +
    +
    +
    +
    +
    +

    +
    +
    +
    +
    +
    +
    +

    + +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/ebay_signup.html b/src/Form/test-cases/ebay_signup.html new file mode 100644 index 000000000..79f408d74 --- /dev/null +++ b/src/Form/test-cases/ebay_signup.html @@ -0,0 +1,31 @@ + +module.exports = ` +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +

    By Creating an account, you agree to our User Agreement and acknowledge reading our User Privacy Notice.

    +
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/espn_login.html b/src/Form/test-cases/espn_login.html new file mode 100644 index 000000000..00448a43f --- /dev/null +++ b/src/Form/test-cases/espn_login.html @@ -0,0 +1,59 @@ +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + +
    + + + + + + +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/espn_signup.html b/src/Form/test-cases/espn_signup.html new file mode 100644 index 000000000..e0ee73e5e --- /dev/null +++ b/src/Form/test-cases/espn_signup.html @@ -0,0 +1,246 @@ +
    + +

    Create Account

    + +
    + +
    + + + + +
    +
    + +
    + + +
    + + +
    +

    Please send me occasional + information and offers about my favorite teams, sports and other information from:

    +
    + +
    + +
    + +
    + +
    + + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/etsy_checkout.html b/src/Form/test-cases/etsy_checkout.html new file mode 100644 index 000000000..95e14e63f --- /dev/null +++ b/src/Form/test-cases/etsy_checkout.html @@ -0,0 +1,1062 @@ +
    +
    +
    +
    + +
    +
    + + +
    + You must enter a valid name. +
    +
    +
    +
    +
    + +
    +
    + + + + + +
    + + + + +
    +
    + Please enter a valid card number. +
    +
    +
    +
    +
    + +
    +
    +
    + + +
    + +
    + + +
    +
    + +
    + You must enter a valid expiration date +
    +
    +
    +
    +
    +
    + + +
    +
    + + + + +
    +
    + + + + + + Your security code is a three digit number on the back of your card. + + + + +
    +
    +
    + Please enter a valid security code. +
    +
    +
    +
    +
    + +
    +
    + + +
    +
    + + +
    +
    +

    + Enter your billing address +

    +
    + + + +
    +
    + +
    + +
    + +
    +
    +
    +
    + + +
    +

    Please enter a full name.

    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + +
    + + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    + +
    \ No newline at end of file diff --git a/src/Form/test-cases/etsy_login.html b/src/Form/test-cases/etsy_login.html new file mode 100644 index 000000000..3e90998f6 --- /dev/null +++ b/src/Form/test-cases/etsy_login.html @@ -0,0 +1,86 @@ +
    +
    +
    +

    + Sign in +

    + +
    + +
    + + +
    + + +
    +
    + +
    + + +
    +
    + + + + +
    +

    Captcha failed to load. Try using a different browser or disabling ad blockers.

    +
    + + + +
    +
    +
    + + +
    +
    + +
    + +
    +
    + +
    + +
    +
    +
    + +

    + + Trouble signing in? + +

    + +
    \ No newline at end of file diff --git a/src/Form/test-cases/etsy_signup.html b/src/Form/test-cases/etsy_signup.html new file mode 100644 index 000000000..b71fdaefd --- /dev/null +++ b/src/Form/test-cases/etsy_signup.html @@ -0,0 +1,74 @@ +
    +
    +
    +
    +

    + Create your account +

    + +
    + +

    Registration is easy.

    +
    + + +
    + + +
    +
    +
    + + +
    +
    +
    + + +
    +
    + + + + +
    +

    Captcha failed to load. Try using a different browser or disabling ad blockers. +

    +
    + + + +
    +
    + +
    + +
    +
    +
    + + +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/everydayoil_checkout.html b/src/Form/test-cases/everydayoil_checkout.html new file mode 100644 index 000000000..46498e668 --- /dev/null +++ b/src/Form/test-cases/everydayoil_checkout.html @@ -0,0 +1,926 @@ + + + +
    + + + + +
    + +
    +
    +
    +

    + Contact information +

    + +

    + Already have an account? + + Log in + +

    +
    +
    +
    +
    +
    + +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + +
    + +
    +
    + +
    +
    +
    +
    + + +
    +
    +

    + Shipping address +

    +
    + + +
    +
    +
    + + + + + + + + + + + + + + + + + + + +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + + +

    + + Add a house number if you have one +

    +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    + +
    +
    +
    + + + + + +
    + +
    + +
    + +
    +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    In case we need to contact you about your + order
    +
    +
    +
    +
    + + + +
    + + +
    +
    + + + + + + + +
    + + + + +
    + + + + +
    + + + + +
    + + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    +
    +
    All transactions are secure and encrypted.
    +
    +
    +
    +
    + + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    +
    +
    + +
    + + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + Card expiration date in format: month, month, year, year + + + + + + + + + + + + + + + + + + +
    + +
    +
    +
    +
    + + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3-digit security code usually found on the back of your card. American Express cards have a 4-digit code located on the front. + + + + + + + + + + + + + +
    + +
    +
    +
    + + + 3-digit security code usually found on the back of your card. American Express cards have a 4-digit code located on the front. + + + + +
    +
    +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/facebook_login.html b/src/Form/test-cases/facebook_login.html new file mode 100644 index 000000000..bb9a78c06 --- /dev/null +++ b/src/Form/test-cases/facebook_login.html @@ -0,0 +1,21 @@ + +
    +
    +
    +
    +
    + +
    +
    +
    +
    + +
    + +
    \ No newline at end of file diff --git a/src/Form/test-cases/facebook_signup.html b/src/Form/test-cases/facebook_signup.html new file mode 100644 index 000000000..2984c9524 --- /dev/null +++ b/src/Form/test-cases/facebook_signup.html @@ -0,0 +1,99 @@ + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    Birthday
    +
    +
    +
    +
    +
    +
    Age
    +
    Use date of birth
    +
    +
    +
    +
    Gender
    +
    +
    +
    +
    +
    Your pronoun is visible to everyone.
    +
    +
    +
    +
    +
    +
    +
    +

    By clicking Sign Up, you agree to our Terms, Data Policy and Cookies Policy. You may receive SMS Notifications from us and can opt out any time.

    +
    +
    +
    +
    +
    +

    Security check

    +
    +
    +
    This field is required.
    +
    +
    +
    Why am I seeing this? +
    +
    Security check
    This is a standard security test that we use to prevent spammers from sending automated requests.
    +
    +
    +
    +
    +
    +
    +
     
    Back
    +
    +
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/fandom_login.html b/src/Form/test-cases/fandom_login.html new file mode 100644 index 000000000..61598a16b --- /dev/null +++ b/src/Form/test-cases/fandom_login.html @@ -0,0 +1,17 @@ + +
    +
    + + +
    +
    + + + + Forgot password? +
    + + +
    \ No newline at end of file diff --git a/src/Form/test-cases/fandom_signup.html b/src/Form/test-cases/fandom_signup.html new file mode 100644 index 000000000..59242b45e --- /dev/null +++ b/src/Form/test-cases/fandom_signup.html @@ -0,0 +1,37 @@ + +
    +
    + + +
    +
    + + +
    +
    + + + +
    +
    +
    + + / + + / + + +
    + + +
    + + + + + + By creating an account, you agree to FANDOM's Terms of Use and Privacy Policy + +
    \ No newline at end of file diff --git a/src/Form/test-cases/fox_login.html b/src/Form/test-cases/fox_login.html new file mode 100644 index 000000000..b68ee009e --- /dev/null +++ b/src/Form/test-cases/fox_login.html @@ -0,0 +1,30 @@ + + \ No newline at end of file diff --git a/src/Form/test-cases/fox_signup.html b/src/Form/test-cases/fox_signup.html new file mode 100644 index 000000000..c4d053c4e --- /dev/null +++ b/src/Form/test-cases/fox_signup.html @@ -0,0 +1,232 @@ + + \ No newline at end of file diff --git a/src/Form/test-cases/google_login.html b/src/Form/test-cases/google_login.html new file mode 100644 index 000000000..5c0113091 --- /dev/null +++ b/src/Form/test-cases/google_login.html @@ -0,0 +1,190 @@ + \ No newline at end of file diff --git a/src/Form/test-cases/google_signup.html b/src/Form/test-cases/google_signup.html new file mode 100644 index 000000000..e154440ea --- /dev/null +++ b/src/Form/test-cases/google_signup.html @@ -0,0 +1,284 @@ + \ No newline at end of file diff --git a/src/Form/test-cases/google_store_checkout.html b/src/Form/test-cases/google_store_checkout.html new file mode 100644 index 000000000..3a0b46c64 --- /dev/null +++ b/src/Form/test-cases/google_store_checkout.html @@ -0,0 +1,2981 @@ + +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    Pixel 6 Pro Stormy Black 128GB (Unlocked)  product image
    +
    +
    +
    Pixel 6 Pro Stormy + Black 128GB (Unlocked)
    +
    +
    +
    Quantity: + 1
    +
    +
    +
    +
    +
    $899.00
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +
    +

    Provide contact email +

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Contact + email address is a required field +

    + + +
    + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + +
    + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +
    +

    Name and shipping + address

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    + Choose + shipping address

    +
    +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    +
    + +
    + +
    +
    +
    +
    +
    +
    +

    + Name + is + required +

    + + +
    +
    +
    +
    +
    +
    +
    + +
    + +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    +
    +
    +
    + +
    + +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    +
    +
    +
    + +
    + +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    + +
    + +
    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    +
    +
    +
    + +
    + + + +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    Standard $0.00
    +
    +
    +
    +
    Delivery: + Feb 3 – 5
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    Priority $13.99
    +
    +
    +
    +
    Delivery: + Feb 2 – 3
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    Expedited $18.99
    +
    +
    +
    +
    Delivery: + Feb 1 – 2
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    + +
    +
    + + +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + Google Pay
    +
    +
    +
    Add + credit or debit card
    +
    +
    +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    Amex +
    +
    Discover +
    +
    JCB +
    +
    Mastercard +
    +
    Visa +
    +
    +
    +
    +
    +

    Card number is + required

    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + +
    / +
    +
    +
    +
    +
    +
    +
    + + + +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +

    Add a promo + code

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + +
    + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    Apply +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    Price
    +
    +
    +
    $899.00
    +
    +
    +
    +
    +
    +
    +
    Standard
    +
    +
    +
    $0.00
    +
    +
    +
    +
    +
    +
    +
    Total
    +
    +
    +
    $899.00
    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    By clicking "CONFIRM PURCHASE", you + are indicating that YOU HAVE READ AND AGREE TO THE GOOGLE STORE SALES TERMS, INCLUDING THE ARBITRATION + CLAUSE LINKED HERE, meaning that any dispute related to your + device and/or subscription services purchased from the Google Store will be resolved + through BINDING ARBITRATION on an individual, non-class basis.
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    + + +
    + +
    +
    +
    +
    + Save changes +
    + +
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/healthline_newsletter.html b/src/Form/test-cases/healthline_newsletter.html new file mode 100644 index 000000000..8cebb83ac --- /dev/null +++ b/src/Form/test-cases/healthline_newsletter.html @@ -0,0 +1,4 @@ +
    \ No newline at end of file diff --git a/src/Form/test-cases/homedepot_login.html b/src/Form/test-cases/homedepot_login.html new file mode 100644 index 000000000..3798f9e5a --- /dev/null +++ b/src/Form/test-cases/homedepot_login.html @@ -0,0 +1,10 @@ + +
    +
    + +
    \ No newline at end of file diff --git a/src/Form/test-cases/homedepot_signup.html b/src/Form/test-cases/homedepot_signup.html new file mode 100644 index 000000000..7897769c0 --- /dev/null +++ b/src/Form/test-cases/homedepot_signup.html @@ -0,0 +1,65 @@ + +
    +
    Please provide your email address.
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/idme_login.html b/src/Form/test-cases/idme_login.html new file mode 100644 index 000000000..846e14a53 --- /dev/null +++ b/src/Form/test-cases/idme_login.html @@ -0,0 +1,66 @@ + +
    +
    +

    Sign in to ID.me

    +
    +
    +

    New to ID.me?

    +

    Create an ID.me account

    +
    + + + +
    +
    +
    + + + + + +
    +
    + + + + + +
    +
    +
    +
    + + +
    + +
    + Or sign in with +
    + + + + + + Ff1f8948 +
    \ No newline at end of file diff --git a/src/Form/test-cases/idme_signup.html b/src/Form/test-cases/idme_signup.html new file mode 100644 index 000000000..36952fae2 --- /dev/null +++ b/src/Form/test-cases/idme_signup.html @@ -0,0 +1,91 @@ + +
    +
    +

    Create an ID.me account

    +
    +
    +

    Already have an ID.me account?

    +

    Sign in to your account

    +
    + + + +
    +
    +
    + + + + + + +
    +
    + + + + + + + +
    +
    + + + + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    + Or sign in with +
    + + + +
    \ No newline at end of file diff --git a/src/Form/test-cases/indeed_login_signup.html b/src/Form/test-cases/indeed_login_signup.html new file mode 100644 index 000000000..99fd597ab --- /dev/null +++ b/src/Form/test-cases/indeed_login_signup.html @@ -0,0 +1,23 @@ + +
    +
    + +
    \ No newline at end of file diff --git a/src/Form/test-cases/index.js b/src/Form/test-cases/index.js new file mode 100644 index 000000000..782a7a683 --- /dev/null +++ b/src/Form/test-cases/index.js @@ -0,0 +1,112 @@ +module.exports = [ + { html: 'poor-markup-form.html' }, + { html: 'wikipedia_login.html' }, + { html: 'wikipedia_signup.html' }, + { html: 'wikipedia_donation.html' }, + { html: 'amazon_login.html' }, + { html: 'amazon_signup.html' }, + { html: 'amazon_address.html' }, + { html: 'facebook_login.html' }, + { html: 'facebook_signup.html' }, + { html: 'twitter_login.html' }, + { html: 'twitter_signup.html', expectedFailures: ['birthdayMonth', 'birthdayDay', 'birthdayYear'] }, + { html: 'fandom_login.html' }, + { html: 'fandom_signup.html', expectedFailures: ['birthday'] }, + { html: 'pinterest_login.html', title: 'Pinterest Login' }, + { html: 'pinterest_signup.html' }, + { html: 'reddit_login.html' }, + { html: 'reddit_signup.html', expectedFailures: ['unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown'] }, + { html: 'yelp_login.html' }, + { html: 'yelp_signup.html' }, + { html: 'instagram_login.html' }, + { html: 'instagram_signup.html' }, + { html: 'ebay_login.html' }, + { html: 'ebay_signup.html' }, + { html: 'ebay_checkout.html', expectedFailures: ['unknown', 'unknown'] }, + { html: 'walmart_login.html' }, + { html: 'walmart_signup.html' }, + { html: 'walmart_checkout.html', expectedFailures: ['unknown', 'unknown'] }, + { html: 'craigslist_account.html' }, + { html: 'healthline_newsletter.html' }, + { html: 'tripadvisor_login.html' }, + { html: 'tripadvisor_signup.html' }, + { html: 'linkedin_login.html' }, + { html: 'linkedin_signup.html' }, + { html: 'webmd_login.html' }, + { html: 'webmd_signup.html', expectedFailures: ['birthday'] }, + { html: 'netflix_login.html' }, + { html: 'netflix_signup.html' }, + { html: 'apple_login.html', expectedFailures: ['username'] }, + { html: 'apple_signup.html', expectedFailures: ['birthday', 'unknown'] }, + { html: 'apple_checkout.html' }, + { html: 'homedepot_login.html' }, + { html: 'homedepot_signup.html' }, + { html: 'yahoo_login.html', expectedFailures: ['unknown'] }, + { html: 'yahoo_signup.html', expectedFailures: ['birthdayMonth', 'birthdayDay', 'birthdayYear'] }, + { html: 'cnn_newsletter.html' }, + { html: 'etsy_login.html' }, + { html: 'etsy_signup.html' }, + { html: 'etsy_checkout.html' }, + { html: 'google_login.html' }, + { html: 'google_signup.html', expectedFailures: ['username'] }, + { html: 'google_store_checkout.html' }, + { html: 'indeed_login_signup.html' }, + { html: 'target_login.html' }, + { html: 'target_signup.html' }, + { html: 'target_checkout.html' }, + { html: 'microsoft_login.html' }, + { html: 'microsoft_signup.html', expectedFailures: ['username'] }, + { html: 'nytimes_login_signup.html' }, + { html: 'mayoclinic_login.html' }, + { html: 'mayoclinic_signup.html', expectedFailures: ['birthdayMonth', 'birthdayDay', 'birthdayYear'] }, + { html: 'espn_login.html' }, + { html: 'espn_signup.html' }, + { html: 'usps_login.html' }, + { html: 'usps_signup.html', expectedFailures: ['unknown', 'unknown', 'unknown', 'unknown'] }, + { html: 'usps_checkout.html' }, + { html: 'quizlet_login.html' }, + { html: 'quizlet_signup.html', expectedFailures: ['birthdayMonth', 'birthdayDay', 'birthdayYear'] }, + { html: 'quizlet_checkout.html' }, + { html: 'lowes_login.html' }, + { html: 'lowes_signup.html' }, + { html: 'lowes_checkout.html' }, + { html: 'idme_login.html', expectedFailures: ['unknown'] }, + { html: 'idme_signup.html' }, + { html: 'merriamwebster_login.html' }, + { html: 'merriamwebster_signup.html' }, + { html: 'steam_login.html', expectedFailures: ['username'] }, + { html: 'steam_signup.html' }, + { html: 'steam_checkout.html', expectedFailures: ['expirationMonth', 'expirationYear', 'addressProvince', 'addressCountryCode', 'unknown', 'unknown', 'addressProvince', 'addressCountryCode', 'cardSecurityCode'] }, + { html: 'mapquest_login.html' }, + { html: 'mapquest_signup.html', expectedFailures: ['birthdayMonth', 'birthdayDay', 'birthdayYear'] }, + { html: 'fox_login.html' }, + { html: 'fox_signup.html', expectedFailures: ['username', 'birthdayMonth', 'birthdayDay', 'birthdayYear'] }, + { html: 'allrecipes_login_signup.html' }, + { html: 'quora_login.html' }, + { html: 'quora_signup.html' }, + { html: 'britannica_login.html' }, + { html: 'britannica_signup.html' }, + { html: 'bestbuy_login.html' }, + { html: 'bestbuy_signup.html' }, + { html: 'bestbuy_checkout.html' }, + { html: 'rottentomatoes_login.html' }, + { html: 'rottentomatoes_signup.html' }, + { html: 'costco_login.html' }, + { html: 'costco_signup.html' }, + { html: 'costco_checkout.html' }, + { html: 'kroger_login.html' }, + { html: 'kroger_signup.html', expectedFailures: ['unknown'] }, + { html: 'kroger_checkout.html', expectedFailures: ['unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown'] }, + { html: 'wayfair_login_signup.html' }, + { html: 'wayfair_checkout.html', expectedFailures: ['unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown'] }, + { html: 'chewy_login.html', expectedFailures: ['username'] }, + { html: 'chewy_signup.html' }, + { html: 'chewy_checkout.html' }, + { html: 'everydayoil_checkout.html', expectedFailures: ['unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown'] }, + { html: 'stripeelements_checkout.html' }, + { html: 'litmus_home_search.html' }, + { html: 'litmus_home_new.html', expectedFailures: ['unknown', 'unknown'] }, + { html: 'asana_tasklist.html' }, + { html: 'asana_search.html' }, + { html: 'aa_login.html' } +] diff --git a/src/Form/test-cases/instagram_login.html b/src/Form/test-cases/instagram_login.html new file mode 100644 index 000000000..5c8770fe0 --- /dev/null +++ b/src/Form/test-cases/instagram_login.html @@ -0,0 +1,21 @@ + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    or
    +
    +
    +
    +
    Forgot password?
    \ No newline at end of file diff --git a/src/Form/test-cases/instagram_signup.html b/src/Form/test-cases/instagram_signup.html new file mode 100644 index 000000000..57ca13e69 --- /dev/null +++ b/src/Form/test-cases/instagram_signup.html @@ -0,0 +1,34 @@ + +
    +

    Sign up to see photos and videos from your friends.

    +
    +
    +
    +
    or
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    By signing up, you agree to our Terms , Data Policy and Cookies Policy .

    +
    \ No newline at end of file diff --git a/src/Form/test-cases/kroger_checkout.html b/src/Form/test-cases/kroger_checkout.html new file mode 100644 index 000000000..3d5db01a7 --- /dev/null +++ b/src/Form/test-cases/kroger_checkout.html @@ -0,0 +1,271 @@ + + + + +
    +

    2. Contact Information

    +
    +
    + Contact Information +
    +
    +
    +

    Your phone number is used to create your shipping label.

    +
    +
    +
    + + + + +
    +
    +
    +
    +
    + + + + + + + + + + + + + + +
    +
    +
    + + + +
    +
    +
    +
    +
    +
    + Expiration +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    + +

    Billing Address

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + \ No newline at end of file diff --git a/src/Form/test-cases/kroger_login.html b/src/Form/test-cases/kroger_login.html new file mode 100644 index 000000000..e4cb193d0 --- /dev/null +++ b/src/Form/test-cases/kroger_login.html @@ -0,0 +1,34 @@ + +
    +
    +
    +
    +
    +
    +
    + +
    \ No newline at end of file diff --git a/src/Form/test-cases/kroger_signup.html b/src/Form/test-cases/kroger_signup.html new file mode 100644 index 000000000..50dd55fb5 --- /dev/null +++ b/src/Form/test-cases/kroger_signup.html @@ -0,0 +1,90 @@ + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    + + + + + Plus Card or Alt ID

    +

    Register your existing + card to access hundreds of digital coupons, track your savings, check your Fuel Points, and more. If you don't + have one we'll create a virtual card for you.

    +

    Your Plus Card or Alt ID Number: +

      +
    • Must be between 10 and 13 digits
    • +
    • Cannot start with a 0
    • +
    +

    +
    \ No newline at end of file diff --git a/src/Form/test-cases/linkedin_login.html b/src/Form/test-cases/linkedin_login.html new file mode 100644 index 000000000..8612fe2b5 --- /dev/null +++ b/src/Form/test-cases/linkedin_login.html @@ -0,0 +1,61 @@ + \ No newline at end of file diff --git a/src/Form/test-cases/linkedin_signup.html b/src/Form/test-cases/linkedin_signup.html new file mode 100644 index 000000000..41dfdfc4b --- /dev/null +++ b/src/Form/test-cases/linkedin_signup.html @@ -0,0 +1,63 @@ +
    +
    +
    +
    +
    +
    By clicking Agree & Join, you + agree to the LinkedIn User Agreement, Privacy Policy, and Cookie Policy. +
    +

    or

    +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/litmus_home_new.html b/src/Form/test-cases/litmus_home_new.html new file mode 100644 index 000000000..31806f86d --- /dev/null +++ b/src/Form/test-cases/litmus_home_new.html @@ -0,0 +1,42 @@ + +
    + +
    +

    Create a new email

    +
    +

    Enter a title

    + +
    + +
    +
    diff --git a/src/Form/test-cases/litmus_home_search.html b/src/Form/test-cases/litmus_home_search.html new file mode 100644 index 000000000..23ccabd57 --- /dev/null +++ b/src/Form/test-cases/litmus_home_search.html @@ -0,0 +1,8 @@ + +
    + + +
    diff --git a/src/Form/test-cases/lowes_checkout.html b/src/Form/test-cases/lowes_checkout.html new file mode 100644 index 000000000..1829d4255 --- /dev/null +++ b/src/Form/test-cases/lowes_checkout.html @@ -0,0 +1,594 @@ + + +
    +
    +
    +
    +
    Add Company Name
    +
    +
    +
    +
    +
    +
    +
    +
    +
    First name is required +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + +
    +
    CARD INFORMATION
    +
    +
    +
    +
    +
    +
    +
    +
    +
    Invalid card number — please check + your card and try again. +
    +
    +
    +
    +
    MM/YY +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/lowes_login.html b/src/Form/test-cases/lowes_login.html new file mode 100644 index 000000000..5793f91a4 --- /dev/null +++ b/src/Form/test-cases/lowes_login.html @@ -0,0 +1,50 @@ + +
    +
    +

    Hi, Welcome to Lowe's

    +
    +
    + + + +
    Enter a valid email address.
    +
    +
    +
    +
    +
    +
  • +
  • + +
    +
    +

    By signing in to Lowes.com, you're agreeing to our Terms of Use and Privacy + Policy.

    +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/lowes_signup.html b/src/Form/test-cases/lowes_signup.html new file mode 100644 index 000000000..2d1d5bf1c --- /dev/null +++ b/src/Form/test-cases/lowes_signup.html @@ -0,0 +1,108 @@ + +
    +
    +

    Create a Personal Account

    +
    +
    *Required Fields
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    +
    +
    +
    +
    +

    Passwords are case-sensitive and must:

    +
    +
    + + + Be 8 to 12 characters in length
    +
    + + + Include at least 1 letter and 1 number
    +
    + + + Contain no spaces
    +
    + + + Maximum of 3 consecutive characters
    +
    +
    +
  • +
    +
    +

    By signing in to Lowes.com, you're agreeing to our Terms of Use and Privacy Policy.

    +
    + +
    \ No newline at end of file diff --git a/src/Form/test-cases/mapquest_login.html b/src/Form/test-cases/mapquest_login.html new file mode 100644 index 000000000..2c9e59a14 --- /dev/null +++ b/src/Form/test-cases/mapquest_login.html @@ -0,0 +1,42 @@ + +
    + + + +
    + + + + +
    + + + + + +
    + + + + +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/mapquest_signup.html b/src/Form/test-cases/mapquest_signup.html new file mode 100644 index 000000000..6ec7b634a --- /dev/null +++ b/src/Form/test-cases/mapquest_signup.html @@ -0,0 +1,75 @@ + +
    + +

    Sign up

    + +
    + + + +
    + + + + + +
    + + +
    +
    + + +
    + + +
    + + + + +
    + + +

    + By clicking "Continue", you agree to the + + Terms + + and + + Privacy Policy + +

    + + + + + +

    + Already have an account? + + Sign in + +

    +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/mayoclinic_login.html b/src/Form/test-cases/mayoclinic_login.html new file mode 100644 index 000000000..760ec3169 --- /dev/null +++ b/src/Form/test-cases/mayoclinic_login.html @@ -0,0 +1,64 @@ + + +
    + + + +
    +

    OR

    +
    + +
    +
    +

    + Sign in with your user name +

    +
    + +
    +
    + + + +
    +
    +
    + + Forgot your password? +
    + +
    +
    +
    +
    + +
    +
    + +
    +

    OR

    +
    +
    +

    + Don't have an account?Sign up now +

    +
    +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/mayoclinic_signup.html b/src/Form/test-cases/mayoclinic_signup.html new file mode 100644 index 000000000..39749d91c --- /dev/null +++ b/src/Form/test-cases/mayoclinic_signup.html @@ -0,0 +1,408 @@ + + +
    +
    + + + + + +

    Enter patient information

    + +
    +
    + +
    +
    + +
    7 to 9 digits; assigned to you before your first visit.
    + + +

    Where to find your Mayo Clinic number

    + + + + +
    +

    Find your Mayo Clinic number

    +

    Look for a 7- to 9-digit number, often near the top of many Mayo Clinic documents, including:

    +
      +
    • Medical documents
    • +
    • Patient Appointment Guides
    • +
    +

    See document + examples

    +
    + + + + +
    + +
    + +
    +
    + +
    +
    + - - +
    (optional)
    +
    XXXXX - XXXXX - XXXXX
    + +

    Don't have an activation code?

    + +
    + +

    Don't worry, you don't need one to set up your Patient Online Services account. Some patients are + given an activation code when they come for an appointment but not all. You can still sign up + for Patient Online Services without this code.

    + + +
    + + +
    + + +
    + + + +
    +
    + +
    +
    + +
    + +
    + +
    +
    +
    + +
    +
    + +
    Please supply a valid email address (for example, johndoe@isp.com). + We send a confirmation email to this address. You can change your contact email at any time.
    + +
    + +
    +
    +
    + +
    +
    + +
    + +
    + +
    +
    +
    + +
    +
    + +
    + +
    +
    (optional)
    +
    +
    +
    + +
    +
    + +
    + +
    + +
    + + +
    +
    + +
    +
    +
    +
    +
    + + + +
    + + +
    + + + + + + + + + + +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    + + +
    + +
    +
    + + +
    +
    + +
    +
    + +
    +
    +
    + +
    \ No newline at end of file diff --git a/src/Form/test-cases/merriamwebster_login.html b/src/Form/test-cases/merriamwebster_login.html new file mode 100644 index 000000000..347a59689 --- /dev/null +++ b/src/Form/test-cases/merriamwebster_login.html @@ -0,0 +1,60 @@ + +
    + +
    + + +
    + + show +
    +
    +
    +
    + + + + + + + +
    + + +
    + +
    \ No newline at end of file diff --git a/src/Form/test-cases/merriamwebster_signup.html b/src/Form/test-cases/merriamwebster_signup.html new file mode 100644 index 000000000..1508b0fe4 --- /dev/null +++ b/src/Form/test-cases/merriamwebster_signup.html @@ -0,0 +1,55 @@ + +
    + +
    + +
    +

    3-15 characters

    + +
    +
    + +
    +
    +
    + +
    +

    8+ characters

    +
    +
    + + show +
    +
    +
    +
    + + + + + +
    + +
    +

    By completing this registration, you accept the terms of service and acknowledge the privacy policy for this site.

    + +
    \ No newline at end of file diff --git a/src/Form/test-cases/microsoft_login.html b/src/Form/test-cases/microsoft_login.html new file mode 100644 index 000000000..ec329767e --- /dev/null +++ b/src/Form/test-cases/microsoft_login.html @@ -0,0 +1,308 @@ +
    + + +
    + + + +
    + + + + +
    + + +
    +
    +
    Sign in
    + + +
    +
    + + + + +
    +
    + + +
    + +
    + + + + +
    + + + + + + + + + +
    + +
    + +
    + +
    +
    + +
    +
    +
    +
    + +
    No account? Create one!
    + + + + + + + + + + + + + +
    +
    +
    +
    + + + + +
    +
    +
    +
    + + + + +
    + + +
    +
    +
    +
    +
    + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/microsoft_signup.html b/src/Form/test-cases/microsoft_signup.html new file mode 100644 index 000000000..165c0ebae --- /dev/null +++ b/src/Form/test-cases/microsoft_signup.html @@ -0,0 +1,819 @@ + + +
    + +
    +
    + + +
    +
    + + +
    +
    + + + +
    +
    + + + +
    +
    +
    +
    + + + + +
    +
    + + + + + + + + + + + + + + + + + + + +
    +
    +
    + + + + +
    +
    +
    +
    Create account
    + + + + + + + + + + + +
    + +
    +
    + + +
    +
    + + +
    +
    + + + +
    +
    + + +
    + + + +
    + +
    +
    +
    +
    + + + + +
    +
    + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    +
    +
    +
    + + + + +
    +
    +
    +
    +
    +
    +
    + +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/netflix_login.html b/src/Form/test-cases/netflix_login.html new file mode 100644 index 000000000..c5007b2c7 --- /dev/null +++ b/src/Form/test-cases/netflix_login.html @@ -0,0 +1,1554 @@ + \ No newline at end of file diff --git a/src/Form/test-cases/netflix_signup.html b/src/Form/test-cases/netflix_signup.html new file mode 100644 index 000000000..d5e50dc42 --- /dev/null +++ b/src/Form/test-cases/netflix_signup.html @@ -0,0 +1,38 @@ + +
    +
    +
    +
    STEP 2 OF 3 +

    Create a password to start your membership

    +
    +
    +
    +
    Just a few more steps and you're done!
    +
    We hate paperwork, too.
    +
      +
    • +
      +
      +
      +
    • +
    • +
      +
      +
      +
    • +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/nytimes_login_signup.html b/src/Form/test-cases/nytimes_login_signup.html new file mode 100644 index 000000000..1e0eb0c03 --- /dev/null +++ b/src/Form/test-cases/nytimes_login_signup.html @@ -0,0 +1,65 @@ + +
    +

    Log in or create an account

    +
    +
    +
    +
    +
    +
    +
    +
    +
    or
    + + +
    \ No newline at end of file diff --git a/src/Form/test-cases/pinterest_login.html b/src/Form/test-cases/pinterest_login.html new file mode 100644 index 000000000..61ee113fb --- /dev/null +++ b/src/Form/test-cases/pinterest_login.html @@ -0,0 +1,17 @@ +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/pinterest_signup.html b/src/Form/test-cases/pinterest_signup.html new file mode 100644 index 000000000..b134bfb62 --- /dev/null +++ b/src/Form/test-cases/pinterest_signup.html @@ -0,0 +1,16 @@ +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/poor-markup-form.html b/src/Form/test-cases/poor-markup-form.html new file mode 100644 index 000000000..e0307299d --- /dev/null +++ b/src/Form/test-cases/poor-markup-form.html @@ -0,0 +1,23 @@ +
    +
    + Card Number + +
    +
    + MM-YYYY + +
    +
    + Security code + +
    +
    + Random unrelated field + + +
    + +
    \ No newline at end of file diff --git a/src/Form/test-cases/quizlet_checkout.html b/src/Form/test-cases/quizlet_checkout.html new file mode 100644 index 000000000..352e6601c --- /dev/null +++ b/src/Form/test-cases/quizlet_checkout.html @@ -0,0 +1,340 @@ + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    By purchasing, you agree to the Terms of service and Privacy Policy.
    +
    + \ No newline at end of file diff --git a/src/Form/test-cases/quizlet_login.html b/src/Form/test-cases/quizlet_login.html new file mode 100644 index 000000000..4f5119696 --- /dev/null +++ b/src/Form/test-cases/quizlet_login.html @@ -0,0 +1,23 @@ +
    +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/quizlet_signup.html b/src/Form/test-cases/quizlet_signup.html new file mode 100644 index 000000000..1b978cf3f --- /dev/null +++ b/src/Form/test-cases/quizlet_signup.html @@ -0,0 +1,241 @@ +
    +
    +
    + Birthday +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    By clicking Sign up, you accept Quizlet's Terms of Service and Privacy Policy
    +
    +
    Already have an account?
    +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/quora_login.html b/src/Form/test-cases/quora_login.html new file mode 100644 index 000000000..758e0e6c6 --- /dev/null +++ b/src/Form/test-cases/quora_login.html @@ -0,0 +1,98 @@ + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    + +
    + + + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    + + + + + +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/quora_signup.html b/src/Form/test-cases/quora_signup.html new file mode 100644 index 000000000..660f66243 --- /dev/null +++ b/src/Form/test-cases/quora_signup.html @@ -0,0 +1,64 @@ + +
    +
    +
    +
    + +
    + + + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    + + + + + +
    +
    +
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/reddit_login.html b/src/Form/test-cases/reddit_login.html new file mode 100644 index 000000000..17fc35bc2 --- /dev/null +++ b/src/Form/test-cases/reddit_login.html @@ -0,0 +1,144 @@ + +
    + +

    + You have two-factor authentication enabled on this account because you're awesome. +

    + +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + Continue with Apple +
    +
    +
    +
    + + + + + + +  Sign in with Apple + + + +
    +
    +
    +
    +
    +
    + +
    + +
    + + or + +
    + +
    + + + +
    + + + +
    +
    + +
    + +
    + + + +
    +
    + +
    + + + + use a backup code + +
    + +
    + +
    +
    + +
    +
    + + + + + +
    + Go back to account details + + Having trouble ? +
    + +
    \ No newline at end of file diff --git a/src/Form/test-cases/reddit_signup.html b/src/Form/test-cases/reddit_signup.html new file mode 100644 index 000000000..7624c06f9 --- /dev/null +++ b/src/Form/test-cases/reddit_signup.html @@ -0,0 +1,42 @@ + +
    + + + + +
    + + + +
    + +
    + + + + + +
    +
    + +
    + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    \ No newline at end of file diff --git a/src/Form/test-cases/rottentomatoes_login.html b/src/Form/test-cases/rottentomatoes_login.html new file mode 100644 index 000000000..d09a93794 --- /dev/null +++ b/src/Form/test-cases/rottentomatoes_login.html @@ -0,0 +1,25 @@ + + +
    + + + +
    \ No newline at end of file diff --git a/src/Form/test-cases/rottentomatoes_signup.html b/src/Form/test-cases/rottentomatoes_signup.html new file mode 100644 index 000000000..789297146 --- /dev/null +++ b/src/Form/test-cases/rottentomatoes_signup.html @@ -0,0 +1,49 @@ + + +
    + +
    + +

    Already have an account?

    +
    + +
    \ No newline at end of file diff --git a/src/Form/test-cases/steam_checkout.html b/src/Form/test-cases/steam_checkout.html new file mode 100644 index 000000000..5fdda75e8 --- /dev/null +++ b/src/Form/test-cases/steam_checkout.html @@ -0,0 +1,1993 @@ + + +
    + + +
    + + + + + + + +
    + + +
    +
    +
    + + +

    Payment method

    + + + + + +
    + + +
    +
    +
    +
    +
    +
    +
    + +
    + + Visa + +
    + +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + +
    + + -- +
    + +
    +
    + +
    + + ---- +
    + +
    +
    + +
    +
    + + ? +
    +
    +
    +
    +
    + + + +

    Billing information ? +

    + + + +
    +
    +
    +
    +
    + + +
    +
    + + +
    + +
    + + +
    + +
    + + +
    + + +
    + +
    +
    +
    +
    +
    + + + + +
    +
    +
    + +
    + + +
    +
    +
    +
    +
    + + + + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + + +
    +

    + You'll have a chance to review your order before it's placed.

    + +
    +
    + + Continue + + + + +
    +


    +
    +
    +
    +
    + +
    + +
    + + + + +
    + \ No newline at end of file diff --git a/src/Form/test-cases/steam_login.html b/src/Form/test-cases/steam_login.html new file mode 100644 index 000000000..2dcb73d5d --- /dev/null +++ b/src/Form/test-cases/steam_login.html @@ -0,0 +1,55 @@ + +
    + + + +
    + + + + + +
    +
    + + + + + +
    \ No newline at end of file diff --git a/src/Form/test-cases/steam_signup.html b/src/Form/test-cases/steam_signup.html new file mode 100644 index 000000000..88abd7c6d --- /dev/null +++ b/src/Form/test-cases/steam_signup.html @@ -0,0 +1,534 @@ + +
    + +
    +
    +
    + Create Your Account
    + +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    + + + + +
    +
    + +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/stripeelements_checkout.html b/src/Form/test-cases/stripeelements_checkout.html new file mode 100644 index 000000000..2d01380b5 --- /dev/null +++ b/src/Form/test-cases/stripeelements_checkout.html @@ -0,0 +1,2232 @@ + +
    + +
    + +

    Stripe Elements examples

    +

    Stripe Elements are pre-built rich UI + components that help you build your own pixel-perfect checkout flows across desktop and mobile.

    +

    + Learn more + Explore the docs +

    +
    + + +
    +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + + + + +
    +
    + + + + + + +
    +
    +
    +
    +
    + +
    +
    +
    +
    + + + +
    +
    +
    +
    + + + +
    +
    + + + + +
    +

    Payment successful

    +

    Thanks for trying Stripe Elements. No + money was charged, but we generated a token:tok_189gMN2eZvKYlo2CwTBv9KKh

    + + + + + + +
    + +
    + Your card won't be charged + + + + + View source on GitHub + +
    +
    + + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    + + +
    + +
    +
    +
    + + + +
    +
    + +
    +
    +
    +
    +
    +
    +
    + +
    + +
    + + +
    +
    + +
    +
    +
    +
    +
    + +
    + +
    + + +
    +
    + +
    +
    +
    + + + +
    +
    + + + + +
    +

    Payment successful

    +

    Thanks for trying Stripe Elements. No + money was charged, but we generated a token:tok_189gMN2eZvKYlo2CwTBv9KKh

    + + + + + + +
    + +
    + Your card won't be charged + + + + + View source on GitHub + +
    +
    + + +
    +
    +
    + + + +
    +
    +
    +
    + + + +
    + +
    +
    +
    + + + +
    +
    +
    +
    + +
    + +
    + + +
    +
    +
    +
    + +
    + +
    + + +
    +
    + +
    + + + +
    +
    + + + + +
    +

    Payment successful

    +

    Thanks for trying Stripe Elements. No + money was charged, but we generated a token:tok_189gMN2eZvKYlo2CwTBv9KKh

    + + + + + + +
    + +
    + Your card won't be charged + + + + + View source on GitHub + +
    +
    + + +
    +
    +
    + +
    +
    + Pay with card + Or enter + card details +
    +
    +
    + + + +
    +
    +
    +
    + + + + + + + + +
    +
    + + + + + + + + + + + + +
    +
    +
    +
    +
    + +
    +
    +
    +
    + + + +
    +
    + +
    +
    + + +
    +
    + + + + +
    +

    Payment successful

    +

    Thanks for trying Stripe Elements. No + money was charged, but we generated a token:tok_189gMN2eZvKYlo2CwTBv9KKh

    + + + + + + +
    + +
    + Your card won't be charged + + + + + View source on GitHub + +
    +
    + + +
    +
    +
    + +
    +
    + Pay with card + Or enter + card details +
    +
    + + +
    +
    +
    +
    + + +
    +
    + + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    +
    + +
    +
    + + + +
    +
    +
    +
    + + + + + + +
    +
    + + + + + + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    + +
    + + +
    +
    + + + + +
    +

    Payment successful

    +

    Thanks for trying Stripe Elements. No + money was charged, but we generated a token:tok_189gMN2eZvKYlo2CwTBv9KKh

    + + + + + + +
    + +
    + Your card won't be charged + + + + + View source on GitHub + +
    +
    +
    diff --git a/src/Form/test-cases/target_checkout.html b/src/Form/test-cases/target_checkout.html new file mode 100644 index 000000000..b39420ef6 --- /dev/null +++ b/src/Form/test-cases/target_checkout.html @@ -0,0 +1,327 @@ + + +
    +
    +
    +
    +
    +

    Delivery address +

    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    Enter full name +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + + +
    +
    +
    +
    +
    +
    + default + default icon + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/target_login.html b/src/Form/test-cases/target_login.html new file mode 100644 index 000000000..f528dd553 --- /dev/null +++ b/src/Form/test-cases/target_login.html @@ -0,0 +1,35 @@ + +
    +
    +
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/target_signup.html b/src/Form/test-cases/target_signup.html new file mode 100644 index 000000000..6197b3b1a --- /dev/null +++ b/src/Form/test-cases/target_signup.html @@ -0,0 +1,77 @@ +
    +
    +
    +
    +
    +
    +
    + + + + +
    +
    +
    +
    +
    +
    +
    +
    By creating an account, you are agreeing to the + Target terms & conditions and Target privacy + policy, including receipt of Target exclusive email offers and promotions. To manage + your marketing choices please access the Choice section of the Target Privacy Policy or call Target Guest + Relations.
    Or sign + in +
    \ No newline at end of file diff --git a/src/Form/test-cases/tripadvisor_login.html b/src/Form/test-cases/tripadvisor_login.html new file mode 100644 index 000000000..fc20d47b6 --- /dev/null +++ b/src/Form/test-cases/tripadvisor_login.html @@ -0,0 +1,41 @@ +
    + +
    +
    +
    +
    Welcome back.
    +
    Show passwordHide password +
    + +
    +
    Not a member?
    +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/tripadvisor_signup.html b/src/Form/test-cases/tripadvisor_signup.html new file mode 100644 index 000000000..1872eeb4e --- /dev/null +++ b/src/Form/test-cases/tripadvisor_signup.html @@ -0,0 +1,52 @@ +
    + +
    +
    +
    +
    +
    Join to unlock the best of Tripadvisor
    +
    +
    +
    Show passwordHide password + +
    +
    Already a member?
    +
    +
    + +
    \ No newline at end of file diff --git a/src/Form/test-cases/twitter_login.html b/src/Form/test-cases/twitter_login.html new file mode 100644 index 000000000..5aa83b0e7 --- /dev/null +++ b/src/Form/test-cases/twitter_login.html @@ -0,0 +1,28 @@ +
    +
    +
    +
    Enter your password
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    Forgot password? + +
    +
    +
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/twitter_signup.html b/src/Form/test-cases/twitter_signup.html new file mode 100644 index 000000000..0c1ec0c88 --- /dev/null +++ b/src/Form/test-cases/twitter_signup.html @@ -0,0 +1,24 @@ +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    Use email instead
    +
    +
    Date of birth
    +
    This will not be shown publicly. Confirm your own age, even if this account is for a business, a pet, or something else.
    +
    +
    +
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/usps_checkout.html b/src/Form/test-cases/usps_checkout.html new file mode 100644 index 000000000..e463c657f --- /dev/null +++ b/src/Form/test-cases/usps_checkout.html @@ -0,0 +1,604 @@ + +
    + +
    +
    +

    Contact Information

    +
    +
    +
    + +
    +
    +
    +

    Contact information for the person making the purchase.

    +
    +
    +
    +
    + +
    +
    +
    +
    + + + Please enter first name. +
    +
    + + + Please enter last name. +
    +
    +
    +
    + + + Please enter phone number. +
    +
    + + + Please enter email. +
    +
    +
    + +
    + +
    +
    +

     

    +
    +
    + +
    +
    +

    Shipping Address

    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    + + + Please enter first name. +
    +
    + + + Please enter last name. +
    +
    +
    +
    + + + Please enter phone number. +
    +
    + + + Please enter email. +
    +
    +
    +
    + + + Please enter address. +
    +
    + + + Please enter address. +
    +
    +
    +
    + + + Please enter city. +
    + + + + + + + + + +
    + + + Please select state or province. +
    +
    + + + Please enter ZIP or postal code. + + +
    +
    + +
    +
    + + + Please enter urbanization. +
    +
    + +
    +
    + +
    +
    +

    Privacy Act Statement

    +
    +

    Your information will be used to enable guest customer checkout via usps.com to fulfill orders for + Postal products and services, and to provide online ordering and payment capabilities. Collection is + authorized by 39 U.S.C. 401, 403, and 404. Supplying your information is voluntary, but if not + provided, we may not be able to fulfill your order or process your transaction. We do not disclose + your information to third parties without your consent, except to act on your behalf or request, or + as legally required. This includes the following limited circumstances: to a congressional office on + your behalf; to agencies and entities to facilitate or resolve financial transactions; to a U.S. + Postal Service auditor; for law enforcement purposes, to labor organizations as required by + applicable law; incident to legal proceedings involving the Postal Service; to government agencies + in connection with decisions as necessary; to agents or contractors when necessary to fulfill a + business function or provide products and services to customers; and for customer service purposes. + For more information regarding our privacy policies visit www.usps.com/privacypolicy. +

    + Expand + additional information. +
    +
    +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/usps_login.html b/src/Form/test-cases/usps_login.html new file mode 100644 index 000000000..b36743d8c --- /dev/null +++ b/src/Form/test-cases/usps_login.html @@ -0,0 +1,102 @@ + +
    + +
    +
    + +
    + + +

    Already have an account?

    + Enter Your Username and Password + + + tool tip +
    + * indicates a required field

    + +
    + + + + + +
    +
    + + + + + + + + + + + + + +
    +
    + +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    + +
    + + Forgot your username? + + tool tip
    +
    + + +
    + + Forgot your password? + + tool tip +
    +
    +
    + +
    +
    +

    The United States Postal Service is serious about protecting your personal information. + For added security, please consider changing your password periodically.

    +
    +
    + +
    \ No newline at end of file diff --git a/src/Form/test-cases/usps_signup.html b/src/Form/test-cases/usps_signup.html new file mode 100644 index 000000000..325002f52 --- /dev/null +++ b/src/Form/test-cases/usps_signup.html @@ -0,0 +1,1910 @@ + +
    + + + + + + + + + + + + + + + + + + + +
    +
    +

    Step 1: Choose your language and username

    +

    Please choose a default language for your USPS account. This can be changed at a later time from your preferences page.

    +

    Please enter a username which will uniquely identify you with the United States Postal Service.

    + * indicates a required field +
    +
    +
    + +
    + + + + +
    + + +
    +
    + + + + + + + + + + + + + + +
    + +
    +
    + +
    +
    + +
    +
    +

    Step 2: Enter your security information

    + +

    Please create a password for your account. We highly recommend you create a unique password - one that you don't use for other websites.

    + * indicates a required field +
    +
    + Pick a Password +
    + + + + + +
    + + +
    + + + + + +
    + + Passwords must be at least 8 characters in length and include at least one uppercase letter, one lowercase letter, and one number. They are case-sensitive and cannot include your username or more than two consecutive identical characters. + + tool tip + + +
    +
    +
    +
    +
    +
    +

    Please answer two secret questions. Answers are not case-sensitive. If you forget your password, you will be asked for this information to re-gain access to our site.

    + * indicates a required field +
    +
    + Pick Two Security Questions + + + + +
    + + + + + + + + + + + + +
    +
    + + + + + + + + + +
    +
    + + + + + +
    +
    +
    +   +
    + + + + + + + + +
    +
    + + + + + + + + + +
    +
    + + + + + + +
    + +
    +
    + +
    +
    +

    Step 3: Choose your account type

    +

    Choose personal account if you are interested in services for your home? i.e. order stamps, renew a MailBox, mail a package, etc.

    +

    Interested in solutions for your business - home-based, small, medium, or large? Choose business account.

    +
    +
    +
    +

    Please choose which type of account you would like to create

    + + +
    +
    +
    + + + + + + +
    +
    + +
    +
    + + + + + + + + + +
    +
    + + + + + + + +
    \ No newline at end of file diff --git a/src/Form/test-cases/walmart_checkout.html b/src/Form/test-cases/walmart_checkout.html new file mode 100644 index 000000000..b08222036 --- /dev/null +++ b/src/Form/test-cases/walmart_checkout.html @@ -0,0 +1,102 @@ + +
    *Required fields +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    We'll contact you in case anything comes up with your order.
    +
    +
    + +
    +
    + +
    * Required field +
    Card information +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    Billing address
    +
    +
    +
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/walmart_login.html b/src/Form/test-cases/walmart_login.html new file mode 100644 index 000000000..2974495b4 --- /dev/null +++ b/src/Form/test-cases/walmart_login.html @@ -0,0 +1,17 @@ + +
    +
    +
    +
    Email address is required.
    +
    +
    +
    Password is required.
    +
    +
    +
    Uncheck if using a public device. +
    We'll keep you signed in on this device. You may be asked to enter your password when modifying sensitive account information.
    +
    +
    +
    +
    Don't have an account?
    +
    \ No newline at end of file diff --git a/src/Form/test-cases/walmart_signup.html b/src/Form/test-cases/walmart_signup.html new file mode 100644 index 000000000..bf0358267 --- /dev/null +++ b/src/Form/test-cases/walmart_signup.html @@ -0,0 +1,30 @@ + +
    +
    * required field
    +
    First name is required.
    +
    Last name is required.
    +
    Email address is required.
    +
    +
    +
    +
    +
    +
    Your password must include the following:
    +
    +

    8–100 characters

    +
    +
    +

    Upper & lowercase letters

    +
    +
    +

    At least one number or special character

    +
    +
    +
    +
    +
    Uncheck if using a public device. +
    We'll keep you signed in on this device. You may be asked to enter your password when modifying sensitive account information.
    +
    +
    +

    By clicking Create Account, you acknowledge you have read and agreed to our Terms of Use and Privacy Policy.

    +
    Already have an account?
    diff --git a/src/Form/test-cases/wayfair_checkout.html b/src/Form/test-cases/wayfair_checkout.html new file mode 100644 index 000000000..2ba9fa2fe --- /dev/null +++ b/src/Form/test-cases/wayfair_checkout.html @@ -0,0 +1,450 @@ + + + + +
    +
    +
    +
    +

    Shipping Address

    +
    +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +

      Used to + contact you with delivery info (mobile preferred).

      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      + + + + + +
      +
      +
      +
      +
      +
      +
      Card Icon
      +
      +

      Please enter a valid card + number

      +
      +
      +
      +
      +
      +
      +

      Please enter a valid + card expiry date

      +
      +
      +
      +
      +
      +

      Please enter a valid + CVC

      +
      +
      +
      +
      \ No newline at end of file diff --git a/src/Form/test-cases/wayfair_login_signup.html b/src/Form/test-cases/wayfair_login_signup.html new file mode 100644 index 000000000..5234559bd --- /dev/null +++ b/src/Form/test-cases/wayfair_login_signup.html @@ -0,0 +1,27 @@ + +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      \ No newline at end of file diff --git a/src/Form/test-cases/webmd_login.html b/src/Form/test-cases/webmd_login.html new file mode 100644 index 000000000..c345ac069 --- /dev/null +++ b/src/Form/test-cases/webmd_login.html @@ -0,0 +1,65 @@ +
      +
      +
      +

      For your security, please re-enter your password.

      +
      +
      +
      + + +
      +
      + Enter your email address +
      +
      +
      +
      +
      + + +
      +
      + +
      +
      + SHOW +
      +
      + +
      + Keep me signed in + ? + +
      +
      +
      +

      Want More Security?

      +
      + Create PIN + + +
      + +
      +
      + +   or + +
      + Forgot your password? +
      +
      \ No newline at end of file diff --git a/src/Form/test-cases/webmd_signup.html b/src/Form/test-cases/webmd_signup.html new file mode 100644 index 000000000..e61aea17f --- /dev/null +++ b/src/Form/test-cases/webmd_signup.html @@ -0,0 +1,252 @@ +
      +
      +
      +
      + + +
      +
      + +
      +
      +
      +
      +
      + + +
      +
      + +
      +
      + SHOW +
      +
      Minimum 8 letters & numbers
      +
      +
      +
      +
      +
      +
      +
      +
      +
      + +
      +
      + + +
      +
      + +
      +
      +
      +
      +

      Want More Security?

      +
      + Create PIN + + +
      + +
      +
      + + By clicking Sign Up, I agree to the WebMD Terms & + Conditions & Privacy Policy + and understand that I may opt out of WebMD subscriptions at any time + +
      +
      + +   or + +
      +
      +
      \ No newline at end of file diff --git a/src/Form/test-cases/wikipedia_donation.html b/src/Form/test-cases/wikipedia_donation.html new file mode 100644 index 000000000..f3f7f1204 --- /dev/null +++ b/src/Form/test-cases/wikipedia_donation.html @@ -0,0 +1,355 @@ + +
      + + + + +
      +

      Donation amount + + + $5.00 + +

      +
      +

      Billing information

      + +
      +
      + + + Please enter your first name + +
      +
      + + + Please enter your last name + +
      +
      +
      + + + Please enter your street address + +
      +
      +
      + + + Please enter your city + +
      +
      + + Please enter your state + +
      +
      + + + Please enter your zip code + +
      +
      +
      + + + + Please enter your email address + +
      +
      +
      +
        + +
      • + +
      • + +
      • + +
      • + +
      • + +
      • + +
      • + +
      • +
      +
      +
      +
      +
      +
      + Your credit / debit card will be securely processed. +
      +
      + +
      + + + + + + + + + + + + + + + + + + + +
      + + + + + + + + + +
      + +
      + + + + + +
      +
      + +
      +
      +
      +

      This card has multiple payment options. Please choose your preferred option.

      +
      +
      + +
      +
      +
        + +
      +
      +
      +
      + +
      + +
      + + +
      +
      + +
      + +
      + + + + + +
      +
      + +
      + +
      + + + + +
      +
      + +
      + + + +
      +
      \ No newline at end of file diff --git a/src/Form/test-cases/wikipedia_login.html b/src/Form/test-cases/wikipedia_login.html new file mode 100644 index 000000000..2de60bafb --- /dev/null +++ b/src/Form/test-cases/wikipedia_login.html @@ -0,0 +1,41 @@ + +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
       
      +
      +
      +
      +
      +
      +
      + + +
      +
      +
      Don't have an account?Join Wikipedia
      +
      +
      +
      + + + + + + +
      \ No newline at end of file diff --git a/src/Form/test-cases/wikipedia_signup.html b/src/Form/test-cases/wikipedia_signup.html new file mode 100644 index 000000000..76166846a --- /dev/null +++ b/src/Form/test-cases/wikipedia_signup.html @@ -0,0 +1,52 @@ + +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      It is recommended to use a unique password that you are not using on any other website.
      +
      +
      +
      +
      +
      +
      +
      +
      +
      Email is required to recover your account if you lose your password.
      +
      +

      +
      +
      +
      +
      Refresh
      +
      + Can't see the image? Request an account
      +
      +
      +
      +
      +
      +
      +
      + + + + + + + + +
      \ No newline at end of file diff --git a/src/Form/test-cases/yahoo_login.html b/src/Form/test-cases/yahoo_login.html new file mode 100644 index 000000000..7b8498043 --- /dev/null +++ b/src/Form/test-cases/yahoo_login.html @@ -0,0 +1,321 @@ + + +
      + + + + + + +
      +
      +
      +1
      + +
      +
      +
      + + +
      +
      + +
      +
      + +
      + +
        +
      • yahoo.com
      • +
      • gmail.com
      • +
      • outlook.com
      • +
      • aol.com
      • +
      +
      +
      + +
      +
      + + + +
      + +
      + + + +
      \ No newline at end of file diff --git a/src/Form/test-cases/yahoo_signup.html b/src/Form/test-cases/yahoo_signup.html new file mode 100644 index 000000000..8351e657d --- /dev/null +++ b/src/Form/test-cases/yahoo_signup.html @@ -0,0 +1,121 @@ + + +
      + + + + + + + + + + + + + + +
      +
      +
      + + +
      +
      + + +
      +
      +
      + + + +
      + I want to create a new Yahoo + email address +
      + + +
      +
      +
      + +
      + +
      +
      + +
      +
      +
      + +
      + + + +
      + +
      + + +

      + By clicking "Continue", you agree to the Terms and Privacy Policy +

      +
      + +
      + + +
      \ No newline at end of file diff --git a/src/Form/test-cases/yelp_login.html b/src/Form/test-cases/yelp_login.html new file mode 100644 index 000000000..36ce548a1 --- /dev/null +++ b/src/Form/test-cases/yelp_login.html @@ -0,0 +1,13 @@ + +
      + + + + + + + + +
      \ No newline at end of file diff --git a/src/Form/test-cases/yelp_signup.html b/src/Form/test-cases/yelp_signup.html new file mode 100644 index 000000000..2a187c333 --- /dev/null +++ b/src/Form/test-cases/yelp_signup.html @@ -0,0 +1,271 @@ + + \ No newline at end of file diff --git a/src/Form/vendor-regex.js b/src/Form/vendor-regex.js new file mode 100644 index 000000000..a4061e78b --- /dev/null +++ b/src/Form/vendor-regex.js @@ -0,0 +1,45 @@ +/** + * Given some ruleSets, create an efficient + * lookup system for accessing cached regexes by name. + * + * @param {VendorRegexConfiguration["rules"]} rules + * @param {VendorRegexConfiguration["ruleSets"]} ruleSets + * @return {{RULES: Record}} + */ +function createCacheableVendorRegexes (rules, ruleSets) { + const vendorRegExp = { + RULES: rules, + RULE_SETS: ruleSets, + _getRule (name) { + let rules = [] + this.RULE_SETS.forEach(set => { + if (set[name]) { + // Add the rule. + // We make the regex lower case so that we can match it against the + // lower-cased field name and get a rough equivalent of a case-insensitive + // match. This avoids a performance cliff with the "iu" flag on regular + // expressions. + rules.push(`(${set[name]?.toLowerCase()})`.normalize('NFKC')) + } + }) + const value = new RegExp(rules.join('|'), 'u') + Object.defineProperty(this.RULES, name, {get: undefined}) + Object.defineProperty(this.RULES, name, {value}) + return value + }, + init () { + Object.keys(this.RULES).forEach(field => + Object.defineProperty(this.RULES, field, { + get () { + return vendorRegExp._getRule(field) + } + }) + ) + } + } + vendorRegExp.init() + // @ts-ignore + return vendorRegExp +} + +module.exports.createCacheableVendorRegexes = createCacheableVendorRegexes diff --git a/src/InputTypes/Credentials.js b/src/InputTypes/Credentials.js new file mode 100644 index 000000000..9c5d8bddb --- /dev/null +++ b/src/InputTypes/Credentials.js @@ -0,0 +1,45 @@ +const GENERATED_ID = '__generated__' + +/** + * @implements {TooltipItemRenderer} + */ +class CredentialsTooltipItem { + /** @type {CredentialsObject} */ + #data; + /** @param {CredentialsObject} data */ + constructor (data) { + this.#data = data + } + id = () => String(this.#data.id) + labelMedium (_subtype) { + if (this.#data.id === GENERATED_ID) { + return 'Generated password' + } + return this.#data.username + } + labelSmall (_subtype) { + if (this.#data.id === GENERATED_ID && this.#data.password) { + return this.#data.password + } + return '•••••••••••••••' + } +} + +/** + * Generate a stand-in 'CredentialsObject' from a + * given (generated) password. + * + * @param {string} password + * @returns {CredentialsObject} + */ +function fromPassword (password) { + return { + id: GENERATED_ID, + password: password, + username: '' + } +} + +module.exports.CredentialsTooltipItem = CredentialsTooltipItem +module.exports.fromPassword = fromPassword +module.exports.GENERATED_ID = GENERATED_ID diff --git a/src/InputTypes/CreditCard.js b/src/InputTypes/CreditCard.js new file mode 100644 index 000000000..44fe76ce8 --- /dev/null +++ b/src/InputTypes/CreditCard.js @@ -0,0 +1,16 @@ +/** + * @implements {TooltipItemRenderer} + */ +class CreditCardTooltipItem { + /** @type {CreditCardObject} */ + #data; + /** @param {CreditCardObject} data */ + constructor (data) { + this.#data = data + } + id = () => String(this.#data.id) + labelMedium = (_) => this.#data.title; + labelSmall = (_) => this.#data.displayNumber +} + +module.exports.CreditCardTooltipItem = CreditCardTooltipItem diff --git a/src/InputTypes/Identity.js b/src/InputTypes/Identity.js new file mode 100644 index 000000000..cb3d4bf84 --- /dev/null +++ b/src/InputTypes/Identity.js @@ -0,0 +1,34 @@ +const {getCountryDisplayName} = require('../Form/formatters') + +/** + * @implements {TooltipItemRenderer} + */ +class IdentityTooltipItem { + /** @type {IdentityObject} */ + #data; + /** @param {IdentityObject} data */ + constructor (data) { + this.#data = data + } + id = () => String(this.#data.id) + labelMedium = (subtype) => { + if (subtype === 'addressCountryCode') { + return getCountryDisplayName('en', this.#data.addressCountryCode || '') + } + if (this.#data.id === 'privateAddress') { + return 'Generated Private Address' + } + return this.#data[subtype] + }; + label (subtype) { + if (this.#data.id === 'privateAddress') { + return this.#data[subtype] + } + return null + } + labelSmall = (_) => { + return this.#data.title + }; +} + +module.exports.IdentityTooltipItem = IdentityTooltipItem diff --git a/src/PasswordGenerator.js b/src/PasswordGenerator.js new file mode 100644 index 000000000..d737d0fdc --- /dev/null +++ b/src/PasswordGenerator.js @@ -0,0 +1,28 @@ +const {generate} = require('../packages/password') +const rules = require('../packages/password/rules.json') + +/** + * Create a password once and reuse it. + */ +class PasswordGenerator { + /** @type {string|null} */ + #previous = null; + + /** @returns {boolean} */ + get generated () { + return this.#previous !== null + } + + /** @param {import('../packages/password').GenerateOptions} [params] */ + generate (params = {}) { + if (this.#previous) { + return this.#previous + } + + this.#previous = generate({ ...params, rules }) + + return this.#previous + } +} + +module.exports.PasswordGenerator = PasswordGenerator diff --git a/src/PasswordGenerator.test.js b/src/PasswordGenerator.test.js new file mode 100644 index 000000000..40af8e5c6 --- /dev/null +++ b/src/PasswordGenerator.test.js @@ -0,0 +1,17 @@ +const {PasswordGenerator} = require('./PasswordGenerator') + +describe('PasswordGenerator', () => { + it('generates a password once', () => { + const pwg = new PasswordGenerator() + expect(pwg.generated).toBe(false) + const pws = [ + pwg.generate(), + pwg.generate(), + pwg.generate(), + pwg.generate(), + pwg.generate() + ] + expect(new Set(pws).size).toBe(1) + expect(pwg.generated).toBe(true) + }) +}) diff --git a/src/TopAutofill.html b/src/TopAutofill.html new file mode 100644 index 000000000..107cc0130 --- /dev/null +++ b/src/TopAutofill.html @@ -0,0 +1,13 @@ + + + + + +
      + + diff --git a/src/UI/DataAutofill.js b/src/UI/DataAutofill.js index f10b2fe6c..94647b6be 100644 --- a/src/UI/DataAutofill.js +++ b/src/UI/DataAutofill.js @@ -1,39 +1,51 @@ const { isApp, + isTopFrame, escapeXML } = require('../autofill-utils') const Tooltip = require('./Tooltip') -const getInputConfig = require('../Form/inputTypeConfig') class DataAutofill extends Tooltip { - constructor (input, associatedForm, Interface) { - super(input, associatedForm, Interface) - - const config = getInputConfig(input) - - this.data = this.interface[`getLocal${config.dataType}`]() - + /** + * @param {InputTypeConfigs} config + * @param {TooltipItemRenderer[]} items + * @param {{onSelect(id:string): void}} callbacks + */ + render (config, items, callbacks) { const includeStyles = isApp ? `` : `` + let hasAddedSeparator = false + // Only show an hr above the first duck address button, but it can be either personal or private + const shouldShowSeparator = (dataId) => { + const shouldShow = ['personalAddress', 'privateAddress'].includes(dataId) && !hasAddedSeparator + if (shouldShow) hasAddedSeparator = true + return shouldShow + } + + const topClass = isTopFrame ? 'top-autofill' : '' + this.shadow.innerHTML = ` ${includeStyles} -
      +
      ` this.wrapper = this.shadow.querySelector('.wrapper') @@ -42,13 +54,12 @@ ${escapeXML(singleData[config.displaySubtitlePropName] || config.displaySubtitle this.autofillButtons.forEach((btn) => { this.registerClickableButton(btn, () => { - this.interface[`${config.autofillMethod}`](btn.id).then(({success, error}) => { - if (success) this.associatedForm.autofillData(success, config.type) - }) + callbacks.onSelect(btn.id) }) }) this.init() + return this } } diff --git a/src/UI/EmailAutofill.js b/src/UI/EmailAutofill.js index 518dd9521..08ef03383 100644 --- a/src/UI/EmailAutofill.js +++ b/src/UI/EmailAutofill.js @@ -1,13 +1,13 @@ const { isApp, - formatAddress, + formatDuckAddress, escapeXML } = require('../autofill-utils') const Tooltip = require('./Tooltip') class EmailAutofill extends Tooltip { - constructor (input, associatedForm, Interface) { - super(input, associatedForm, Interface) + constructor (config, inputType, position, deviceInterface) { + super(config, inputType, position, deviceInterface) this.addresses = this.interface.getLocalAddresses() @@ -21,7 +21,7 @@ ${includeStyles}