From 94c60fe530d0989f7aa925981329e8a7e1c84115 Mon Sep 17 00:00:00 2001 From: Oliver Shi Date: Wed, 12 May 2021 10:30:19 -0400 Subject: [PATCH 01/56] add Coveralls github workflow (#759) Adds a code coverage workflow using Coveralls Only static .js files have their coverage collected. Trying to collect code coverage from hbs files masquerading as js files causes the coverage reporter to crash, since it can't parse the hbs portions of the file correctly. Also adds a code coverage badge to the readme. J=SLAP-873 TEST=auto --- .github/workflows/coverage.yml | 30 ++++++++++++++++++++++++++++++ README.md | 6 ++++++ package.json | 3 +++ 3 files changed, 39 insertions(+) create mode 100644 .github/workflows/coverage.yml diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml new file mode 100644 index 000000000..1b4b984f7 --- /dev/null +++ b/.github/workflows/coverage.yml @@ -0,0 +1,30 @@ +# This workflow will run our tests, generate an lcov code coverage file, +# and send that coverage to Coveralls + +name: Code Coverage + +on: + push: + branches-ignore: dev/* + pull_request: + +jobs: + Coveralls: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [15.x] + + steps: + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + - run: npm ci + - run: npx jest tests/static/ --coverage + - name: Coveralls + uses: coverallsapp/github-action@master + with: + github-token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/README.md b/README.md index 8144925d1..b1b964e63 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,11 @@ # Answers Hitchhiker Theme +
+ + Coverage Status + +
+ A [Jambo](https://github.com/yext/jambo) theme for building Answers experiences. Additonal resources for integrating Answers can be found at https://hitchhikers.yext.com/. diff --git a/package.json b/package.json index 9c4c98492..c998903a3 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,9 @@ "yargs": "^17.0" }, "jest": { + "collectCoverageFrom": [ + "static/**/*.js" + ], "verbose": true, "moduleFileExtensions": [ "js" From 54cdd25b3b493ba5c195481d7e72216f239e98ec Mon Sep 17 00:00:00 2001 From: Oliver Shi Date: Wed, 12 May 2021 10:25:09 -0400 Subject: [PATCH 02/56] fix test-site's mock date (#764) This commit fixes an issue with the mocked date we use for our formatters in the test-site. Currently, we create an instance of Date, and decorate the original Date class to return this instance if new Date() is called with no params (which should return the current date). However, the issue is that, if new Date() is called, and then out of its setters is called, like setHours() or setMinutes(), which we call in our HoursStringsLocalizer, this fixed instance will be mutated. This causes inconsistent date time behavior when using the test-site for local testing. This is fixed by returning a new instance of Date every time the Date() constructor is called. J=SLAP-1313 TEST=manual open dev tools and see that the output of new Date() is the expected date, and that without this change it is not --- test-site/static/js/formatters-custom.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test-site/static/js/formatters-custom.js b/test-site/static/js/formatters-custom.js index 1a9abd410..6bcb27325 100644 --- a/test-site/static/js/formatters-custom.js +++ b/test-site/static/js/formatters-custom.js @@ -1,6 +1,5 @@ -const mockedDate = new Date('December 25, 2020 12:42:00'); global.Date = class extends Date { - constructor(date) { - return date ? super(date) : mockedDate; + constructor(date = 'December 25, 2020 12:42:00 GMT-0500') { + super(date); } }; \ No newline at end of file From 1a2e170ee3915f6eefe19d4eb6dd57100dc9fa52 Mon Sep 17 00:00:00 2001 From: Oliver Shi Date: Wed, 12 May 2021 10:25:17 -0400 Subject: [PATCH 03/56] remove + signs from percy snapshot query params (#765) When the percy snapshot infra was updated to use an object instead of directly specifying the query param string, plus signs were kept as + signs instead of being translated into spaces. J=SLAP-1313 TEST=auto check that the "office sparce" snapshots show the spell check again --- tests/percy/photographer.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/percy/photographer.js b/tests/percy/photographer.js index 95bef904f..ee5f50e44 100644 --- a/tests/percy/photographer.js +++ b/tests/percy/photographer.js @@ -34,7 +34,7 @@ class Photographer { await this._pageNavigator.gotoUniversalPage({ query: 'a' }); await this._camera.snapshot('universal-search'); - await this._pageNavigator.gotoUniversalPage({ query: 'office+sparce'}); + await this._pageNavigator.gotoUniversalPage({ query: 'office sparce'}); await this._camera.snapshot('universal-search--spellcheck'); } @@ -73,7 +73,7 @@ class Photographer { await this._camera.snapshotMobileOnly('vertical-full-page-map__mobile-detail-view'); await this._pageNavigator - .gotoVerticalPage('locations_full_page_map', { query: 'office+sparce'}); + .gotoVerticalPage('locations_full_page_map', { query: 'office sparce'}); await this._camera.snapshotDesktopOnly('vertical-full-page-map--spellcheck__desktop-view'); await this._camera.snapshotMobileOnly('vertical-full-page-map--spellcheck__mobile-list-view'); From 2eda3c454949b320b004356b5d3dc80c8b6f3be0 Mon Sep 17 00:00:00 2001 From: Oliver Shi Date: Wed, 12 May 2021 10:27:47 -0400 Subject: [PATCH 04/56] use express instead of serve-handler for snapshots (#766) This pr updates our tests to use express instead of serve-handler. serve (likely due to using serve-handler) currently has a bug where, if any redirects occur, it will lose any query params you had in the url. See: vercel/serve#643 On top of that, serve will automatically redirect urls like /index.html to just /, which breaks our iframe integration for universal. J=SLAP-1313 TEST=auto percy snapshots for universal on iframe are now corrected and show the correct query --- package-lock.json | 11 +---------- package.json | 1 + tests/percy/iframepagenavigator.js | 4 ++-- tests/percy/standardpagenavigator.js | 2 +- tests/test-utils/server.js | 15 ++++++--------- 5 files changed, 11 insertions(+), 22 deletions(-) diff --git a/package-lock.json b/package-lock.json index aa6f50f58..e0a992e66 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6794,10 +6794,7 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/full-icu/-/full-icu-1.3.1.tgz", "integrity": "sha512-VMtK//85QJomhk3cXOCksNwOYaw1KWnYTS37GYGgyf7A3ajdBoPGhaJuJWAH2S2kq8GZeXkdKn+3Mfmgy11cVw==", - "dev": true, - "requires": { - "icu4c-data": "^0.64.2" - } + "dev": true }, "function-bind": { "version": "1.1.1", @@ -7216,12 +7213,6 @@ "safer-buffer": ">= 2.1.2 < 3" } }, - "icu4c-data": { - "version": "0.67.2", - "resolved": "https://registry.npmjs.org/icu4c-data/-/icu4c-data-0.67.2.tgz", - "integrity": "sha512-OIRiop+k1IVf4TBLEOj910duoO9NKwtJLwp++qWT6KT5gRziHNt+5gwhcGuTqRy++RTK2gLoAIbk8KYCNxW++g==", - "dev": true - }, "ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", diff --git a/package.json b/package.json index c998903a3..e0e478e3d 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "babel-jest": "^25.5.1", "comment-json": "^4.1.0", "cross-env": "^7.0.2", + "express": "^4.17.1", "file-system": "^2.2.2", "full-icu": "^1.3.1", "handlebars": "^4.7.6", diff --git a/tests/percy/iframepagenavigator.js b/tests/percy/iframepagenavigator.js index dc2496e49..6c4f0bdec 100644 --- a/tests/percy/iframepagenavigator.js +++ b/tests/percy/iframepagenavigator.js @@ -19,14 +19,14 @@ class IframePageNavigator extends PageNavigator { async gotoUniversalPage(queryParams = {}) { const queryParamsString = getQueryParamsString(queryParams); - const url = `${this._siteUrl}/${this._iframePage}?${queryParamsString}`; + const url = `${this._siteUrl}/${this._iframePage}.html?${queryParamsString}`; await this._page.goto(url); await waitTillHTMLRendered(this._page); } async gotoVerticalPage(vertical, queryParams = {}) { const queryParamsString = getQueryParamsString(queryParams); - const url = `${this._siteUrl}/${this._iframePage}?verticalUrl=${vertical}&${queryParamsString}`; + const url = `${this._siteUrl}/${this._iframePage}.html?verticalUrl=${vertical}.html&${queryParamsString}`; await this._page.goto(url); await waitTillHTMLRendered(this._page); } diff --git a/tests/percy/standardpagenavigator.js b/tests/percy/standardpagenavigator.js index 665b6ddd9..37e18ab54 100644 --- a/tests/percy/standardpagenavigator.js +++ b/tests/percy/standardpagenavigator.js @@ -24,7 +24,7 @@ class StandardPageNavigator extends PageNavigator { async gotoVerticalPage(vertical, queryParams = {}) { const queryParamsString = getQueryParamsString(queryParams); - const url = `${this._siteUrl}/${vertical}?${queryParamsString}`; + const url = `${this._siteUrl}/${vertical}.html?${queryParamsString}`; await this._page.goto(url); await waitTillHTMLRendered(this._page); } diff --git a/tests/test-utils/server.js b/tests/test-utils/server.js index 678f1792d..0668ed630 100644 --- a/tests/test-utils/server.js +++ b/tests/test-utils/server.js @@ -1,5 +1,4 @@ -const http = require('http'); -const handler = require('serve-handler'); +const express = require('express'); /** * A simple http server @@ -13,12 +12,8 @@ class HttpServer { * @param {number} config.port - The port to serve at */ constructor ({dir, port}) { - this._server = http.createServer((request, response) => { - return handler(request, response, { - "public": dir - }); - }); - + this._app = express(); + this._app.use(express.static(dir)); this._port = port; } @@ -26,7 +21,9 @@ class HttpServer { * Starts the server */ start () { - this._server.listen(this._port); + this._server = this._app.listen(this._port, () => { + console.log(`listening at http://localhost:${this._port}`); + }); } /** From 1e7549cd58756174306124862c24f8802723855b Mon Sep 17 00:00:00 2001 From: Oliver Shi Date: Wed, 12 May 2021 14:07:06 -0400 Subject: [PATCH 05/56] fix acceptance tests false positives (#778) Previously, the acceptance test github check would always pass, even if tests failed. There currently is some issue with how we load mapbox-gl and firefox:headless, which would cause a "Failed to initialize WebGL." error, which only occurs for firefox:headless, and not chrome:headless or regular firefox. As a short term fix we now run firefox in browserstack. J=SLAP-1319 TEST=auto see that the process will exit with 1 (by checking `$?` in terminal) if I throw an error inside of acceptance/index.js's `try` block, and also that the github acceptance test check will report a failure see that the acceptance test check will report a failure if any tests fail, and exit with status code 1 --- .github/run_browserstack_acceptance.sh | 2 +- .github/workflows/acceptance.yml | 2 +- package-lock.json | 6 +++--- package.json | 2 +- tests/acceptance/index.js | 5 ++++- 5 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.github/run_browserstack_acceptance.sh b/.github/run_browserstack_acceptance.sh index b7a59d317..2459fc882 100755 --- a/.github/run_browserstack_acceptance.sh +++ b/.github/run_browserstack_acceptance.sh @@ -6,4 +6,4 @@ export BROWSERSTACK_BUILD_ID="${GITHUB_BRANCH} - ${GITHUB_RUN_ID}" COMMIT_MSG_TITLE=$(git log -n 1 --pretty=format:%s) export BROWSERSTACK_TEST_RUN_NAME=$COMMIT_MSG_TITLE -npm run acceptance -- --browsers browserstack:ie@11.0 browserstack:safari +npm run acceptance -- --browsers browserstack:ie@11.0 browserstack:safari browserstack:firefox diff --git a/.github/workflows/acceptance.yml b/.github/workflows/acceptance.yml index 563be0ef1..11c8d5441 100644 --- a/.github/workflows/acceptance.yml +++ b/.github/workflows/acceptance.yml @@ -31,4 +31,4 @@ jobs: - run: npm run setup-test-site - run: npm run build-test-site - name: Run Acceptance Tests - run: npm run acceptance -- --browsers chrome:headless firefox:headless + run: npm run acceptance -- --browsers chrome:headless diff --git a/package-lock.json b/package-lock.json index e0a992e66..97d39c06c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13950,9 +13950,9 @@ "dev": true }, "yargs": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.0.0.tgz", - "integrity": "sha512-gbtedDPfBgG40iLbaRXhqYJycUYqFVZQLIxl1cG5Ez/xZL/47TetSYzPSIixkWa36GKHr9D/o/oSG1vHXF4zTw==", + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.0.1.tgz", + "integrity": "sha512-xBBulfCc8Y6gLFcrPvtqKz9hz8SO0l1Ni8GgDekvBX2ro0HRQImDGnikfc33cgzcYUSncapnNcZDjVFIH3f6KQ==", "dev": true, "requires": { "cliui": "^7.0.2", diff --git a/package.json b/package.json index e0e478e3d..3af46a70f 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "testcafe-browser-provider-browserstack": "^1.13.1", "underscore.string": "^3.3.5", "urijs": "1.18.12", - "yargs": "^17.0" + "yargs": "^17.0.1" }, "jest": { "collectCoverageFrom": [ diff --git a/tests/acceptance/index.js b/tests/acceptance/index.js index 95827ebce..114c2cf63 100644 --- a/tests/acceptance/index.js +++ b/tests/acceptance/index.js @@ -23,11 +23,14 @@ runTests(argv.browsers); async function runTests (browsers) { const testcafe = await createTestCafe(); try { - await testcafe.createRunner() + const numberTestsFailed = await testcafe.createRunner() .src('tests/acceptance/suites/*.js') .browsers(browsers) .startApp(`npx serve -p ${PORT} test-site/public`, 4000) .run({ quarantineMode: true }); + if (numberTestsFailed > 0) { + process.exit(1); + } } finally { await testcafe.close(); From d97720ad87897bdb98b780f628d51b142bddc60e Mon Sep 17 00:00:00 2001 From: Oliver Shi Date: Thu, 13 May 2021 10:29:14 -0400 Subject: [PATCH 06/56] update acceptance test workflow name (#779) I think initially the workflow only ran tests in browserstack, but the headless tests don't use browserstack. --- .github/workflows/acceptance.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/acceptance.yml b/.github/workflows/acceptance.yml index 11c8d5441..2793e3143 100644 --- a/.github/workflows/acceptance.yml +++ b/.github/workflows/acceptance.yml @@ -1,4 +1,4 @@ -name: BrowserStack Acceptance Tests +name: Acceptance Tests on: push From 8866b7889f6f0ea935e7a8e21b375418e2547aad Mon Sep 17 00:00:00 2001 From: Tom Meyer Date: Thu, 13 May 2021 12:35:39 -0400 Subject: [PATCH 07/56] Update Theme dependencies according to Dependabot's suggestions. (#780) (#781) Dependabot suggested we update the following dependencies: - hosted-git-info from 2.8.8 to 2.8.9. - postcss from 8.1.4 to 8.2.10. - lodash from 4.17.20 to 4.17.21. - grunt from 1.1.0 to 1.3.0. TEST=manual Built a local Jambo site and ensured the served site looked as expected. Also verified that the Grunt watch task still worked. --- static/package-lock.json | 564 +++++++++++++++++++++++++++++++-------- static/package.json | 4 +- 2 files changed, 448 insertions(+), 120 deletions(-) diff --git a/static/package-lock.json b/static/package-lock.json index dbc2bb216..e1cf08191 100644 --- a/static/package-lock.json +++ b/static/package-lock.json @@ -1612,12 +1612,24 @@ "integrity": "sha512-Z/JnaVEXv+A9xabHzN43FiiiWEE7gPCRXMrVmRm00tWbjZRul1iHm7ECzlyNq1p4a4ATXz+G9FJ3GqGOkOV3fg==", "dev": true }, + "array-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", + "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", + "dev": true + }, "array-find-index": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", "dev": true }, + "array-slice": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", + "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", + "dev": true + }, "array-union": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", @@ -1662,9 +1674,9 @@ "dev": true }, "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", + "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==", "dev": true }, "async-foreach": { @@ -1952,12 +1964,6 @@ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true }, - "coffeescript": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-1.10.0.tgz", - "integrity": "sha1-56qDAZF+9iGzXYo580jc3R234z4=", - "dev": true - }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -2326,14 +2332,10 @@ } }, "dateformat": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz", - "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", - "dev": true, - "requires": { - "get-stdin": "^4.0.1", - "meow": "^3.3.0" - } + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "dev": true }, "debug": { "version": "4.1.1", @@ -2404,6 +2406,12 @@ "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", "dev": true }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true + }, "dir-glob": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", @@ -2783,6 +2791,15 @@ "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", "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" + } + }, "ext": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", @@ -2942,11 +2959,45 @@ } } }, + "fined": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", + "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "is-plain-object": "^2.0.3", + "object.defaults": "^1.1.0", + "object.pick": "^1.2.0", + "parse-filepath": "^1.0.1" + } + }, + "flagged-respawn": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", + "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", + "dev": true + }, "font-awesome": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz", "integrity": "sha1-j6jPBBGhoxr9B7BtKQK7n8gVoTM=" }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "dev": true, + "requires": { + "for-in": "^1.0.1" + } + }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -3072,9 +3123,9 @@ } }, "getobject": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz", - "integrity": "sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/getobject/-/getobject-1.0.1.tgz", + "integrity": "sha512-tj18lLe+917AACr6BdVoUuHnBPTVd9BEJp1vxnMZ58ztNvuxz9Ufa+wf3g37tlGITH35jggwZ2d9lcgHJJgXfQ==", "dev": true }, "getpass": { @@ -3150,6 +3201,30 @@ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "dev": true }, + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -3238,53 +3313,87 @@ "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" }, "grunt": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.1.0.tgz", - "integrity": "sha512-+NGod0grmviZ7Nzdi9am7vuRS/h76PcWDsV635mEXF0PEQMUV6Kb+OjTdsVxbi0PZmfQOjCMKb3w8CVZcqsn1g==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.4.0.tgz", + "integrity": "sha512-yRFc0GVCDu9yxqOFzpuXQ2pEdgtLDnFv5Qz54jfIcNnpJ8Z7B7P7kPkT4VMuRvm+N+QOsI8C4v/Q0DSaoj3LgQ==", "dev": true, "requires": { - "coffeescript": "~1.10.0", - "dateformat": "~1.0.12", + "dateformat": "~3.0.3", "eventemitter2": "~0.4.13", - "exit": "~0.1.1", + "exit": "~0.1.2", "findup-sync": "~0.3.0", - "glob": "~7.0.0", - "grunt-cli": "~1.2.0", - "grunt-known-options": "~1.1.0", - "grunt-legacy-log": "~2.0.0", - "grunt-legacy-util": "~1.1.1", + "glob": "~7.1.6", + "grunt-cli": "~1.4.2", + "grunt-known-options": "~1.1.1", + "grunt-legacy-log": "~3.0.0", + "grunt-legacy-util": "~2.0.1", "iconv-lite": "~0.4.13", - "js-yaml": "~3.13.1", - "minimatch": "~3.0.2", - "mkdirp": "~1.0.3", + "js-yaml": "~3.14.0", + "minimatch": "~3.0.4", + "mkdirp": "~1.0.4", "nopt": "~3.0.6", - "path-is-absolute": "~1.0.0", - "rimraf": "~2.6.2" + "rimraf": "~3.0.2" }, "dependencies": { + "glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, "grunt-cli": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.2.0.tgz", - "integrity": "sha1-VisRnrsGndtGSs4oRVAb6Xs1tqg=", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.4.2.tgz", + "integrity": "sha512-wsu6BZh7KCnfeaSkDrKIAvOlqGKxNRTZjc8xfZlvxCByQIqUfZ31kh5uHpPnhQ4NdVgvaWaVxa1LUbVU80nACw==", "dev": true, "requires": { - "findup-sync": "~0.3.0", - "grunt-known-options": "~1.1.0", - "nopt": "~3.0.6", - "resolve": "~1.1.0" + "grunt-known-options": "~1.1.1", + "interpret": "~1.1.0", + "liftup": "~3.0.1", + "nopt": "~4.0.1", + "v8flags": "~3.2.0" + }, + "dependencies": { + "nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "dev": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + } } }, + "interpret": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", + "dev": true + }, "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true }, - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } } } }, @@ -3318,50 +3427,100 @@ "dev": true }, "grunt-legacy-log": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-2.0.0.tgz", - "integrity": "sha512-1m3+5QvDYfR1ltr8hjiaiNjddxGdQWcH0rw1iKKiQnF0+xtgTazirSTGu68RchPyh1OBng1bBUjLmX8q9NpoCw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-3.0.0.tgz", + "integrity": "sha512-GHZQzZmhyq0u3hr7aHW4qUH0xDzwp2YXldLPZTCjlOeGscAOWWPftZG3XioW8MasGp+OBRIu39LFx14SLjXRcA==", "dev": true, "requires": { "colors": "~1.1.2", - "grunt-legacy-log-utils": "~2.0.0", + "grunt-legacy-log-utils": "~2.1.0", "hooker": "~0.2.3", - "lodash": "~4.17.5" + "lodash": "~4.17.19" } }, "grunt-legacy-log-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.0.1.tgz", - "integrity": "sha512-o7uHyO/J+i2tXG8r2bZNlVk20vlIFJ9IEYyHMCQGfWYru8Jv3wTqKZzvV30YW9rWEjq0eP3cflQ1qWojIe9VFA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.1.0.tgz", + "integrity": "sha512-lwquaPXJtKQk0rUM1IQAop5noEpwFqOXasVoedLeNzaibf/OPWjKYvvdqnEHNmU+0T0CaReAXIbGo747ZD+Aaw==", "dev": true, "requires": { - "chalk": "~2.4.1", - "lodash": "~4.17.10" + "chalk": "~4.1.0", + "lodash": "~4.17.19" + }, + "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.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "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" + } + } } }, "grunt-legacy-util": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-1.1.1.tgz", - "integrity": "sha512-9zyA29w/fBe6BIfjGENndwoe1Uy31BIXxTH3s8mga0Z5Bz2Sp4UCjkeyv2tI449ymkx3x26B+46FV4fXEddl5A==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-2.0.1.tgz", + "integrity": "sha512-2bQiD4fzXqX8rhNdXkAywCadeqiPiay0oQny77wA2F3WF4grPJXCvAcyoWUJV+po/b15glGkxuSiQCK299UC2w==", "dev": true, "requires": { - "async": "~1.5.2", - "exit": "~0.1.1", - "getobject": "~0.1.0", + "async": "~3.2.0", + "exit": "~0.1.2", + "getobject": "~1.0.0", "hooker": "~0.2.3", - "lodash": "~4.17.10", - "underscore.string": "~3.3.4", - "which": "~1.3.0" + "lodash": "~4.17.21", + "underscore.string": "~3.3.5", + "which": "~2.0.2" }, "dependencies": { - "underscore.string": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.5.tgz", - "integrity": "sha512-g+dpmgn+XBneLmXXo+sGlW5xQEt4ErkS3mgeN2GFbremYeMBSJKr9Wf2KJplQVaiPY/f7FN6atosWYNm9ovrYg==", + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { - "sprintf-js": "^1.0.3", - "util-deprecate": "^1.0.2" + "isexe": "^2.0.0" } } } @@ -3374,14 +3533,6 @@ "requires": { "deep-for-each": "^3.0.0", "lodash": "^4.17.19" - }, - "dependencies": { - "lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", - "dev": true - } } }, "handlebars": { @@ -3468,6 +3619,15 @@ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "requires": { + "parse-passwd": "^1.0.0" + } + }, "hooker": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz", @@ -3475,9 +3635,9 @@ "dev": true }, "hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, "html-encoding-sniffer": { @@ -3825,6 +3985,12 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, "interpret": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", @@ -3846,6 +4012,16 @@ "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", "dev": true }, + "is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, + "requires": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + } + }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -3858,6 +4034,15 @@ "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", "dev": true }, + "is-core-module": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", + "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, "is-date-object": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", @@ -3931,6 +4116,15 @@ "has-symbols": "^1.0.1" } }, + "is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "dev": true, + "requires": { + "is-unc-path": "^1.0.0" + } + }, "is-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", @@ -3952,12 +4146,27 @@ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, + "is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dev": true, + "requires": { + "unc-path-regex": "^0.1.2" + } + }, "is-utf8": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", "dev": true }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -4057,9 +4266,9 @@ "dev": true }, "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "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, "requires": { "argparse": "^1.0.7", @@ -4230,23 +4439,42 @@ "xml2js": "^0.4.17" } }, - "line-column": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/line-column/-/line-column-1.0.2.tgz", - "integrity": "sha1-0lryk2tvSEkXKzEuR5LR2Ye8NKI=", + "liftup": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/liftup/-/liftup-3.0.1.tgz", + "integrity": "sha512-yRHaiQDizWSzoXk3APcA71eOI/UuhEkNN9DiW2Tt44mhYzX4joFoCZlxsSOF7RyeLlfqzFLQI1ngFq3ggMPhOw==", "dev": true, "requires": { - "isarray": "^1.0.0", - "isobject": "^2.0.0" + "extend": "^3.0.2", + "findup-sync": "^4.0.0", + "fined": "^1.2.0", + "flagged-respawn": "^1.0.1", + "is-plain-object": "^2.0.4", + "object.map": "^1.0.1", + "rechoir": "^0.7.0", + "resolve": "^1.19.0" }, "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "findup-sync": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-4.0.0.tgz", + "integrity": "sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==", + "dev": true, + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^4.0.2", + "resolve-dir": "^1.0.1" + } + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", "dev": true, "requires": { - "isarray": "1.0.0" + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" } } } @@ -4317,9 +4545,9 @@ } }, "lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, "lodash.clonedeep": { @@ -4391,6 +4619,21 @@ "semver": "^5.6.0" } }, + "make-iterator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", + "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", + "dev": true, + "requires": { + "kind-of": "^6.0.2" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, "map-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", @@ -4607,9 +4850,9 @@ "dev": true }, "nanoid": { - "version": "3.1.16", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.16.tgz", - "integrity": "sha512-+AK8MN0WHji40lj8AEuwLOvLSbWYApQpre/aFJZD71r43wVRLrOYS4FmJOPQYon1TqB462RzrrxlfA74XRES8w==", + "version": "3.1.23", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz", + "integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==", "dev": true }, "neo-async": { @@ -4843,6 +5086,18 @@ "object-keys": "^1.0.11" } }, + "object.defaults": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", + "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", + "dev": true, + "requires": { + "array-each": "^1.0.1", + "array-slice": "^1.0.0", + "for-own": "^1.0.0", + "isobject": "^3.0.0" + } + }, "object.getownpropertydescriptors": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", @@ -4853,6 +5108,25 @@ "es-abstract": "^1.17.0-next.1" } }, + "object.map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", + "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", + "dev": true, + "requires": { + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -4938,6 +5212,17 @@ "tslib": "^1.10.0" } }, + "parse-filepath": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", + "dev": true, + "requires": { + "is-absolute": "^1.0.0", + "map-cache": "^0.2.0", + "path-root": "^0.1.1" + } + }, "parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", @@ -4947,6 +5232,12 @@ "error-ex": "^1.2.0" } }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, "parse-srcset": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz", @@ -4990,6 +5281,21 @@ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, + "path-root": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", + "dev": true, + "requires": { + "path-root-regex": "^0.1.0" + } + }, + "path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", + "dev": true + }, "path-type": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", @@ -5055,17 +5361,22 @@ "dev": true }, "postcss": { - "version": "8.1.4", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.1.4.tgz", - "integrity": "sha512-LfqcwgMq9LOd8pX7K2+r2HPitlIGC5p6PoZhVELlqhh2YGDVcXKpkCseqan73Hrdik6nBd2OvoDPUaP/oMj9hQ==", + "version": "8.2.15", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.15.tgz", + "integrity": "sha512-2zO3b26eJD/8rb106Qu2o7Qgg52ND5HPjcyQiK2B98O388h43A448LCslC0dI2P97wCAQRJsFvwTRcXxTKds+Q==", "dev": true, "requires": { - "colorette": "^1.2.1", - "line-column": "^1.0.2", - "nanoid": "^3.1.15", + "colorette": "^1.2.2", + "nanoid": "^3.1.23", "source-map": "^0.6.1" }, "dependencies": { + "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 + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -5661,14 +5972,6 @@ "dev": true, "requires": { "lodash": "^4.17.19" - }, - "dependencies": { - "lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", - "dev": true - } } }, "request-promise-native": { @@ -5712,6 +6015,16 @@ "resolve-from": "^5.0.0" } }, + "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, + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + } + }, "resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", @@ -6740,6 +7053,12 @@ "dev": true, "optional": true }, + "unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", + "dev": true + }, "underscore.string": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.5.tgz", @@ -6865,6 +7184,15 @@ "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==", "dev": true }, + "v8flags": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", + "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, "validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", diff --git a/static/package.json b/static/package.json index 5cc473c98..073c8d35e 100644 --- a/static/package.json +++ b/static/package.json @@ -24,7 +24,7 @@ "file-loader": "^5.1.0", "file-system": "^2.2.2", "fs-extra": "^9.0.1", - "grunt": "^1.0.4", + "grunt": "^1.3.0", "grunt-contrib-watch": "^1.1.0", "grunt-webpack": "^4.0.0", "html-loader": "^1.1.0", @@ -33,7 +33,7 @@ "jsdom": "^16.4.0", "mini-css-extract-plugin": "^1.6.0", "node-sass": "^4.13.1", - "postcss": "^8.1.4", + "postcss": "^8.2.10", "resolve-url-loader": "^3.1.1", "sass-loader": "^8.0.2", "simple-git": "^2.15.0", From 78a6b96327da205dca51489bdba9807662fa43cf Mon Sep 17 00:00:00 2001 From: cea2aj <42848445+cea2aj@users.noreply.github.com> Date: Wed, 19 May 2021 16:01:01 -0400 Subject: [PATCH 08/56] Optimize the HoursTransformer (#784) Improve the HoursTransformer The clonedeep unnecessarily increased the computation time. Removing it improves performance by about 22%. This PR also improves the clarity of the code by making it more functional and making the data models easier to understand. J=SLAP-1289 TEST=manual, auto Smoke test the openStatus formatter and the hoursList formatter which both rely on this code. Add unit tests. Benchmark the code by running the function 1000 times and comparing the time in milliseconds before and after. --- static/js/hours/transformer.js | 126 +++++++++++++++----------- tests/static/js/hours/transformer.js | 127 +++++++++++++++++++++++++++ 2 files changed, 204 insertions(+), 49 deletions(-) create mode 100644 tests/static/js/hours/transformer.js diff --git a/static/js/hours/transformer.js b/static/js/hours/transformer.js index 4ee55a924..3e1db1c97 100644 --- a/static/js/hours/transformer.js +++ b/static/js/hours/transformer.js @@ -1,4 +1,3 @@ -import clonedeep from 'lodash.clonedeep'; import { DayNames } from './constants.js'; import Hours from './models/hours.js'; import { OpenStatusTypes } from './open-status/constants.js'; @@ -177,6 +176,8 @@ export default class HoursTransformer { } /** + * Transforms the hours data into the shape needed by the front-end + * * @param {Object} days e.g. * { * monday: { @@ -193,43 +194,28 @@ export default class HoursTransformer { * @returns {Object[]} */ static _formatHoursForAnswers(days, timezone) { - const formattedDays = clonedeep(days); const daysOfWeek = Object.values(DayNames); - const holidayHours = formattedDays.holidayHours || []; - for (let day in formattedDays) { - if (day === 'holidayHours' || day === 'reopenDate') { - delete formattedDays[day]; - } else { + return Object.entries(days) + .filter(([day]) => day !== 'holidayHours' && day !== 'reopenDate') + .reduce((formattedDays, [day, dayInfo]) => { const currentDayName = day.toUpperCase(); const numberTimezone = this._convertTimezoneToNumber(timezone); - const userDateToEntityDate = this._getDateWithUTCOffset(numberTimezone); - const dayNameToDate = this._getNextDayOfWeek(userDateToEntityDate, daysOfWeek.indexOf(currentDayName)); - - for (let holiday of holidayHours) { - let holidayDate = new Date(holiday.date + 'T00:00:00.000'); - if (dayNameToDate.toDateString() == holidayDate.toDateString()) { - holiday.intervals = this._formatIntervals(holiday.openIntervals); - formattedDays[day].dailyHolidayHours = holiday; - } - } - - formattedDays[day].day = day.toUpperCase(); - - let intervals = formattedDays[day].openIntervals; - if (intervals) { - for (let interval of intervals) { - for (let period in interval) { - interval[period] = parseInt(interval[period].replace(':', '')); - } - } - } else { - formattedDays[day].openIntervals = []; + const userDate = this._getDateWithUTCOffset(numberTimezone); + const nextDayOfWeek = this._getNextDayOfWeek(userDate, daysOfWeek.indexOf(currentDayName)); + const dailyHolidayHours = this._getDailyHolidayHours(days.holidayHours, nextDayOfWeek); + const openIntervals = (dayInfo.openIntervals || []).map(this._formatInterval); + + const formattedDay = { + day: currentDayName, + ...dailyHolidayHours && { dailyHolidayHours }, + openIntervals: openIntervals, + intervals: openIntervals, + isClosed: dayInfo.isClosed } - formattedDays[day].intervals = formattedDays[day].openIntervals; - } - } - return Object.values(formattedDays); + formattedDays.push(formattedDay); + return formattedDays; + }, []); } /** @@ -272,24 +258,66 @@ export default class HoursTransformer { } /** - * Returns the hours intervals array with hours parsed into a number - * e.g. "09:00" turning into 900. - * @param {Object[]} intervals - * @param {string} intervals[].start start time like "09:00" - * @param {string} intervals[].end end time like "17:00" - * @returns {Object[]} + * @typedef HolidayHourInfo + * @type {Object} + * @property {string} date the date of the holiday + * @property {boolean} isClosed indicates whether or not the location is closed + * @property {boolean} isRegularHours indicates whether or not the location has regular hours on the holiday + * @property {OpenInterval[]} openIntervals intervals of time when the location is open */ - static _formatIntervals(intervals) { - if (!intervals) { - return []; - } - let formatted = Array.from(intervals); - for (let interval of formatted) { - for (let period in interval) { - interval[period] = parseInt(interval[period].replace(':', '')); - } + + /** + * @typedef OpenInterval + * @type {Object} + * @property {string} start start time, e.g. '03:00' + * @property {string} end end time, e.g '09:00' + */ + + /** + * Gets the holiday hours for the provided date given a HoldiayHourInfo list + * @param {HolidayHourInfo[]} holidayHours + * @param {Date} date + * @returns {Object|null} + */ + static _getDailyHolidayHours (holidayHours = [], date) { + const holidayHoursForDate = holidayHours.find(holiday => { + const holidayDate = new Date(holiday.date + 'T00:00:00.000'); + return date.toDateString() == holidayDate.toDateString(); + }); + + if (!holidayHoursForDate) { + return null; } - return formatted; + + const formattedIntervals = (holidayHoursForDate.openIntervals || []).map(this._formatInterval); + + return { + date: holidayHoursForDate.date, + intervals: formattedIntervals, + openIntervals: formattedIntervals, + ...holidayHoursForDate.isClosed && { isClosed: true }, + ...holidayHoursForDate.isRegularHours && { isRegularHours: true } + }; + } + + /** + * @typedef NumericOpenInterval + * @type {Object} + * @property {number} start start time, e.g. '300' + * @property {number} end end time, e.g '900' + */ + + /** + * Returns the hours intervals object with hours parsed into a number + * e.g. "09:00" turning into 900. + * @param {OpenInterval} interval + * @returns {NumericOpenInterval} + */ + static _formatInterval (interval) { + return Object.entries(interval).reduce((formattedInterval, [period, value]) => { + formattedInterval[period] = parseInt(value.replace(':', '')); + return formattedInterval; + }, {}); } /** diff --git a/tests/static/js/hours/transformer.js b/tests/static/js/hours/transformer.js new file mode 100644 index 000000000..6713b7e62 --- /dev/null +++ b/tests/static/js/hours/transformer.js @@ -0,0 +1,127 @@ +import { DayNames } from '../../../../static/js/hours/constants'; +import HoursTransformer from '../../../../static/js/hours/transformer'; + +const dateClass = Date; +const mockDateClass = class extends Date { + constructor(date = 'July 21, 2020 12:42:00 GMT-0500') { + super(date); + } +}; + +describe('formats hours for answers', () => { + beforeEach(() => { + // Mock the date class because holiday hours are only applied if they are for + // dates which are within one week of the current date. + global.Date = mockDateClass; + }); + + afterEach(() => { + global.Date = dateClass; + }) + + it('formats hours for multiple days', () => { + const expectedFormattedHours = [ + { + day: DayNames.MONDAY, + intervals: [{end: 400, start: 100}], + isClosed: false, + openIntervals: [{end: 400, start: 100}], + }, + { + day: DayNames.TUESDAY, + intervals: [{end: 800, start: 100}], + openIntervals: [{end: 800, start: 100}], + isClosed: false + }, + { + day: DayNames.WEDNESDAY, + intervals: [], + openIntervals: [], + isClosed: true + } + ]; + const days = { + monday: { + isClosed: false, + openIntervals: [{ start: '01:00', end: '04:00' }] + }, + tuesday: { + isClosed: false, + openIntervals: [{ start: '01:00', end: '08:00' }] + }, + wednesday: { + isClosed: true + } + } + const timezoneOffset = '-04:00'; + const actualFormattedHours = HoursTransformer._formatHoursForAnswers(days, timezoneOffset); + expect(actualFormattedHours).toEqual(expectedFormattedHours); + }); + + it('formats hours for multiple days and holiday hours', () => { + const expectedFormattedHours = [ + { + day: DayNames.TUESDAY, + intervals: [{end: 800, start: 100}], + openIntervals: [{end: 800, start: 100}], + isClosed: false, + dailyHolidayHours: { + date: '2020-07-21', + intervals: [{end: 200, start: 100}], + openIntervals: [ + { + end: 200, + start: 100, + }, + ], + }, + }, + { + day: DayNames.WEDNESDAY, + intervals: [{end: 1000, start: 100}], + openIntervals: [{end: 1000, start: 100}], + isClosed: false, + dailyHolidayHours: { + date: '2020-07-22', + isClosed: true, + intervals: [], + openIntervals: [], + }, + }, + { + day: DayNames.THURSDAY, + intervals: [{end: 400, start: 100}], + isClosed: false, + openIntervals: [{end: 400, start: 100}], + dailyHolidayHours: { + date: '2020-07-23', + intervals: [], + openIntervals: [], + isRegularHours: true + }, + }, + ]; + const days = { + tuesday: { + isClosed: false, + openIntervals: [{ start: '01:00', end: '08:00' }] + }, + wednesday: { + isClosed: false, + openIntervals: [{ start: '01:00', end: '10:00' }] + }, + thursday: { + isClosed: false, + openIntervals: [{ start: '01:00', end: '04:00' }] + }, + holidayHours: [ + { date: '2020-07-21', openIntervals: [{ start: '01:00', end: '02:00' }] }, + { date: '2020-07-22', isClosed: true }, + { date: '2020-07-23', isRegularHours: true } + ] + } + const timezoneOffset = '-04:00'; + const actualFormattedHours = HoursTransformer._formatHoursForAnswers(days, timezoneOffset); + expect(actualFormattedHours).toEqual(expectedFormattedHours); + }); +}); From a0f8092810f91d67a30f0a70c5c81ca7a62b5678 Mon Sep 17 00:00:00 2001 From: Tom Meyer Date: Thu, 20 May 2021 08:38:31 -0400 Subject: [PATCH 09/56] Do not run the `babel` helper in Development Mode. (#782) (#785) This PR adds a check to the `babel` helper to see if we are currently in the Development Mode. If so, the enclosed source code is not run through Babel, it is returned verbatim. This is a preview optimization, since the Babel-ification is a relatively slow operation. It's not necessary for preview either, assuming devs are not previewing their changes in IE11. There will need to be a corresponding Jambo PR for this as well. Jambo still has a `babel` helper of its own for legacy reasons. J=SLAP-1312 TEST=manual Ensured that when in Development mode, the helper was a simple pass-through. In Production mode, the enclosed code was Babel-ified. --- hbshelpers/babel.js | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/hbshelpers/babel.js b/hbshelpers/babel.js index 1c60ce92d..5fbb79b9a 100644 --- a/hbshelpers/babel.js +++ b/hbshelpers/babel.js @@ -1,24 +1,31 @@ const { transformSync } = require('@babel/core'); /** - * Babel-ifies the enclosed code, using the config below. + * Babel-ifies the enclosed code, using the config below. Note that if the + * IS_DEVELOPMENT_PREVIEW environment variable is set to 'true', the enclosed + * code is returned verbatim. This is an optimization for the build preview. * * @param {import('handlebars').HelperOptions} options * @returns {string|null} */ module.exports = function babel(options) { const srcCode = options.fn(this); - return transformSync(srcCode, { - compact: true, - minified: true, - comments: false, - sourceType: 'script', - presets: ['@babel/preset-env'], - plugins: [ - '@babel/syntax-dynamic-import', - '@babel/plugin-transform-arrow-functions', - '@babel/plugin-proposal-object-rest-spread', - '@babel/plugin-transform-object-assign', - ] - }).code; + + if (process.env.IS_DEVELOPMENT_PREVIEW === 'true' ) { + return srcCode; + } else { + return transformSync(srcCode, { + compact: true, + minified: true, + comments: false, + sourceType: 'script', + presets: ['@babel/preset-env'], + plugins: [ + '@babel/syntax-dynamic-import', + '@babel/plugin-transform-arrow-functions', + '@babel/plugin-proposal-object-rest-spread', + '@babel/plugin-transform-object-assign', + ] + }).code; + } }; From 3278741b0ae91ddad146a4698934f438629742cf Mon Sep 17 00:00:00 2001 From: Yen Truong Date: Thu, 20 May 2021 15:24:42 -0400 Subject: [PATCH 10/56] correct orderUrl in menuitem updated profile.orderUrl to profile.orderUrl.url, and added the related null check, in menuitem-standard and multilang-menuitem-standard component. J=SLAP-1329 TEST=manual launched test site and rendered a menu item where its profile object contains a dummy url, which redirected accordingly. --- cards/menuitem-standard/component.js | 2 +- cards/multilang-menuitem-standard/component.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cards/menuitem-standard/component.js b/cards/menuitem-standard/component.js index 599b00a08..98734bef4 100644 --- a/cards/menuitem-standard/component.js +++ b/cards/menuitem-standard/component.js @@ -37,7 +37,7 @@ class menuitem_standardCardComponent extends BaseCard['menuitem-standard'] { CTA1: { label: 'Order Now', // The CTA's label iconName: 'chevron', // The icon to use for the CTA - url: profile.orderUrl, // The URL a user will be directed to when clicking + url: profile.orderUrl && profile.orderUrl.url, // The URL a user will be directed to when clicking target: '_top', // Where the new URL will be opened eventType: 'CTA_CLICK', // Type of Analytics event fired when clicking the CTA eventOptions: this.addDefaultEventOptions(), diff --git a/cards/multilang-menuitem-standard/component.js b/cards/multilang-menuitem-standard/component.js index 8401c878b..a11366f11 100644 --- a/cards/multilang-menuitem-standard/component.js +++ b/cards/multilang-menuitem-standard/component.js @@ -37,7 +37,7 @@ class multilang_menuitem_standardCardComponent extends BaseCard['multilang-menui CTA1: { label: {{ translateJS phrase='Order Now' }}, // The CTA's label iconName: 'chevron', // The icon to use for the CTA - url: profile.orderUrl, // The URL a user will be directed to when clicking + url: profile.orderUrl && profile.orderUrl.url, // The URL a user will be directed to when clicking target: '_top', // Where the new URL will be opened eventType: 'CTA_CLICK', // Type of Analytics event fired when clicking the CTA eventOptions: this.addDefaultEventOptions(), From 08d53d6e205d6aea716fb65549c34e708ed83f8f Mon Sep 17 00:00:00 2001 From: Tom Meyer Date: Thu, 20 May 2021 17:13:21 -0400 Subject: [PATCH 11/56] Optimize `bundle.css` with `css-nano`. (#783) (#788) This PR adds the `postcss-loader` and `css-nano` to the Theme's Webpack configuration. This addition allows `css-nano` to perform a number of optimizations and minimizations on the `bundle.css` that we output. I saw the size of this asset decrease by about 10 KB on a local test site. J=SLAP-1299 TEST=auto, manual Ensured the Percy tests passed after the change. Smoke tested a local test site and verified that the styling looked as expected. --- static/package-lock.json | 1241 ++++++++++++++++++++++++++++++++++++-- static/package.json | 2 + static/webpack-config.js | 11 + 3 files changed, 1195 insertions(+), 59 deletions(-) diff --git a/static/package-lock.json b/static/package-lock.json index e1cf08191..e89a2e567 100644 --- a/static/package-lock.json +++ b/static/package-lock.json @@ -1049,6 +1049,12 @@ "resolved": "https://registry.npmjs.org/@stroncium/procfs/-/procfs-1.2.1.tgz", "integrity": "sha512-X1Iui3FUNZP18EUvysTHxt+Avu2nlVzyf90YM8OYgP6SGzTzzX/0JgObfO1AQQDzuZtNNz29bVh8h5R97JrjxA==" }, + "@trysound/sax": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.1.1.tgz", + "integrity": "sha512-Z6DoceYb/1xSg5+e+ZlPZ9v0N16ZvZ+wYMraFue4HYrE4ttONKtsvruIRf6t9TBR0YvSOfi1hUU0fJfBLCDYow==", + "dev": true + }, "@types/anymatch": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", @@ -1113,6 +1119,12 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.14.tgz", "integrity": "sha512-syUgf67ZQpaJj01/tRTknkMNoBBLWJOBODF0Zm4NrXmiSuxjymFrxnTu1QVYRubhVkRcZLYZG8STTwJRdVm/WQ==" }, + "@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "dev": true + }, "@types/parse5": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-5.0.3.tgz", @@ -1514,6 +1526,12 @@ "integrity": "sha512-eyoaac3btgU8eJlvh01En8OCKzRqlLe2G5jDsCr3RiE2uLGMEEB1aaGwVVpwR8M95956tGH6R+9edC++OvzaVw==", "dev": true }, + "alphanum-sort": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", + "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", + "dev": true + }, "amdefine": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", @@ -1831,6 +1849,12 @@ "integrity": "sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=", "dev": true }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, "camel-case": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.1.tgz", @@ -1865,6 +1889,18 @@ } } }, + "caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, "caniuse-lite": { "version": "1.0.30001164", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001164.tgz", @@ -1964,6 +2000,16 @@ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true }, + "color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/color/-/color-3.1.3.tgz", + "integrity": "sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ==", + "dev": true, + "requires": { + "color-convert": "^1.9.1", + "color-string": "^1.5.4" + } + }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -1979,6 +2025,16 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, + "color-string": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.5.tgz", + "integrity": "sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg==", + "dev": true, + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, "colorette": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz", @@ -2110,6 +2166,39 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, + "cosmiconfig": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", + "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", + "dev": true, + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "dependencies": { + "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-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + } + } + }, "cp-file": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-6.2.0.tgz", @@ -2161,6 +2250,21 @@ } } }, + "css-color-names": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-1.0.1.tgz", + "integrity": "sha512-/loXYOch1qU1biStIFsHH8SxTmOseh1IJqFvy8IujXOm1h+QjUdDhkzOrR5HG8K8mlxREj0yfi8ewCHx0eMxzA==", + "dev": true + }, + "css-declaration-sorter": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.0.0.tgz", + "integrity": "sha512-S0TE4E0ha5+tBHdLWPc5n+S8E4dFBS5xScPvgHkLNZwWvX4ISoFGhGeerLC9uS1cKA/sC+K2wHq6qEbcagT/fg==", + "dev": true, + "requires": { + "timsort": "^0.3.0" + } + }, "css-loader": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.6.0.tgz", @@ -2252,6 +2356,24 @@ "integrity": "sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g==", "dev": true }, + "css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "dev": true, + "requires": { + "mdn-data": "2.0.14", + "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 + } + } + }, "css-vars-ponyfill": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/css-vars-ponyfill/-/css-vars-ponyfill-2.4.2.tgz", @@ -2269,6 +2391,69 @@ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "dev": true }, + "cssnano": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.0.2.tgz", + "integrity": "sha512-8JK3EnPsjQsULme9/e5M2hF564f/480hwsdcHvQ7ZtAIMfQ1O3SCfs+b8Mjf5KJxhYApyRshR2QSovEJi2K72Q==", + "dev": true, + "requires": { + "cosmiconfig": "^7.0.0", + "cssnano-preset-default": "^5.0.1", + "is-resolvable": "^1.1.0" + } + }, + "cssnano-preset-default": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.0.1.tgz", + "integrity": "sha512-cfmfThYODGqhpQKDq9H0MTAqkMvZ3dGbOUTBKw0xWZiIycMqHid22LsJXJl4r1qX4qzDeKxcSyQ/Xb5Mu3Z//Q==", + "dev": true, + "requires": { + "css-declaration-sorter": "6.0.0", + "cssnano-utils": "^2.0.0", + "postcss-calc": "^8.0.0", + "postcss-colormin": "^5.0.0", + "postcss-convert-values": "^5.0.0", + "postcss-discard-comments": "^5.0.0", + "postcss-discard-duplicates": "^5.0.0", + "postcss-discard-empty": "^5.0.0", + "postcss-discard-overridden": "^5.0.0", + "postcss-merge-longhand": "^5.0.1", + "postcss-merge-rules": "^5.0.0", + "postcss-minify-font-values": "^5.0.0", + "postcss-minify-gradients": "^5.0.0", + "postcss-minify-params": "^5.0.0", + "postcss-minify-selectors": "^5.0.0", + "postcss-normalize-charset": "^5.0.0", + "postcss-normalize-display-values": "^5.0.0", + "postcss-normalize-positions": "^5.0.0", + "postcss-normalize-repeat-style": "^5.0.0", + "postcss-normalize-string": "^5.0.0", + "postcss-normalize-timing-functions": "^5.0.0", + "postcss-normalize-unicode": "^5.0.0", + "postcss-normalize-url": "^5.0.0", + "postcss-normalize-whitespace": "^5.0.0", + "postcss-ordered-values": "^5.0.0", + "postcss-reduce-initial": "^5.0.0", + "postcss-reduce-transforms": "^5.0.0", + "postcss-svgo": "^5.0.0", + "postcss-unique-selectors": "^5.0.0" + } + }, + "cssnano-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-2.0.0.tgz", + "integrity": "sha512-xvxmTszdrvSyTACdPe8VU5J6p4sm3egpgw54dILvNqt5eBUv6TFjACLhSxtRuEsxYrgy8uDy269YjScO5aKbGA==", + "dev": true + }, + "csso": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "dev": true, + "requires": { + "css-tree": "^1.1.2" + } + }, "cssom": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", @@ -2507,6 +2692,15 @@ "tslib": "^1.10.0" } }, + "dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "requires": { + "is-obj": "^2.0.0" + } + }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -3619,6 +3813,12 @@ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, + "hex-color-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", + "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==", + "dev": true + }, "homedir-polyfill": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", @@ -3640,6 +3840,18 @@ "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, + "hsl-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", + "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=", + "dev": true + }, + "hsla-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", + "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=", + "dev": true + }, "html-encoding-sniffer": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", @@ -3895,6 +4107,24 @@ "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==" }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "dependencies": { + "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 + } + } + }, "import-local": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", @@ -4022,6 +4252,12 @@ "is-windows": "^1.0.1" } }, + "is-absolute-url": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", + "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", + "dev": true + }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -4034,6 +4270,28 @@ "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", "dev": true }, + "is-color-stop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", + "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=", + "dev": true, + "requires": { + "css-color-names": "^0.0.4", + "hex-color-regex": "^1.1.0", + "hsl-regex": "^1.0.0", + "hsla-regex": "^1.0.0", + "rgb-regex": "^1.0.1", + "rgba-regex": "^1.0.0" + }, + "dependencies": { + "css-color-names": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", + "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", + "dev": true + } + } + }, "is-core-module": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", @@ -4087,6 +4345,12 @@ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true + }, "is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", @@ -4125,6 +4389,12 @@ "is-unc-path": "^1.0.0" } }, + "is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "dev": true + }, "is-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", @@ -4346,6 +4616,12 @@ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "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", @@ -4405,6 +4681,12 @@ "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true }, + "klona": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.4.tgz", + "integrity": "sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA==", + "dev": true + }, "leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -4479,6 +4761,12 @@ } } }, + "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 + }, "livereload-js": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.4.0.tgz", @@ -4567,12 +4855,24 @@ "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", "dev": true }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + }, "lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", "dev": true }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", + "dev": true + }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -4640,6 +4940,12 @@ "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", "dev": true }, + "mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", + "dev": true + }, "meow": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", @@ -5004,6 +5310,12 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, + "normalize-url": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", + "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", + "dev": true + }, "npm-run-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-1.0.0.tgz", @@ -5212,6 +5524,15 @@ "tslib": "^1.10.0" } }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, "parse-filepath": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", @@ -5385,96 +5706,412 @@ } } }, - "postcss-modules-extract-imports": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", - "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", + "postcss-calc": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.0.0.tgz", + "integrity": "sha512-5NglwDrcbiy8XXfPM11F3HeC6hoT9W7GUH/Zi5U/p7u3Irv4rHhdDcIZwG0llHXV4ftsBjpfWMXAnXNl4lnt8g==", "dev": true, "requires": { - "postcss": "^7.0.5" + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.0.2" + } + }, + "postcss-colormin": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.0.0.tgz", + "integrity": "sha512-Yt84+5V6CgS/AhK7d7MA58vG8dSZ7+ytlRtWLaQhag3HXOncTfmYpuUOX4cDoXjvLfw1sHRCHMiBjYhc35CymQ==", + "dev": true, + "requires": { + "browserslist": "^4.16.0", + "color": "^3.1.1", + "postcss-value-parser": "^4.1.0" }, "dependencies": { - "postcss": { - "version": "7.0.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", - "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", + "browserslist": { + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", "dev": true, "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" } }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "caniuse-lite": { + "version": "1.0.30001228", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz", + "integrity": "sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A==", "dev": true }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } + "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 + }, + "electron-to-chromium": { + "version": "1.3.732", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.732.tgz", + "integrity": "sha512-qKD5Pbq+QMk4nea4lMuncUMhpEiQwaJyCW7MrvissnRcBDENhVfDmAqQYRQ3X525oTzhar9Zh1cK0L2d1UKYcw==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "node-releases": { + "version": "1.1.72", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", + "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", + "dev": true } } }, - "postcss-modules-local-by-default": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.2.tgz", - "integrity": "sha512-jM/V8eqM4oJ/22j0gx4jrp63GSvDH6v86OqyTHHUvk4/k1vceipZsaymiZ5PvocqZOl5SFHiFJqjs3la0wnfIQ==", + "postcss-convert-values": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.0.0.tgz", + "integrity": "sha512-V5kmYm4xoBAjNs+eHY/6XzXJkkGeg4kwNf2ocfqhLb1WBPEa4oaSmoi1fnVO7Dkblqvus9h+AenDvhCKUCK7uQ==", "dev": true, "requires": { - "icss-utils": "^4.1.1", - "postcss": "^7.0.16", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.0.0" + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-discard-comments": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.0.0.tgz", + "integrity": "sha512-Umig6Gxs8m20RihiXY6QkePd6mp4FxkA1Dg+f/Kd6uw0gEMfKRjDeQOyFkLibexbJJGHpE3lrN/Q0R9SMrUMbQ==", + "dev": true + }, + "postcss-discard-duplicates": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.0.0.tgz", + "integrity": "sha512-vEJJ+Y3pFUnO1FyCBA6PSisGjHtnphL3V6GsNvkASq/VkP3OX5/No5RYXXLxHa2QegStNzg6HYrYdo71uR4caQ==", + "dev": true + }, + "postcss-discard-empty": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.0.0.tgz", + "integrity": "sha512-+wigy099Y1xZxG36WG5L1f2zeH1oicntkJEW4TDIqKKDO2g9XVB3OhoiHTu08rDEjLnbcab4rw0BAccwi2VjiQ==", + "dev": true + }, + "postcss-discard-overridden": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.0.0.tgz", + "integrity": "sha512-hybnScTaZM2iEA6kzVQ6Spozy7kVdLw+lGw8hftLlBEzt93uzXoltkYp9u0tI8xbfhxDLTOOzHsHQCkYdmzRUg==", + "dev": true + }, + "postcss-loader": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-5.3.0.tgz", + "integrity": "sha512-/+Z1RAmssdiSLgIZwnJHwBMnlABPgF7giYzTN2NOfr9D21IJZ4mQC1R2miwp80zno9M4zMD/umGI8cR+2EL5zw==", + "dev": true, + "requires": { + "cosmiconfig": "^7.0.0", + "klona": "^2.0.4", + "semver": "^7.3.4" }, "dependencies": { - "postcss": { - "version": "7.0.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", - "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" + "yallist": "^4.0.0" } }, - "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 - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "lru-cache": "^6.0.0" } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } }, - "postcss-modules-scope": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", - "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", + "postcss-merge-longhand": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.0.1.tgz", + "integrity": "sha512-H1RO8le5deFGumQzuhJjuL0bIXPRysa+w7xtk5KrHe38oiaSS9ksPXDo24+IOS3SETPhip0J5+1uCOW+ALs3Yw==", "dev": true, "requires": { - "postcss": "^7.0.6", - "postcss-selector-parser": "^6.0.0" + "css-color-names": "^1.0.1", + "postcss-value-parser": "^4.1.0", + "stylehacks": "^5.0.0" + } + }, + "postcss-merge-rules": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.0.0.tgz", + "integrity": "sha512-TfsXbKjNYCGfUPEXGIGPySnMiJbdS+3gcVeV8gwmJP4RajyKZHW8E0FYDL1WmggTj3hi+m+WUCAvqRpX2ut4Kg==", + "dev": true, + "requires": { + "browserslist": "^4.16.0", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^2.0.0", + "postcss-selector-parser": "^6.0.4", + "vendors": "^1.0.3" }, "dependencies": { - "postcss": { - "version": "7.0.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", + "browserslist": { + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" + } + }, + "caniuse-lite": { + "version": "1.0.30001228", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz", + "integrity": "sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A==", + "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 + }, + "electron-to-chromium": { + "version": "1.3.732", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.732.tgz", + "integrity": "sha512-qKD5Pbq+QMk4nea4lMuncUMhpEiQwaJyCW7MrvissnRcBDENhVfDmAqQYRQ3X525oTzhar9Zh1cK0L2d1UKYcw==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "node-releases": { + "version": "1.1.72", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", + "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", + "dev": true + }, + "postcss-selector-parser": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz", + "integrity": "sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + } + } + }, + "postcss-minify-font-values": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.0.0.tgz", + "integrity": "sha512-zi2JhFaMOcIaNxhndX5uhsqSY1rexKDp23wV8EOmC9XERqzLbHsoRye3aYF716Zm+hkcR4loqKDt8LZlmihwAg==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-minify-gradients": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.0.0.tgz", + "integrity": "sha512-/jPtNgs6JySMwgsE5dPOq8a2xEopWTW3RyqoB9fLqxgR+mDUNLSi7joKd+N1z7FXWgVkc4l/dEBMXHgNAaUbvg==", + "dev": true, + "requires": { + "cssnano-utils": "^2.0.0", + "is-color-stop": "^1.1.0", + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-minify-params": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.0.0.tgz", + "integrity": "sha512-KvZYIxTPBVKjdd+XgObq9A+Sfv8lMkXTpbZTsjhr42XbfWIeLaTItMlygsDWfjArEc3muUfDaUFgNSeDiJ5jug==", + "dev": true, + "requires": { + "alphanum-sort": "^1.0.2", + "browserslist": "^4.16.0", + "cssnano-utils": "^2.0.0", + "postcss-value-parser": "^4.1.0", + "uniqs": "^2.0.0" + }, + "dependencies": { + "browserslist": { + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" + } + }, + "caniuse-lite": { + "version": "1.0.30001228", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz", + "integrity": "sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A==", + "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 + }, + "electron-to-chromium": { + "version": "1.3.732", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.732.tgz", + "integrity": "sha512-qKD5Pbq+QMk4nea4lMuncUMhpEiQwaJyCW7MrvissnRcBDENhVfDmAqQYRQ3X525oTzhar9Zh1cK0L2d1UKYcw==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "node-releases": { + "version": "1.1.72", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", + "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", + "dev": true + } + } + }, + "postcss-minify-selectors": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.0.0.tgz", + "integrity": "sha512-cEM0O0eWwFIvmo6nfB0lH0vO/XFwgqIvymODbfPXZ1gTA3i76FKnb7TGUrEpiTxaXH6tgYQ6DcTHwRiRS+YQLQ==", + "dev": true, + "requires": { + "alphanum-sort": "^1.0.2", + "postcss-selector-parser": "^3.1.2" + }, + "dependencies": { + "postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dev": true, + "requires": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "postcss-modules-extract-imports": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", + "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", + "dev": true, + "requires": { + "postcss": "^7.0.5" + }, + "dependencies": { + "postcss": { + "version": "7.0.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", + "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "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 + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-modules-local-by-default": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.2.tgz", + "integrity": "sha512-jM/V8eqM4oJ/22j0gx4jrp63GSvDH6v86OqyTHHUvk4/k1vceipZsaymiZ5PvocqZOl5SFHiFJqjs3la0wnfIQ==", + "dev": true, + "requires": { + "icss-utils": "^4.1.1", + "postcss": "^7.0.16", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.0.0" + }, + "dependencies": { + "postcss": { + "version": "7.0.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", + "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "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 + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-modules-scope": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", + "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", + "dev": true, + "requires": { + "postcss": "^7.0.6", + "postcss-selector-parser": "^6.0.0" + }, + "dependencies": { + "postcss": { + "version": "7.0.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", "dev": true, "requires": { @@ -5538,6 +6175,210 @@ } } }, + "postcss-normalize-charset": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.0.0.tgz", + "integrity": "sha512-pqsCkgo9KmQP0ew6DqSA+uP9YN6EfsW20pQ3JU5JoQge09Z6Too4qU0TNDsTNWuEaP8SWsMp+19l15210MsDZQ==", + "dev": true + }, + "postcss-normalize-display-values": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.0.0.tgz", + "integrity": "sha512-t4f2d//gH1f7Ns0Jq3eNdnWuPT7TeLuISZ6RQx4j8gpl5XrhkdshdNcOnlrEK48YU6Tcb6jqK7dorME3N4oOGA==", + "dev": true, + "requires": { + "cssnano-utils": "^2.0.0", + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-normalize-positions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.0.0.tgz", + "integrity": "sha512-0o6/qU5ky74X/eWYj/tv4iiKCm3YqJnrhmVADpIMNXxzFZywsSQxl8F7cKs8jQEtF3VrJBgcDHTexZy1zgDoYg==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-normalize-repeat-style": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.0.0.tgz", + "integrity": "sha512-KRT14JbrXKcFMYuc4q7lh8lvv8u22wLyMrq+UpHKLtbx2H/LOjvWXYdoDxmNrrrJzomAWL+ViEXr48/IhSUJnQ==", + "dev": true, + "requires": { + "cssnano-utils": "^2.0.0", + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-normalize-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.0.0.tgz", + "integrity": "sha512-wSO4pf7GNcDZpmelREWYADF1+XZWrAcbFLQCOqoE92ZwYgaP/RLumkUTaamEzdT2YKRZAH8eLLKGWotU/7FNPw==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-normalize-timing-functions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.0.0.tgz", + "integrity": "sha512-TwPaDX+wl9wO3MUm23lzGmOzGCGKnpk+rSDgzB2INpakD5dgWR3L6bJq1P1LQYzBAvz8fRIj2NWdnZdV4EV98Q==", + "dev": true, + "requires": { + "cssnano-utils": "^2.0.0", + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-normalize-unicode": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.0.0.tgz", + "integrity": "sha512-2CpVoz/67rXU5s9tsPZDxG1YGS9OFHwoY9gsLAzrURrCxTAb0H7Vp87/62LvVPgRWTa5ZmvgmqTp2rL8tlm72A==", + "dev": true, + "requires": { + "browserslist": "^4.16.0", + "postcss-value-parser": "^4.1.0" + }, + "dependencies": { + "browserslist": { + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" + } + }, + "caniuse-lite": { + "version": "1.0.30001228", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz", + "integrity": "sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A==", + "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 + }, + "electron-to-chromium": { + "version": "1.3.732", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.732.tgz", + "integrity": "sha512-qKD5Pbq+QMk4nea4lMuncUMhpEiQwaJyCW7MrvissnRcBDENhVfDmAqQYRQ3X525oTzhar9Zh1cK0L2d1UKYcw==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "node-releases": { + "version": "1.1.72", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", + "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", + "dev": true + } + } + }, + "postcss-normalize-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.0.0.tgz", + "integrity": "sha512-ICDaGFBqLgA3dlrCIRuhblLl80D13YtgEV9NJPTYJtgR72vu61KgxAHv+z/lKMs1EbwfSQa3ALjOFLSmXiE34A==", + "dev": true, + "requires": { + "is-absolute-url": "^3.0.3", + "normalize-url": "^4.5.0", + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-normalize-whitespace": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.0.0.tgz", + "integrity": "sha512-KRnxQvQAVkJfaeXSz7JlnD9nBN9sFZF9lrk9452Q2uRoqrRSkinqifF8Iex7wZGei2DZVG/qpmDFDmRvbNAOGA==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-ordered-values": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.0.0.tgz", + "integrity": "sha512-dPr+SRObiHueCIc4IUaG0aOGQmYkuNu50wQvdXTGKy+rzi2mjmPsbeDsheLk5WPb9Zyf2tp8E+I+h40cnivm6g==", + "dev": true, + "requires": { + "cssnano-utils": "^2.0.0", + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-reduce-initial": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.0.0.tgz", + "integrity": "sha512-wR6pXUaFbSMG1oCKx8pKVA+rnSXCHlca5jMrlmkmif+uig0HNUTV9oGN5kjKsM3mATQAldv2PF9Tbl2vqLFjnA==", + "dev": true, + "requires": { + "browserslist": "^4.16.0", + "caniuse-api": "^3.0.0" + }, + "dependencies": { + "browserslist": { + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" + } + }, + "caniuse-lite": { + "version": "1.0.30001228", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz", + "integrity": "sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A==", + "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 + }, + "electron-to-chromium": { + "version": "1.3.732", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.732.tgz", + "integrity": "sha512-qKD5Pbq+QMk4nea4lMuncUMhpEiQwaJyCW7MrvissnRcBDENhVfDmAqQYRQ3X525oTzhar9Zh1cK0L2d1UKYcw==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "node-releases": { + "version": "1.1.72", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", + "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", + "dev": true + } + } + }, + "postcss-reduce-transforms": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.0.0.tgz", + "integrity": "sha512-iHdGODW4YzM3WjVecBhPQt6fpJC4lGQZxJKjkBNHpp2b8dzmvj0ogKThqya+IRodQEFzjfXgYeESkf172FH5Lw==", + "dev": true, + "requires": { + "cssnano-utils": "^2.0.0", + "postcss-value-parser": "^4.1.0" + } + }, "postcss-selector-parser": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz", @@ -5549,6 +6390,27 @@ "uniq": "^1.0.1" } }, + "postcss-svgo": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.0.0.tgz", + "integrity": "sha512-M3/VS4sFI1Yp9g0bPL+xzzCNz5iLdRUztoFaugMit5a8sMfkVzzhwqbsOlD8IFFymCdJDmXmh31waYHWw1K4BA==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.1.0", + "svgo": "^2.3.0" + } + }, + "postcss-unique-selectors": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.0.0.tgz", + "integrity": "sha512-o9l4pF8SRn7aCMTmzb/kNv/kjV7wPZpZ8Nlb1Gq8v/Qvw969K1wanz1RVA0ehHzWe9+wHXaC2DvZlak/gdMJ5w==", + "dev": true, + "requires": { + "alphanum-sort": "^1.0.2", + "postcss-selector-parser": "^6.0.2", + "uniqs": "^2.0.0" + } + }, "postcss-value-parser": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", @@ -6139,6 +7001,18 @@ "integrity": "sha1-mUWygD8hni96ygCtuLyfZA+ELJo=", "dev": true }, + "rgb-regex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", + "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=", + "dev": true + }, + "rgba-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", + "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=", + "dev": true + }, "rimraf": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", @@ -6420,6 +7294,23 @@ "debug": "^4.1.1" } }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "dev": true, + "requires": { + "is-arrayish": "^0.3.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "dev": true + } + } + }, "sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -6534,6 +7425,12 @@ "tweetnacl": "~0.14.0" } }, + "stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "dev": true + }, "stdout-stream": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz", @@ -6673,6 +7570,71 @@ "get-stdin": "^4.0.1" } }, + "stylehacks": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.0.0.tgz", + "integrity": "sha512-QOWm6XivDLb+fqffTZP8jrmPmPITVChl2KCY2R05nsCWwLi3VGhCdVc3IVGNwd1zzTt1jPd67zIKjpQfxzQZeA==", + "dev": true, + "requires": { + "browserslist": "^4.16.0", + "postcss-selector-parser": "^6.0.4" + }, + "dependencies": { + "browserslist": { + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" + } + }, + "caniuse-lite": { + "version": "1.0.30001228", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz", + "integrity": "sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A==", + "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 + }, + "electron-to-chromium": { + "version": "1.3.732", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.732.tgz", + "integrity": "sha512-qKD5Pbq+QMk4nea4lMuncUMhpEiQwaJyCW7MrvissnRcBDENhVfDmAqQYRQ3X525oTzhar9Zh1cK0L2d1UKYcw==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "node-releases": { + "version": "1.1.72", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", + "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", + "dev": true + }, + "postcss-selector-parser": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz", + "integrity": "sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + } + } + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -6682,6 +7644,143 @@ "has-flag": "^3.0.0" } }, + "svgo": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.3.0.tgz", + "integrity": "sha512-fz4IKjNO6HDPgIQxu4IxwtubtbSfGEAJUq/IXyTPIkGhWck/faiiwfkvsB8LnBkKLvSoyNNIY6d13lZprJMc9Q==", + "dev": true, + "requires": { + "@trysound/sax": "0.1.1", + "chalk": "^4.1.0", + "commander": "^7.1.0", + "css-select": "^3.1.2", + "css-tree": "^1.1.2", + "csso": "^4.2.0", + "stable": "^0.1.8" + }, + "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.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "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 + }, + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true + }, + "css-select": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-3.1.2.tgz", + "integrity": "sha512-qmss1EihSuBNWNNhHjxzxSfJoFBM/lERB/Q4EnsJQQC62R2evJDW481091oAdOr9uh46/0n4nrg0It5cAnj1RA==", + "dev": true, + "requires": { + "boolbase": "^1.0.0", + "css-what": "^4.0.0", + "domhandler": "^4.0.0", + "domutils": "^2.4.3", + "nth-check": "^2.0.0" + } + }, + "css-what": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-4.0.0.tgz", + "integrity": "sha512-teijzG7kwYfNVsUh2H/YN62xW3KK9YhXEgSlbxMlcyjPNvdKJqFx5lrwlJgoFP1ZHlB89iGDlo/JyshKeRhv5A==", + "dev": true + }, + "dom-serializer": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", + "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + } + }, + "domelementtype": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", + "dev": true + }, + "domhandler": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.0.tgz", + "integrity": "sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA==", + "dev": true, + "requires": { + "domelementtype": "^2.2.0" + } + }, + "domutils": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.6.0.tgz", + "integrity": "sha512-y0BezHuy4MDYxh6OvolXYsH+1EMGmFbwv5FKW7ovwMG6zTPWqNPq3WF9ayZssFq+UlKdffGLbOEaghNdaOm1WA==", + "dev": true, + "requires": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.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 + }, + "nth-check": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.0.tgz", + "integrity": "sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q==", + "dev": true, + "requires": { + "boolbase": "^1.0.0" + } + }, + "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" + } + } + } + }, "symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -6833,6 +7932,12 @@ } } }, + "timsort": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", + "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", + "dev": true + }, "tiny-lr": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-1.1.1.tgz", @@ -7102,6 +8207,12 @@ "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", "dev": true }, + "uniqs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", + "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", + "dev": true + }, "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -7203,6 +8314,12 @@ "spdx-expression-parse": "^3.0.0" } }, + "vendors": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz", + "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==", + "dev": true + }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", @@ -7791,6 +8908,12 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true + }, "yargs": { "version": "17.0.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.0.1.tgz", diff --git a/static/package.json b/static/package.json index 073c8d35e..079295083 100644 --- a/static/package.json +++ b/static/package.json @@ -21,6 +21,7 @@ "babel-loader": "^8.1.0", "comment-json": "^3.0.2", "css-loader": "^3.4.2", + "cssnano": "^5.0.2", "file-loader": "^5.1.0", "file-system": "^2.2.2", "fs-extra": "^9.0.1", @@ -34,6 +35,7 @@ "mini-css-extract-plugin": "^1.6.0", "node-sass": "^4.13.1", "postcss": "^8.2.10", + "postcss-loader": "^5.3.0", "resolve-url-loader": "^3.1.1", "sass-loader": "^8.0.2", "simple-git": "^2.15.0", diff --git a/static/webpack-config.js b/static/webpack-config.js index 2b429483f..b82742d85 100644 --- a/static/webpack-config.js +++ b/static/webpack-config.js @@ -5,6 +5,7 @@ const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const HtmlPlugin = require('html-webpack-plugin'); const RemovePlugin = require('remove-files-webpack-plugin'); const { merge } = require('webpack-merge'); +const cssnano = require('cssnano'); module.exports = function () { const jamboConfig = require('./jambo.json'); @@ -91,6 +92,16 @@ module.exports = function () { use: [ MiniCssExtractPlugin.loader, 'css-loader', + { + loader: 'postcss-loader', + options: { + postcssOptions: { + plugins: [ + cssnano({ preset: 'default'}) + ], + }, + }, + }, 'resolve-url-loader', { loader: 'sass-loader', From dab722ef0b023e48e62547699b6255b8441d6bb3 Mon Sep 17 00:00:00 2001 From: Oliver Shi Date: Mon, 24 May 2021 10:46:03 -0400 Subject: [PATCH 12/56] run on-document-load js partial through #babel helper (#789) The exit disclaimer code instructions tell people to put their code in the on-document-load partial. We want this partial to work in ie11 even if people use newer features. J=SLAP-1131 TEST=manual see that I can specify an arrow func in on-doc-load and it gets transpiled --- layouts/html.hbs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/layouts/html.hbs b/layouts/html.hbs index d41854428..a41eddd06 100644 --- a/layouts/html.hbs +++ b/layouts/html.hbs @@ -78,9 +78,11 @@ href="{{#unless (isNonRelativeUrl global_config.favicon)}}{{relativePath}}/{{/unless}}{{global_config.favicon}}" /> {{/if}} {{#if global_config.googleAnalyticsId}} From d489b9d97e9d87df004fcdae901a62996f4ac4b2 Mon Sep 17 00:00:00 2001 From: Tom Meyer Date: Mon, 24 May 2021 15:06:33 -0400 Subject: [PATCH 13/56] Allow any SDK branch to be specified in `global_config.sdkVersion`. (#791) This PR allows any SDK branch, not just official releases, to be specified in `global_config.sdkVersion`. To support this, a new HBS helper was added to the Theme: `sdkAssetUrl`. This helper takes in the branch (or release version), locale, and asset name, and provides the correct URL for it. With the addition of this helper, we were able to remove the `sdk-url` partial. The logic for computing the URL is now sufficiently complicated that we should do it in JS instead of HBS. J=SLAP-924 TEST=auto, manual Added unit tests for the new helper. For the following scenarios, I tested with both an English and French locale, and verified the correct asset URLs were provided: - Released SDK version. - Release branch of the SDK. - Feature branch of the SDK. - Dev branch of the SDK. --- hbshelpers/sdkAssetUrl.js | 35 ++++++++++ layouts/html.hbs | 2 +- script/core.hbs | 2 +- script/partials/sdk-js-script-tags.hbs | 4 +- script/partials/sdk-url.hbs | 15 ----- tests/hbshelpers/sdkAssetUrl.js | 73 +++++++++++++++++++++ tests/script/partials/sdk-js-script-tags.js | 5 -- tests/script/partials/sdk-url.js | 22 ------- 8 files changed, 112 insertions(+), 46 deletions(-) create mode 100644 hbshelpers/sdkAssetUrl.js delete mode 100644 script/partials/sdk-url.hbs create mode 100644 tests/hbshelpers/sdkAssetUrl.js delete mode 100644 tests/script/partials/sdk-url.js diff --git a/hbshelpers/sdkAssetUrl.js b/hbshelpers/sdkAssetUrl.js new file mode 100644 index 000000000..453a791c5 --- /dev/null +++ b/hbshelpers/sdkAssetUrl.js @@ -0,0 +1,35 @@ +const RELEASE_BRANCH_REGEX = /^release\/v[0-9.]+$/; +const HOTFIX_BRANCH_REGEX = /^hotfix\/v[0-9.]+$/; +const SEM_VER_REGEX = /^[1-9]+$|^[1-9]+\.[0-9]+$|^[1-9]+\.[0-9]+\.[0-9]+$/; + +/** + * Given a branch (or release) of the SDK and a locale, this helper provides the correct + * URL in the CDN for the asset. + * + * @param {string} branch The branch (or release) of the SDK. + * @param {string} locale The locale to use. + * @param {string} assetName The name of the desired asset. + * @returns {string} The CDN URL of the localized asset. + */ +module.exports = function sdkAssetUrl(branch, locale, assetName) { + const isReleasedBranch = SEM_VER_REGEX.test(branch); + + let parsedBranch; + if (isReleasedBranch) { + parsedBranch = `v${branch}`; + } else { + parsedBranch = `dev/${branch.replace(/\//g, '-')}`; + } + + const isPreReleaseBranch = + RELEASE_BRANCH_REGEX.test(branch) || HOTFIX_BRANCH_REGEX.test(branch); + const isLocalizationSupported = + (isReleasedBranch || isPreReleaseBranch) && + !(locale.startsWith('en') || assetName === 'answers.css') ; + + const parsedAssetName = isLocalizationSupported ? + `${locale}-${assetName}` : + assetName; + + return `https://assets.sitescdn.net/answers/${parsedBranch}/${parsedAssetName}`; +}; diff --git a/layouts/html.hbs b/layouts/html.hbs index a41eddd06..b0f1786f4 100644 --- a/layouts/html.hbs +++ b/layouts/html.hbs @@ -139,7 +139,7 @@ {{/babel}} - + diff --git a/script/core.hbs b/script/core.hbs index f8b28dbd6..80b6ed22b 100644 --- a/script/core.hbs +++ b/script/core.hbs @@ -4,7 +4,7 @@ console.error('ERROR: no sdkVersion specified, please specify an sdkVersion in the global_config.'); } - + `; -it('creates correct tags when no locale specified', () => { - const partialUsage = '{{> script/partials/sdk-js-script-tags sdkVersion=1.8}}' - expect(hbs.compile(partialUsage)()).toEqual(defaultOutput); -}); - it('creates correct tags for en', () => { const partialUsage = `{{> script/partials/sdk-js-script-tags sdkVersion=1.8 diff --git a/tests/script/partials/sdk-url.js b/tests/script/partials/sdk-url.js deleted file mode 100644 index 40dd26eea..000000000 --- a/tests/script/partials/sdk-url.js +++ /dev/null @@ -1,22 +0,0 @@ -const hbs = require('../../test-utils/hbs'); - -it('creates an sdk asset url correctly', () => { - const partialUsage = - '{{> script/partials/sdk-url sdkVersion=1.8 sdkAsset="answers.js" locale="it"}}'; - const expectedOutput = 'https://assets.sitescdn.net/answers/v1.8/it-answers.js'; - expect(hbs.compile(partialUsage)()).toEqual(expectedOutput); -}); - -it('does not include a locale prefix when no locale specified', () => { - const partialUsage = '{{> script/partials/sdk-url sdkVersion=1.8 sdkAsset="answers.js"}}'; - const expectedOutput = 'https://assets.sitescdn.net/answers/v1.8/answers.js'; - expect(hbs.compile(partialUsage)()).toEqual(expectedOutput); -}); - -it('does not include a locale prefix when locale is set to "en"', () => { - const partialUsage = - '{{> script/partials/sdk-url sdkVersion=1.8 sdkAsset="answers.js" locale="en"}}'; - const expectedOutput = 'https://assets.sitescdn.net/answers/v1.8/answers.js'; - expect(hbs.compile(partialUsage)()).toEqual(expectedOutput); -}); - From 93b70ee18cdbb0e64537fe86781708d935a6feb6 Mon Sep 17 00:00:00 2001 From: Yen Truong <36055303+yen-tt@users.noreply.github.com> Date: Wed, 26 May 2021 09:01:40 -0400 Subject: [PATCH 14/56] Swap node-sass to dart-sass (#792) Update package.json to use sass packae and remove node-sass in static folder sass-loader will resolve the implementation based on depedencies and use sass package J=SLAP-1310 TEST=compile Co-authored-by: Yen Truong --- static/package-lock.json | 2203 +++----------------------------------- static/package.json | 2 +- 2 files changed, 135 insertions(+), 2070 deletions(-) diff --git a/static/package-lock.json b/static/package-lock.json index e89a2e567..0d767fbaa 100644 --- a/static/package-lock.json +++ b/static/package-lock.json @@ -1049,12 +1049,6 @@ "resolved": "https://registry.npmjs.org/@stroncium/procfs/-/procfs-1.2.1.tgz", "integrity": "sha512-X1Iui3FUNZP18EUvysTHxt+Avu2nlVzyf90YM8OYgP6SGzTzzX/0JgObfO1AQQDzuZtNNz29bVh8h5R97JrjxA==" }, - "@trysound/sax": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.1.1.tgz", - "integrity": "sha512-Z6DoceYb/1xSg5+e+ZlPZ9v0N16ZvZ+wYMraFue4HYrE4ttONKtsvruIRf6t9TBR0YvSOfi1hUU0fJfBLCDYow==", - "dev": true - }, "@types/anymatch": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", @@ -1119,12 +1113,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.14.tgz", "integrity": "sha512-syUgf67ZQpaJj01/tRTknkMNoBBLWJOBODF0Zm4NrXmiSuxjymFrxnTu1QVYRubhVkRcZLYZG8STTwJRdVm/WQ==" }, - "@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", - "dev": true - }, "@types/parse5": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-5.0.3.tgz", @@ -1526,18 +1514,6 @@ "integrity": "sha512-eyoaac3btgU8eJlvh01En8OCKzRqlLe2G5jDsCr3RiE2uLGMEEB1aaGwVVpwR8M95956tGH6R+9edC++OvzaVw==", "dev": true }, - "alphanum-sort": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", - "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", - "dev": true - }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", - "dev": true - }, "ansi-colors": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", @@ -1559,46 +1535,14 @@ "color-convert": "^1.9.0" } }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" } }, "argparse": { @@ -1636,12 +1580,6 @@ "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", "dev": true }, - "array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", - "dev": true - }, "array-slice": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", @@ -1697,12 +1635,6 @@ "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==", "dev": true }, - "async-foreach": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", - "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=", - "dev": true - }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -1769,14 +1701,11 @@ "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", "dev": true }, - "block-stream": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", - "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", - "dev": true, - "requires": { - "inherits": "~2.0.0" - } + "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 }, "body": { "version": "5.1.0", @@ -1849,12 +1778,6 @@ "integrity": "sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=", "dev": true }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, "camel-case": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.1.tgz", @@ -1871,36 +1794,6 @@ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, - "camelcase-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", - "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", - "dev": true, - "requires": { - "camelcase": "^2.0.0", - "map-obj": "^1.0.0" - }, - "dependencies": { - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "dev": true - } - } - }, - "caniuse-api": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", - "dev": true, - "requires": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } - }, "caniuse-lite": { "version": "1.0.30001164", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001164.tgz", @@ -1924,6 +1817,22 @@ "supports-color": "^5.3.0" } }, + "chokidar": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.3.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + } + }, "chrome-trace-event": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", @@ -1994,22 +1903,6 @@ "shallow-clone": "^3.0.0" } }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "color": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/color/-/color-3.1.3.tgz", - "integrity": "sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ==", - "dev": true, - "requires": { - "color-convert": "^1.9.1", - "color-string": "^1.5.4" - } - }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -2025,16 +1918,6 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, - "color-string": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.5.tgz", - "integrity": "sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg==", - "dev": true, - "requires": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, "colorette": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz", @@ -2105,12 +1988,6 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true - }, "content-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", @@ -2166,39 +2043,6 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, - "cosmiconfig": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", - "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", - "dev": true, - "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - }, - "dependencies": { - "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-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - } - } - }, "cp-file": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-6.2.0.tgz", @@ -2211,16 +2055,6 @@ "safe-buffer": "^5.0.1" } }, - "cross-spawn": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", - "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "which": "^1.2.9" - } - }, "cross-spawn-async": { "version": "2.2.5", "resolved": "https://registry.npmjs.org/cross-spawn-async/-/cross-spawn-async-2.2.5.tgz", @@ -2250,21 +2084,6 @@ } } }, - "css-color-names": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-1.0.1.tgz", - "integrity": "sha512-/loXYOch1qU1biStIFsHH8SxTmOseh1IJqFvy8IujXOm1h+QjUdDhkzOrR5HG8K8mlxREj0yfi8ewCHx0eMxzA==", - "dev": true - }, - "css-declaration-sorter": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.0.0.tgz", - "integrity": "sha512-S0TE4E0ha5+tBHdLWPc5n+S8E4dFBS5xScPvgHkLNZwWvX4ISoFGhGeerLC9uS1cKA/sC+K2wHq6qEbcagT/fg==", - "dev": true, - "requires": { - "timsort": "^0.3.0" - } - }, "css-loader": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.6.0.tgz", @@ -2356,24 +2175,6 @@ "integrity": "sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g==", "dev": true }, - "css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "dev": true, - "requires": { - "mdn-data": "2.0.14", - "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 - } - } - }, "css-vars-ponyfill": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/css-vars-ponyfill/-/css-vars-ponyfill-2.4.2.tgz", @@ -2391,69 +2192,6 @@ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "dev": true }, - "cssnano": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.0.2.tgz", - "integrity": "sha512-8JK3EnPsjQsULme9/e5M2hF564f/480hwsdcHvQ7ZtAIMfQ1O3SCfs+b8Mjf5KJxhYApyRshR2QSovEJi2K72Q==", - "dev": true, - "requires": { - "cosmiconfig": "^7.0.0", - "cssnano-preset-default": "^5.0.1", - "is-resolvable": "^1.1.0" - } - }, - "cssnano-preset-default": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.0.1.tgz", - "integrity": "sha512-cfmfThYODGqhpQKDq9H0MTAqkMvZ3dGbOUTBKw0xWZiIycMqHid22LsJXJl4r1qX4qzDeKxcSyQ/Xb5Mu3Z//Q==", - "dev": true, - "requires": { - "css-declaration-sorter": "6.0.0", - "cssnano-utils": "^2.0.0", - "postcss-calc": "^8.0.0", - "postcss-colormin": "^5.0.0", - "postcss-convert-values": "^5.0.0", - "postcss-discard-comments": "^5.0.0", - "postcss-discard-duplicates": "^5.0.0", - "postcss-discard-empty": "^5.0.0", - "postcss-discard-overridden": "^5.0.0", - "postcss-merge-longhand": "^5.0.1", - "postcss-merge-rules": "^5.0.0", - "postcss-minify-font-values": "^5.0.0", - "postcss-minify-gradients": "^5.0.0", - "postcss-minify-params": "^5.0.0", - "postcss-minify-selectors": "^5.0.0", - "postcss-normalize-charset": "^5.0.0", - "postcss-normalize-display-values": "^5.0.0", - "postcss-normalize-positions": "^5.0.0", - "postcss-normalize-repeat-style": "^5.0.0", - "postcss-normalize-string": "^5.0.0", - "postcss-normalize-timing-functions": "^5.0.0", - "postcss-normalize-unicode": "^5.0.0", - "postcss-normalize-url": "^5.0.0", - "postcss-normalize-whitespace": "^5.0.0", - "postcss-ordered-values": "^5.0.0", - "postcss-reduce-initial": "^5.0.0", - "postcss-reduce-transforms": "^5.0.0", - "postcss-svgo": "^5.0.0", - "postcss-unique-selectors": "^5.0.0" - } - }, - "cssnano-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-2.0.0.tgz", - "integrity": "sha512-xvxmTszdrvSyTACdPe8VU5J6p4sm3egpgw54dILvNqt5eBUv6TFjACLhSxtRuEsxYrgy8uDy269YjScO5aKbGA==", - "dev": true - }, - "csso": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", - "dev": true, - "requires": { - "css-tree": "^1.1.2" - } - }, "cssom": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", @@ -2477,15 +2215,6 @@ } } }, - "currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", - "dev": true, - "requires": { - "array-find-index": "^1.0.1" - } - }, "d": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", @@ -2531,12 +2260,6 @@ "ms": "^2.1.1" } }, - "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", @@ -2585,12 +2308,6 @@ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", "dev": true }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true - }, "detect-file": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", @@ -2692,15 +2409,6 @@ "tslib": "^1.10.0" } }, - "dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "dev": true, - "requires": { - "is-obj": "^2.0.0" - } - }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -2806,15 +2514,6 @@ "string-template": "~0.2.1" } }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, "es-abstract": { "version": "1.17.6", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", @@ -3224,17 +2923,12 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, - "fstream": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", - "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" - } + "optional": true }, "function-bind": { "version": "1.1.1", @@ -3242,44 +2936,6 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dev": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } - } - }, "gaze": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", @@ -3301,12 +2957,6 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", - "dev": true - }, "get-stream": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", @@ -3775,15 +3425,6 @@ "function-bind": "^1.1.1" } }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -3801,24 +3442,12 @@ "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", "dev": true }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true - }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, - "hex-color-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", - "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==", - "dev": true - }, "homedir-polyfill": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", @@ -3834,24 +3463,6 @@ "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=", "dev": true }, - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "hsl-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", - "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=", - "dev": true - }, - "hsla-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", - "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=", - "dev": true - }, "html-encoding-sniffer": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", @@ -4107,24 +3718,6 @@ "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==" }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "dependencies": { - "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 - } - } - }, "import-local": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", @@ -4180,21 +3773,6 @@ } } }, - "in-publish": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.1.tgz", - "integrity": "sha512-oDM0kUSNFC31ShNxHKUyfZKy8ZeXZBWMjMdZHKLOk13uvT27VTL/QzRGfRUcevJhpkZAvlhPYuXkF7eNWrtyxQ==", - "dev": true - }, - "indent-string": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, "indexes-of": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", @@ -4252,17 +3830,14 @@ "is-windows": "^1.0.1" } }, - "is-absolute-url": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", - "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", - "dev": true - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } }, "is-callable": { "version": "1.2.0", @@ -4270,28 +3845,6 @@ "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", "dev": true }, - "is-color-stop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", - "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=", - "dev": true, - "requires": { - "css-color-names": "^0.0.4", - "hex-color-regex": "^1.1.0", - "hsl-regex": "^1.0.0", - "hsla-regex": "^1.0.0", - "rgb-regex": "^1.0.1", - "rgba-regex": "^1.0.0" - }, - "dependencies": { - "css-color-names": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", - "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", - "dev": true - } - } - }, "is-core-module": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", @@ -4313,12 +3866,6 @@ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, - "is-finite": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", - "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", - "dev": true - }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -4345,12 +3892,6 @@ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, - "is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true - }, "is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", @@ -4389,12 +3930,6 @@ "is-unc-path": "^1.0.0" } }, - "is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", - "dev": true - }, "is-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", @@ -4425,24 +3960,12 @@ "unc-path-regex": "^0.1.2" } }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true - }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -4523,12 +4046,6 @@ } } }, - "js-base64": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.2.tgz", - "integrity": "sha512-1hgLrLIrmCgZG+ID3VoLNLOSwjGnoZa8tyrUdEteMeIzsT6PH7PMLyUvbDwzNE56P3PNxyvuIOx4Uh2E5rzQIw==", - "dev": true - }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -4616,12 +4133,6 @@ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "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", @@ -4681,12 +4192,6 @@ "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true }, - "klona": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.4.tgz", - "integrity": "sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA==", - "dev": true - }, "leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -4761,39 +4266,12 @@ } } }, - "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 - }, "livereload-js": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.4.0.tgz", "integrity": "sha512-XPQH8Z2GDP/Hwz2PCDrh2mth4yFejwA1OZ/81Ti3LgKyhDcEjsSsqFWZojHG0va/duGd+WyosY7eXLDoOyqcPw==", "dev": true }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, "loader-runner": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.1.0.tgz", @@ -4855,24 +4333,12 @@ "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", "dev": true }, - "lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", - "dev": true - }, "lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", "dev": true }, - "lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", - "dev": true - }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -4882,16 +4348,6 @@ "js-tokens": "^3.0.0 || ^4.0.0" } }, - "loud-rejection": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", - "dev": true, - "requires": { - "currently-unhandled": "^0.4.1", - "signal-exit": "^3.0.0" - } - }, "lower-case": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.1.tgz", @@ -4934,36 +4390,6 @@ "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", "dev": true }, - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true - }, - "mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", - "dev": true - }, - "meow": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", - "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", - "dev": true, - "requires": { - "camelcase-keys": "^2.0.0", - "decamelize": "^1.1.2", - "loud-rejection": "^1.0.0", - "map-obj": "^1.0.1", - "minimist": "^1.1.3", - "normalize-package-data": "^2.3.4", - "object-assign": "^4.0.1", - "read-pkg-up": "^1.0.1", - "redent": "^1.0.0", - "trim-newlines": "^1.0.0" - } - }, "merge-options": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-2.0.0.tgz", @@ -5149,12 +4575,6 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", - "dev": true - }, "nanoid": { "version": "3.1.23", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz", @@ -5197,92 +4617,12 @@ "lodash.get": "^4.4.2" } }, - "node-gyp": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz", - "integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==", - "dev": true, - "requires": { - "fstream": "^1.0.0", - "glob": "^7.0.3", - "graceful-fs": "^4.1.2", - "mkdirp": "^0.5.0", - "nopt": "2 || 3", - "npmlog": "0 || 1 || 2 || 3 || 4", - "osenv": "0", - "request": "^2.87.0", - "rimraf": "2", - "semver": "~5.3.0", - "tar": "^2.0.0", - "which": "1" - }, - "dependencies": { - "semver": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", - "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", - "dev": true - } - } - }, "node-releases": { "version": "1.1.58", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.58.tgz", "integrity": "sha512-NxBudgVKiRh/2aPWMgPR7bPTX0VPmGx5QBwCtdHitnqFE5/O8DeBXuIMH1nwNnw/aMo6AjOrpsHzfY3UbUJ7yg==", "dev": true }, - "node-sass": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.14.1.tgz", - "integrity": "sha512-sjCuOlvGyCJS40R8BscF5vhVlQjNN069NtQ1gSxyK1u9iqvn6tf7O1R4GNowVZfiZUCRt5MmMs1xd+4V/7Yr0g==", - "dev": true, - "requires": { - "async-foreach": "^0.1.3", - "chalk": "^1.1.1", - "cross-spawn": "^3.0.0", - "gaze": "^1.0.0", - "get-stdin": "^4.0.1", - "glob": "^7.0.3", - "in-publish": "^2.0.0", - "lodash": "^4.17.15", - "meow": "^3.7.0", - "mkdirp": "^0.5.1", - "nan": "^2.13.2", - "node-gyp": "^3.8.0", - "npmlog": "^4.0.0", - "request": "^2.88.0", - "sass-graph": "2.2.5", - "stdout-stream": "^1.4.0", - "true-case-path": "^1.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, "nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", @@ -5292,30 +4632,12 @@ "abbrev": "1" } }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, - "normalize-url": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", - "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", - "dev": true - }, "npm-run-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-1.0.0.tgz", @@ -5324,18 +4646,6 @@ "path-key": "^1.0.0" } }, - "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dev": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, "nth-check": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", @@ -5345,12 +4655,6 @@ "boolbase": "~1.0.0" } }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, "nwsapi": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", @@ -5524,15 +4828,6 @@ "tslib": "^1.10.0" } }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, "parse-filepath": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", @@ -5544,15 +4839,6 @@ "path-root": "^0.1.1" } }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, "parse-passwd": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", @@ -5617,25 +4903,6 @@ "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", "dev": true }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -5706,441 +4973,125 @@ } } }, - "postcss-calc": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.0.0.tgz", - "integrity": "sha512-5NglwDrcbiy8XXfPM11F3HeC6hoT9W7GUH/Zi5U/p7u3Irv4rHhdDcIZwG0llHXV4ftsBjpfWMXAnXNl4lnt8g==", - "dev": true, - "requires": { - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.0.2" - } - }, - "postcss-colormin": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.0.0.tgz", - "integrity": "sha512-Yt84+5V6CgS/AhK7d7MA58vG8dSZ7+ytlRtWLaQhag3HXOncTfmYpuUOX4cDoXjvLfw1sHRCHMiBjYhc35CymQ==", + "postcss-modules-extract-imports": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", + "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", "dev": true, "requires": { - "browserslist": "^4.16.0", - "color": "^3.1.1", - "postcss-value-parser": "^4.1.0" + "postcss": "^7.0.5" }, "dependencies": { - "browserslist": { - "version": "4.16.6", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", - "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "postcss": { + "version": "7.0.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", + "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001219", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.723", - "escalade": "^3.1.1", - "node-releases": "^1.1.71" + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" } }, - "caniuse-lite": { - "version": "1.0.30001228", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz", - "integrity": "sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A==", - "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 - }, - "electron-to-chromium": { - "version": "1.3.732", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.732.tgz", - "integrity": "sha512-qKD5Pbq+QMk4nea4lMuncUMhpEiQwaJyCW7MrvissnRcBDENhVfDmAqQYRQ3X525oTzhar9Zh1cK0L2d1UKYcw==", - "dev": true - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "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 }, - "node-releases": { - "version": "1.1.72", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", - "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", - "dev": true + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } } } }, - "postcss-convert-values": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.0.0.tgz", - "integrity": "sha512-V5kmYm4xoBAjNs+eHY/6XzXJkkGeg4kwNf2ocfqhLb1WBPEa4oaSmoi1fnVO7Dkblqvus9h+AenDvhCKUCK7uQ==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-discard-comments": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.0.0.tgz", - "integrity": "sha512-Umig6Gxs8m20RihiXY6QkePd6mp4FxkA1Dg+f/Kd6uw0gEMfKRjDeQOyFkLibexbJJGHpE3lrN/Q0R9SMrUMbQ==", - "dev": true - }, - "postcss-discard-duplicates": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.0.0.tgz", - "integrity": "sha512-vEJJ+Y3pFUnO1FyCBA6PSisGjHtnphL3V6GsNvkASq/VkP3OX5/No5RYXXLxHa2QegStNzg6HYrYdo71uR4caQ==", - "dev": true - }, - "postcss-discard-empty": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.0.0.tgz", - "integrity": "sha512-+wigy099Y1xZxG36WG5L1f2zeH1oicntkJEW4TDIqKKDO2g9XVB3OhoiHTu08rDEjLnbcab4rw0BAccwi2VjiQ==", - "dev": true - }, - "postcss-discard-overridden": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.0.0.tgz", - "integrity": "sha512-hybnScTaZM2iEA6kzVQ6Spozy7kVdLw+lGw8hftLlBEzt93uzXoltkYp9u0tI8xbfhxDLTOOzHsHQCkYdmzRUg==", - "dev": true - }, - "postcss-loader": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-5.3.0.tgz", - "integrity": "sha512-/+Z1RAmssdiSLgIZwnJHwBMnlABPgF7giYzTN2NOfr9D21IJZ4mQC1R2miwp80zno9M4zMD/umGI8cR+2EL5zw==", + "postcss-modules-local-by-default": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.2.tgz", + "integrity": "sha512-jM/V8eqM4oJ/22j0gx4jrp63GSvDH6v86OqyTHHUvk4/k1vceipZsaymiZ5PvocqZOl5SFHiFJqjs3la0wnfIQ==", "dev": true, "requires": { - "cosmiconfig": "^7.0.0", - "klona": "^2.0.4", - "semver": "^7.3.4" + "icss-utils": "^4.1.1", + "postcss": "^7.0.16", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.0.0" }, "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "postcss": { + "version": "7.0.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", + "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", "dev": true, "requires": { - "yallist": "^4.0.0" + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" } }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "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 + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dev": true, "requires": { - "lru-cache": "^6.0.0" + "has-flag": "^3.0.0" } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true } } }, - "postcss-merge-longhand": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.0.1.tgz", - "integrity": "sha512-H1RO8le5deFGumQzuhJjuL0bIXPRysa+w7xtk5KrHe38oiaSS9ksPXDo24+IOS3SETPhip0J5+1uCOW+ALs3Yw==", - "dev": true, - "requires": { - "css-color-names": "^1.0.1", - "postcss-value-parser": "^4.1.0", - "stylehacks": "^5.0.0" - } - }, - "postcss-merge-rules": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.0.0.tgz", - "integrity": "sha512-TfsXbKjNYCGfUPEXGIGPySnMiJbdS+3gcVeV8gwmJP4RajyKZHW8E0FYDL1WmggTj3hi+m+WUCAvqRpX2ut4Kg==", + "postcss-modules-scope": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", + "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", "dev": true, "requires": { - "browserslist": "^4.16.0", - "caniuse-api": "^3.0.0", - "cssnano-utils": "^2.0.0", - "postcss-selector-parser": "^6.0.4", - "vendors": "^1.0.3" + "postcss": "^7.0.6", + "postcss-selector-parser": "^6.0.0" }, "dependencies": { - "browserslist": { - "version": "4.16.6", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", - "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "postcss": { + "version": "7.0.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", + "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001219", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.723", - "escalade": "^3.1.1", - "node-releases": "^1.1.71" + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" } }, - "caniuse-lite": { - "version": "1.0.30001228", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz", - "integrity": "sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A==", - "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 - }, - "electron-to-chromium": { - "version": "1.3.732", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.732.tgz", - "integrity": "sha512-qKD5Pbq+QMk4nea4lMuncUMhpEiQwaJyCW7MrvissnRcBDENhVfDmAqQYRQ3X525oTzhar9Zh1cK0L2d1UKYcw==", - "dev": true - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "node-releases": { - "version": "1.1.72", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", - "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", + "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 }, - "postcss-selector-parser": { - "version": "6.0.6", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz", - "integrity": "sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==", + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dev": true, "requires": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" + "has-flag": "^3.0.0" } } } }, - "postcss-minify-font-values": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.0.0.tgz", - "integrity": "sha512-zi2JhFaMOcIaNxhndX5uhsqSY1rexKDp23wV8EOmC9XERqzLbHsoRye3aYF716Zm+hkcR4loqKDt8LZlmihwAg==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-minify-gradients": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.0.0.tgz", - "integrity": "sha512-/jPtNgs6JySMwgsE5dPOq8a2xEopWTW3RyqoB9fLqxgR+mDUNLSi7joKd+N1z7FXWgVkc4l/dEBMXHgNAaUbvg==", - "dev": true, - "requires": { - "cssnano-utils": "^2.0.0", - "is-color-stop": "^1.1.0", - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-minify-params": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.0.0.tgz", - "integrity": "sha512-KvZYIxTPBVKjdd+XgObq9A+Sfv8lMkXTpbZTsjhr42XbfWIeLaTItMlygsDWfjArEc3muUfDaUFgNSeDiJ5jug==", - "dev": true, - "requires": { - "alphanum-sort": "^1.0.2", - "browserslist": "^4.16.0", - "cssnano-utils": "^2.0.0", - "postcss-value-parser": "^4.1.0", - "uniqs": "^2.0.0" - }, - "dependencies": { - "browserslist": { - "version": "4.16.6", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", - "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001219", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.723", - "escalade": "^3.1.1", - "node-releases": "^1.1.71" - } - }, - "caniuse-lite": { - "version": "1.0.30001228", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz", - "integrity": "sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A==", - "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 - }, - "electron-to-chromium": { - "version": "1.3.732", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.732.tgz", - "integrity": "sha512-qKD5Pbq+QMk4nea4lMuncUMhpEiQwaJyCW7MrvissnRcBDENhVfDmAqQYRQ3X525oTzhar9Zh1cK0L2d1UKYcw==", - "dev": true - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "node-releases": { - "version": "1.1.72", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", - "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", - "dev": true - } - } - }, - "postcss-minify-selectors": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.0.0.tgz", - "integrity": "sha512-cEM0O0eWwFIvmo6nfB0lH0vO/XFwgqIvymODbfPXZ1gTA3i76FKnb7TGUrEpiTxaXH6tgYQ6DcTHwRiRS+YQLQ==", - "dev": true, - "requires": { - "alphanum-sort": "^1.0.2", - "postcss-selector-parser": "^3.1.2" - }, - "dependencies": { - "postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "dev": true, - "requires": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } - } - }, - "postcss-modules-extract-imports": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", - "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", - "dev": true, - "requires": { - "postcss": "^7.0.5" - }, - "dependencies": { - "postcss": { - "version": "7.0.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", - "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", - "dev": true, - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "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 - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "postcss-modules-local-by-default": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.2.tgz", - "integrity": "sha512-jM/V8eqM4oJ/22j0gx4jrp63GSvDH6v86OqyTHHUvk4/k1vceipZsaymiZ5PvocqZOl5SFHiFJqjs3la0wnfIQ==", - "dev": true, - "requires": { - "icss-utils": "^4.1.1", - "postcss": "^7.0.16", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.0.0" - }, - "dependencies": { - "postcss": { - "version": "7.0.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", - "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", - "dev": true, - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "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 - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "postcss-modules-scope": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", - "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", - "dev": true, - "requires": { - "postcss": "^7.0.6", - "postcss-selector-parser": "^6.0.0" - }, - "dependencies": { - "postcss": { - "version": "7.0.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", - "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", - "dev": true, - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "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 - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "postcss-modules-values": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz", - "integrity": "sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==", + "postcss-modules-values": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz", + "integrity": "sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==", "dev": true, "requires": { "icss-utils": "^4.0.0", @@ -6175,210 +5126,6 @@ } } }, - "postcss-normalize-charset": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.0.0.tgz", - "integrity": "sha512-pqsCkgo9KmQP0ew6DqSA+uP9YN6EfsW20pQ3JU5JoQge09Z6Too4qU0TNDsTNWuEaP8SWsMp+19l15210MsDZQ==", - "dev": true - }, - "postcss-normalize-display-values": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.0.0.tgz", - "integrity": "sha512-t4f2d//gH1f7Ns0Jq3eNdnWuPT7TeLuISZ6RQx4j8gpl5XrhkdshdNcOnlrEK48YU6Tcb6jqK7dorME3N4oOGA==", - "dev": true, - "requires": { - "cssnano-utils": "^2.0.0", - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-normalize-positions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.0.0.tgz", - "integrity": "sha512-0o6/qU5ky74X/eWYj/tv4iiKCm3YqJnrhmVADpIMNXxzFZywsSQxl8F7cKs8jQEtF3VrJBgcDHTexZy1zgDoYg==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-normalize-repeat-style": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.0.0.tgz", - "integrity": "sha512-KRT14JbrXKcFMYuc4q7lh8lvv8u22wLyMrq+UpHKLtbx2H/LOjvWXYdoDxmNrrrJzomAWL+ViEXr48/IhSUJnQ==", - "dev": true, - "requires": { - "cssnano-utils": "^2.0.0", - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-normalize-string": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.0.0.tgz", - "integrity": "sha512-wSO4pf7GNcDZpmelREWYADF1+XZWrAcbFLQCOqoE92ZwYgaP/RLumkUTaamEzdT2YKRZAH8eLLKGWotU/7FNPw==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-normalize-timing-functions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.0.0.tgz", - "integrity": "sha512-TwPaDX+wl9wO3MUm23lzGmOzGCGKnpk+rSDgzB2INpakD5dgWR3L6bJq1P1LQYzBAvz8fRIj2NWdnZdV4EV98Q==", - "dev": true, - "requires": { - "cssnano-utils": "^2.0.0", - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-normalize-unicode": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.0.0.tgz", - "integrity": "sha512-2CpVoz/67rXU5s9tsPZDxG1YGS9OFHwoY9gsLAzrURrCxTAb0H7Vp87/62LvVPgRWTa5ZmvgmqTp2rL8tlm72A==", - "dev": true, - "requires": { - "browserslist": "^4.16.0", - "postcss-value-parser": "^4.1.0" - }, - "dependencies": { - "browserslist": { - "version": "4.16.6", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", - "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001219", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.723", - "escalade": "^3.1.1", - "node-releases": "^1.1.71" - } - }, - "caniuse-lite": { - "version": "1.0.30001228", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz", - "integrity": "sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A==", - "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 - }, - "electron-to-chromium": { - "version": "1.3.732", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.732.tgz", - "integrity": "sha512-qKD5Pbq+QMk4nea4lMuncUMhpEiQwaJyCW7MrvissnRcBDENhVfDmAqQYRQ3X525oTzhar9Zh1cK0L2d1UKYcw==", - "dev": true - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "node-releases": { - "version": "1.1.72", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", - "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", - "dev": true - } - } - }, - "postcss-normalize-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.0.0.tgz", - "integrity": "sha512-ICDaGFBqLgA3dlrCIRuhblLl80D13YtgEV9NJPTYJtgR72vu61KgxAHv+z/lKMs1EbwfSQa3ALjOFLSmXiE34A==", - "dev": true, - "requires": { - "is-absolute-url": "^3.0.3", - "normalize-url": "^4.5.0", - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-normalize-whitespace": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.0.0.tgz", - "integrity": "sha512-KRnxQvQAVkJfaeXSz7JlnD9nBN9sFZF9lrk9452Q2uRoqrRSkinqifF8Iex7wZGei2DZVG/qpmDFDmRvbNAOGA==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-ordered-values": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.0.0.tgz", - "integrity": "sha512-dPr+SRObiHueCIc4IUaG0aOGQmYkuNu50wQvdXTGKy+rzi2mjmPsbeDsheLk5WPb9Zyf2tp8E+I+h40cnivm6g==", - "dev": true, - "requires": { - "cssnano-utils": "^2.0.0", - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-reduce-initial": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.0.0.tgz", - "integrity": "sha512-wR6pXUaFbSMG1oCKx8pKVA+rnSXCHlca5jMrlmkmif+uig0HNUTV9oGN5kjKsM3mATQAldv2PF9Tbl2vqLFjnA==", - "dev": true, - "requires": { - "browserslist": "^4.16.0", - "caniuse-api": "^3.0.0" - }, - "dependencies": { - "browserslist": { - "version": "4.16.6", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", - "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001219", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.723", - "escalade": "^3.1.1", - "node-releases": "^1.1.71" - } - }, - "caniuse-lite": { - "version": "1.0.30001228", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz", - "integrity": "sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A==", - "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 - }, - "electron-to-chromium": { - "version": "1.3.732", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.732.tgz", - "integrity": "sha512-qKD5Pbq+QMk4nea4lMuncUMhpEiQwaJyCW7MrvissnRcBDENhVfDmAqQYRQ3X525oTzhar9Zh1cK0L2d1UKYcw==", - "dev": true - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "node-releases": { - "version": "1.1.72", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", - "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", - "dev": true - } - } - }, - "postcss-reduce-transforms": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.0.0.tgz", - "integrity": "sha512-iHdGODW4YzM3WjVecBhPQt6fpJC4lGQZxJKjkBNHpp2b8dzmvj0ogKThqya+IRodQEFzjfXgYeESkf172FH5Lw==", - "dev": true, - "requires": { - "cssnano-utils": "^2.0.0", - "postcss-value-parser": "^4.1.0" - } - }, "postcss-selector-parser": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz", @@ -6390,27 +5137,6 @@ "uniq": "^1.0.1" } }, - "postcss-svgo": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.0.0.tgz", - "integrity": "sha512-M3/VS4sFI1Yp9g0bPL+xzzCNz5iLdRUztoFaugMit5a8sMfkVzzhwqbsOlD8IFFymCdJDmXmh31waYHWw1K4BA==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.1.0", - "svgo": "^2.3.0" - } - }, - "postcss-unique-selectors": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.0.0.tgz", - "integrity": "sha512-o9l4pF8SRn7aCMTmzb/kNv/kjV7wPZpZ8Nlb1Gq8v/Qvw969K1wanz1RVA0ehHzWe9+wHXaC2DvZlak/gdMJ5w==", - "dev": true, - "requires": { - "alphanum-sort": "^1.0.2", - "postcss-selector-parser": "^6.0.2", - "uniqs": "^2.0.0" - } - }, "postcss-value-parser": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", @@ -6439,12 +5165,6 @@ "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", "dev": true }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, "prompts": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.1.tgz", @@ -6513,48 +5233,6 @@ "string_decoder": "0.10" } }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - }, - "dependencies": { - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - } - } - }, "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -6583,6 +5261,15 @@ } } }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, "rechoir": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.0.tgz", @@ -6592,16 +5279,6 @@ "resolve": "^1.9.0" } }, - "redent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", - "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", - "dev": true, - "requires": { - "indent-string": "^2.1.0", - "strip-indent": "^1.0.1" - } - }, "reduce-flatten": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz", @@ -6782,15 +5459,6 @@ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true, - "requires": { - "is-finite": "^1.0.0" - } - }, "request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", @@ -6853,12 +5521,6 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "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.17.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", @@ -7001,43 +5663,6 @@ "integrity": "sha1-mUWygD8hni96ygCtuLyfZA+ELJo=", "dev": true }, - "rgb-regex": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", - "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=", - "dev": true - }, - "rgba-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", - "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=", - "dev": true - }, - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, "run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -7064,106 +5689,13 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, - "sass-graph": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.5.tgz", - "integrity": "sha512-VFWDAHOe6mRuT4mZRd4eKE+d8Uedrk6Xnh7Sh9b4NGufQLQjOrvf/MQoOdx+0s92L89FeyUUNfU597j/3uNpag==", + "sass": { + "version": "1.34.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.34.0.tgz", + "integrity": "sha512-rHEN0BscqjUYuomUEaqq3BMgsXqQfkcMVR7UhscsAVub0/spUrZGBMxQXFS2kfiDsPLZw5yuU9iJEFNC2x38Qw==", "dev": true, "requires": { - "glob": "^7.0.0", - "lodash": "^4.0.0", - "scss-tokenizer": "^0.2.3", - "yargs": "^13.3.2" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } + "chokidar": ">=3.0.0 <4.0.0" } }, "sass-loader": { @@ -7212,27 +5744,6 @@ "ajv-keywords": "^3.4.1" } }, - "scss-tokenizer": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", - "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=", - "dev": true, - "requires": { - "js-base64": "^2.1.8", - "source-map": "^0.4.2" - }, - "dependencies": { - "source-map": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", - "dev": true, - "requires": { - "amdefine": ">=0.0.4" - } - } - } - }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -7247,12 +5758,6 @@ "randombytes": "^2.1.0" } }, - "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 - }, "shallow-clone": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", @@ -7286,29 +5791,12 @@ "simple-git": { "version": "2.15.0", "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-2.15.0.tgz", - "integrity": "sha512-a1IE3q8pWsGhQR0/ugAkXls2ekbB7LDhJnFnrS/R+5zFZZbN4bfdIp3Vdht4x/z1oIH/8IHiKdjilN55FGL70g==", - "dev": true, - "requires": { - "@kwsites/file-exists": "^1.1.1", - "@kwsites/promise-deferred": "^1.1.1", - "debug": "^4.1.1" - } - }, - "simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "integrity": "sha512-a1IE3q8pWsGhQR0/ugAkXls2ekbB7LDhJnFnrS/R+5zFZZbN4bfdIp3Vdht4x/z1oIH/8IHiKdjilN55FGL70g==", "dev": true, "requires": { - "is-arrayish": "^0.3.1" - }, - "dependencies": { - "is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", - "dev": true - } + "@kwsites/file-exists": "^1.1.1", + "@kwsites/promise-deferred": "^1.1.1", + "debug": "^4.1.1" } }, "sisteransi": { @@ -7371,38 +5859,6 @@ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", "dev": true }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", - "dev": true - }, "sprintf-js": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", @@ -7425,47 +5881,6 @@ "tweetnacl": "~0.14.0" } }, - "stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", - "dev": true - }, - "stdout-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz", - "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==", - "dev": true, - "requires": { - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, "stealthy-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", @@ -7541,15 +5956,6 @@ "ansi-regex": "^2.0.0" } }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - }, "strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", @@ -7561,80 +5967,6 @@ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true }, - "strip-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", - "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", - "dev": true, - "requires": { - "get-stdin": "^4.0.1" - } - }, - "stylehacks": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.0.0.tgz", - "integrity": "sha512-QOWm6XivDLb+fqffTZP8jrmPmPITVChl2KCY2R05nsCWwLi3VGhCdVc3IVGNwd1zzTt1jPd67zIKjpQfxzQZeA==", - "dev": true, - "requires": { - "browserslist": "^4.16.0", - "postcss-selector-parser": "^6.0.4" - }, - "dependencies": { - "browserslist": { - "version": "4.16.6", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", - "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001219", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.723", - "escalade": "^3.1.1", - "node-releases": "^1.1.71" - } - }, - "caniuse-lite": { - "version": "1.0.30001228", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz", - "integrity": "sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A==", - "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 - }, - "electron-to-chromium": { - "version": "1.3.732", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.732.tgz", - "integrity": "sha512-qKD5Pbq+QMk4nea4lMuncUMhpEiQwaJyCW7MrvissnRcBDENhVfDmAqQYRQ3X525oTzhar9Zh1cK0L2d1UKYcw==", - "dev": true - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "node-releases": { - "version": "1.1.72", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", - "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", - "dev": true - }, - "postcss-selector-parser": { - "version": "6.0.6", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz", - "integrity": "sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==", - "dev": true, - "requires": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - } - } - } - }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -7644,143 +5976,6 @@ "has-flag": "^3.0.0" } }, - "svgo": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.3.0.tgz", - "integrity": "sha512-fz4IKjNO6HDPgIQxu4IxwtubtbSfGEAJUq/IXyTPIkGhWck/faiiwfkvsB8LnBkKLvSoyNNIY6d13lZprJMc9Q==", - "dev": true, - "requires": { - "@trysound/sax": "0.1.1", - "chalk": "^4.1.0", - "commander": "^7.1.0", - "css-select": "^3.1.2", - "css-tree": "^1.1.2", - "csso": "^4.2.0", - "stable": "^0.1.8" - }, - "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.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", - "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 - }, - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true - }, - "css-select": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-3.1.2.tgz", - "integrity": "sha512-qmss1EihSuBNWNNhHjxzxSfJoFBM/lERB/Q4EnsJQQC62R2evJDW481091oAdOr9uh46/0n4nrg0It5cAnj1RA==", - "dev": true, - "requires": { - "boolbase": "^1.0.0", - "css-what": "^4.0.0", - "domhandler": "^4.0.0", - "domutils": "^2.4.3", - "nth-check": "^2.0.0" - } - }, - "css-what": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-4.0.0.tgz", - "integrity": "sha512-teijzG7kwYfNVsUh2H/YN62xW3KK9YhXEgSlbxMlcyjPNvdKJqFx5lrwlJgoFP1ZHlB89iGDlo/JyshKeRhv5A==", - "dev": true - }, - "dom-serializer": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", - "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", - "dev": true, - "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - } - }, - "domelementtype": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", - "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", - "dev": true - }, - "domhandler": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.0.tgz", - "integrity": "sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA==", - "dev": true, - "requires": { - "domelementtype": "^2.2.0" - } - }, - "domutils": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.6.0.tgz", - "integrity": "sha512-y0BezHuy4MDYxh6OvolXYsH+1EMGmFbwv5FKW7ovwMG6zTPWqNPq3WF9ayZssFq+UlKdffGLbOEaghNdaOm1WA==", - "dev": true, - "requires": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.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 - }, - "nth-check": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.0.tgz", - "integrity": "sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q==", - "dev": true, - "requires": { - "boolbase": "^1.0.0" - } - }, - "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" - } - } - } - }, "symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -7805,17 +6000,6 @@ "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", "dev": true }, - "tar": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", - "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", - "dev": true, - "requires": { - "block-stream": "*", - "fstream": "^1.0.12", - "inherits": "2" - } - }, "terser": { "version": "4.8.0", "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz", @@ -7932,12 +6116,6 @@ } } }, - "timsort": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", - "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", - "dev": true - }, "tiny-lr": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-1.1.1.tgz", @@ -8072,37 +6250,6 @@ } } }, - "trim-newlines": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", - "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", - "dev": true - }, - "true-case-path": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz", - "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==", - "dev": true, - "requires": { - "glob": "^7.1.2" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, "tslib": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", @@ -8207,12 +6354,6 @@ "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", "dev": true }, - "uniqs": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", - "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", - "dev": true - }, "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -8304,22 +6445,6 @@ "homedir-polyfill": "^1.0.1" } }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "vendors": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz", - "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==", - "dev": true - }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", @@ -8705,54 +6830,6 @@ "isexe": "^2.0.0" } }, - "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 - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, "wildcard": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", @@ -8897,23 +6974,11 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" }, - "yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true - }, "yargs": { "version": "17.0.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.0.1.tgz", diff --git a/static/package.json b/static/package.json index 079295083..369d118da 100644 --- a/static/package.json +++ b/static/package.json @@ -33,10 +33,10 @@ "jambo": "^1.11.0", "jsdom": "^16.4.0", "mini-css-extract-plugin": "^1.6.0", - "node-sass": "^4.13.1", "postcss": "^8.2.10", "postcss-loader": "^5.3.0", "resolve-url-loader": "^3.1.1", + "sass": "^1.34.0", "sass-loader": "^8.0.2", "simple-git": "^2.15.0", "webpack": "^5.4.0", From 25d08e9a67a9856c9480b079347ad5864489ee74 Mon Sep 17 00:00:00 2001 From: Oliver Shi Date: Wed, 26 May 2021 12:34:13 -0400 Subject: [PATCH 15/56] remove unused mixins (#793) (#795) This commit removes css classes generated by UtilityLayouts.scss. These classes (`l-row-\*`, `l-col-\*`, `l-centeredColumn`) are not used anywhere in the theme or SDK. Removing these auto-generated classes reduces the css bundle size from 267KB to 194KB. J=SLAP-1298 TEST=manual loaded up a page, ran a search, asked for a direct answer --- .../answers/common/util/UtilityLayout.scss | 91 ------------------- static/scss/answers/common/variables.scss | 3 - 2 files changed, 94 deletions(-) diff --git a/static/scss/answers/common/util/UtilityLayout.scss b/static/scss/answers/common/util/UtilityLayout.scss index 0486efc99..96b54c427 100644 --- a/static/scss/answers/common/util/UtilityLayout.scss +++ b/static/scss/answers/common/util/UtilityLayout.scss @@ -1,97 +1,6 @@ @import "../variables"; @import "./Spacing.scss"; -$generate-classes: false !default; -$col-gap: spacing(base) !default; -$splitting-points: (sm, md, lg) !default; - - -@if $generate-classes -{ - .l-row - { - @include l-row; - - &-separator - { - border-bottom:solid 1px #222; - } - - &-vertical-margin - { - &-top - { - margin-top: $vertical-margin-top; - - &-sm - { - margin-top: $vertical-margin-top / 2; - } - } - - &-bottom - { - margin-bottom: $vertical-margin-top; - - &-sm - { - margin-bottom: $vertical-margin-top / 2; - } - } - } - } - - @for $colCount from 1 through $grid-columns - { - @each $start, $end, $direction in (lg, null, "up"), - (md, null, "up"), - (sm, null, "up"), - (null, md, "down"), - (null, sm, "down"), - (null, xs, "down") - { - $abbreviation: if($start, $start, $end); - - .l-col-#{$abbreviation}-#{$colCount}-#{$direction} - { - @include bp($start, $end) - { - @include l-col($colCount, $grid-columns) - } - } - } - } - - @for $colCount from 1 through $grid-columns - { - @each $start, $end in (lg, null), - (md, md), - (sm, sm), - (null, xs) - { - $abbreviation: if($start, $start, $end); - - .l-col-#{$abbreviation}-#{$colCount} - { - @include bp($start, $end) - { - @include l-col($colCount, $grid-columns) - } - } - } - } - - @each $bp in $splitting-points - { - @include l-Split($bp, $col-gap, '.l-Split'); - } - - .l-centeredColumn - { - @include l-centeredColumn; - } -} - .l-container { @include l-container; diff --git a/static/scss/answers/common/variables.scss b/static/scss/answers/common/variables.scss index f22f48bff..384f7ecb5 100644 --- a/static/scss/answers/common/variables.scss +++ b/static/scss/answers/common/variables.scss @@ -1,6 +1,3 @@ -// utility mixin layout variables -$generate-classes: true; - $grid-gutter-width: 32px !default; $grid-gutter-width-xs: $grid-gutter-width !default; $grid-gutter-width-sm: $grid-gutter-width !default; From 32455b85f23bb07382cf637ab74240a2bcd25bdd Mon Sep 17 00:00:00 2001 From: Yen Truong <36055303+yen-tt@users.noreply.github.com> Date: Thu, 27 May 2021 10:40:56 -0400 Subject: [PATCH 16/56] Resolved deprecation warnings from inlineAssetHtmlPlugin and webpack (#796) Updated html-webpack-plugin, used by inlineAssetHtlmPlugin, to be more integrated with webpack v5, which got rid of the deprecated warnings from older v4 with asset and public path. Since inlineAssetHTMLPlugin only access compilation.assets without modification, no changes are needed in the js file. Instead, updated webpack version to remove compilation asset warning. J=SLAP-1307 TEST=compile Co-authored-by: Yen Truong --- static/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/static/package.json b/static/package.json index 369d118da..a347084ee 100644 --- a/static/package.json +++ b/static/package.json @@ -29,7 +29,7 @@ "grunt-contrib-watch": "^1.1.0", "grunt-webpack": "^4.0.0", "html-loader": "^1.1.0", - "html-webpack-plugin": "^4.3.0", + "html-webpack-plugin": "^5.3.1", "jambo": "^1.11.0", "jsdom": "^16.4.0", "mini-css-extract-plugin": "^1.6.0", @@ -39,7 +39,7 @@ "sass": "^1.34.0", "sass-loader": "^8.0.2", "simple-git": "^2.15.0", - "webpack": "^5.4.0", + "webpack": "^5.37.1", "webpack-cli": "^4.2.0", "webpack-merge": "^5.7.3" }, From 3d454b27aee59735d74186640601c0143cdaf0b3 Mon Sep 17 00:00:00 2001 From: cea2aj <42848445+cea2aj@users.noreply.github.com> Date: Thu, 27 May 2021 17:28:45 -0400 Subject: [PATCH 17/56] Video card (#794) Add video card In order to embed the video responsively, I used the styling by http://embedresponsively.com/ (MIT License). This ensures that the vimeo videos are always full width. I also added a getYoutubeUrl formatter which gets an embed link for youtube videos based on the profile.videos data from the KG. J=SLAP-1328 TEST=manual, auto Test youtube and vimeo videos. Test details, CTAs, and the showMoreDetails option. Use a test site from product to test with actual KG data for both youtube and vimeo. Add unit test for the new formatter --- .../component.js | 71 ++++++++++ .../template.hbs | 123 ++++++++++++++++++ static/js/formatters-internal.js | 17 +++ static/js/formatters.js | 6 +- static/scss/answers/_default.scss | 1 + .../answers/cards/product-prominentvideo.scss | 87 +++++++++++++ .../js/formatters-internal/getYoutubeUrl.js | 21 +++ 7 files changed, 324 insertions(+), 2 deletions(-) create mode 100644 cards/multilang-product-prominentvideo/component.js create mode 100644 cards/multilang-product-prominentvideo/template.hbs create mode 100644 static/scss/answers/cards/product-prominentvideo.scss create mode 100644 tests/static/js/formatters-internal/getYoutubeUrl.js diff --git a/cards/multilang-product-prominentvideo/component.js b/cards/multilang-product-prominentvideo/component.js new file mode 100644 index 000000000..6ab67da28 --- /dev/null +++ b/cards/multilang-product-prominentvideo/component.js @@ -0,0 +1,71 @@ +{{> cards/card_component componentName='multilang-product-prominentvideo' }} + +class multilang_product_prominentvideoCardComponent extends BaseCard['multilang-product-prominentvideo'] { + constructor(config = {}, systemConfig = {}) { + super(config, systemConfig); + } + + /** + * This returns an object that will be called `card` + * in the template. Put all mapping logic here. + * + * @param profile profile of the entity in the card + */ + dataForRender(profile) { + const youtubeUrl = Formatter.getYoutubeUrl(profile.videos); + // const vimeoUrl = profile.c_vimeo; + + return { + title: profile.name, // The header text of the card + url: profile.landingPageUrl, // If the card title is a clickable link, set URL here + target: '_top', // If the title's URL should open in a new tab, etc. + titleEventOptions: this.addDefaultEventOptions(), + subtitle: profile.featuredMessage?.description, // The sub-header text of the card + videoUrl: youtubeUrl, + details: profile.richTextDescription ? ANSWERS.formatRichText(profile.richTextDescription, 'richTextDescription', '_top') : null, // The text in the body of the card + // If the card's details are longer than a certain character count, you can truncate the + // text. A toggle will be supplied that can show or hide the truncated text. + // Note: If you are using rich text for the details, you should not enable this feature. + // showMoreDetails: { + // showMoreLimit: 24, // Character count limit + // showMoreText: {{ translateJS phrase='Show more' }}, // Label when toggle will show truncated text + // showLessText: {{ translateJS phrase='Show less' }} // Label when toggle will hide truncated text + // }, + // The primary CTA of the card + CTA1: { + label: profile.c_primaryCTA ? profile.c_primaryCTA.label : null, // The CTA's label + iconName: 'chevron', // The icon to use for the CTA + url: Formatter.generateCTAFieldTypeLink(profile.c_primaryCTA), // The URL a user will be directed to when clicking + target: '_top', // Where the new URL will be opened + eventType: 'CTA_CLICK', // Type of Analytics event fired when clicking the CTA + eventOptions: this.addDefaultEventOptions(), + // ariaLabel: '', // Accessible text providing a descriptive label for the CTA + }, + // The secondary CTA of the card + CTA2: { + label: profile.c_secondaryCTA ? profile.c_secondaryCTA.label : null, + iconName: 'chevron', + url: Formatter.generateCTAFieldTypeLink(profile.c_secondaryCTA), + target: '_top', + eventType: 'CTA_CLICK', + eventOptions: this.addDefaultEventOptions(), + // ariaLabel: '', + } + }; + } + + /** + * The template to render + * @returns {string} + * @override + */ + static defaultTemplateName (config) { + return 'cards/multilang-product-prominentvideo'; + } +} + +ANSWERS.registerTemplate( + 'cards/multilang-product-prominentvideo', + {{{stringifyPartial (read 'cards/multilang-product-prominentvideo/template') }}} +); +ANSWERS.registerComponentType(multilang_product_prominentvideoCardComponent); diff --git a/cards/multilang-product-prominentvideo/template.hbs b/cards/multilang-product-prominentvideo/template.hbs new file mode 100644 index 000000000..9b2cea265 --- /dev/null +++ b/cards/multilang-product-prominentvideo/template.hbs @@ -0,0 +1,123 @@ +
+
+ {{> title }} + {{> subtitle }} +
+ {{> video }} + {{> content }} +
+ +{{#*inline 'title'}} +{{#if card.title}} +
+ {{#if card.url}} + + {{card.title}} + + {{else}} + {{card.title}} + {{/if}} +
+{{/if}} +{{/inline}} + +{{#*inline 'subtitle'}} +{{#if card.subtitle}} +
+ {{card.subtitle}} +
+{{/if}} +{{/inline}} + +{{#*inline 'video'}} +{{#if card.videoUrl}} +
+ +
+{{/if}} +{{/inline}} + +{{#*inline 'content'}} +{{#if (any card.details (all card.CTA1 card.CTA1.url card.CTA1.label) (all card.CTA2 card.CTA2.url card.CTA2.label))}} +
+ {{> details }} + {{> ctas }} +
+{{/if}} +{{/inline}} + +{{! Displays the details for the card. If showMoreDetails has been configured, + this partial handles the show more toggle, show less toggle, truncated details, + and full details. If showMoreDetails has not been configured, it will display the + the regular card details. +}} +{{#*inline 'details'}} +{{#if card.details}} +
+ {{#if showExcessDetailsToggle}} +
+ {{{truncatedDetails}}} +
+ {{/if}} +
+ {{{card.details}}} +
+ {{#if showExcessDetailsToggle}} + + + {{/if}} +
+{{/if}} +{{/inline}} + +{{#*inline 'ctas'}} +{{#if (any (all card.CTA1 card.CTA1.url card.CTA1.label) (all card.CTA2 card.CTA2.url card.CTA2.label))}} +
+ {{> CTA card.CTA1 ctaName="primaryCTA" }} + {{> CTA card.CTA2 ctaName="secondaryCTA" }} +
+{{/if}} +{{/inline}} + +{{#*inline 'CTA'}} +{{#if (all url label)}} + +{{/if}} +{{/inline}} diff --git a/static/js/formatters-internal.js b/static/js/formatters-internal.js index 7ad725f08..accc7beeb 100644 --- a/static/js/formatters-internal.js +++ b/static/js/formatters-internal.js @@ -560,4 +560,21 @@ export function highlightField(fieldValue, matchedSubstrings = []) { }); return highlightedString; +} + +/** + * Given an array of youtube videos from the KG, returns an embed link for the first video. + * If it is not possible to get an embed link, null is returned instead. + * + * @param {Object[]} videos + * @returns {string|null} + */ +export function getYoutubeUrl(videos = []) { + if (videos.length === 0) { + return null; + } + const videoUrl = videos[0]?.video?.url; + const youtubeVideoId = videoUrl?.split('watch?v=')[1]; + const youtubeVideoUrl = youtubeVideoId ? 'https://www.youtube.com/embed/' + youtubeVideoId : null; + return youtubeVideoUrl; } \ No newline at end of file diff --git a/static/js/formatters.js b/static/js/formatters.js index 2235ff251..1d1084929 100644 --- a/static/js/formatters.js +++ b/static/js/formatters.js @@ -28,7 +28,8 @@ import { hoursList, generateCTAFieldTypeLink, price, - highlightField + highlightField, + getYoutubeUrl } from './formatters-internal.js'; import * as CustomFormatters from './formatters-custom.js'; @@ -60,7 +61,8 @@ let Formatters = { hoursList, generateCTAFieldTypeLink, price, - highlightField + highlightField, + getYoutubeUrl }; Formatters = Object.assign(Formatters, CustomFormatters); diff --git a/static/scss/answers/_default.scss b/static/scss/answers/_default.scss index e684277a3..a9a9c20fc 100644 --- a/static/scss/answers/_default.scss +++ b/static/scss/answers/_default.scss @@ -45,6 +45,7 @@ @import "cards/link-standard"; @import "cards/menuitem-standard"; @import "cards/product-prominentimage"; +@import "cards/product-prominentvideo"; @import "cards/professional-standard"; @import "cards/product-standard"; @import "cards/professional-location"; diff --git a/static/scss/answers/cards/product-prominentvideo.scss b/static/scss/answers/cards/product-prominentvideo.scss new file mode 100644 index 000000000..e341222f1 --- /dev/null +++ b/static/scss/answers/cards/product-prominentvideo.scss @@ -0,0 +1,87 @@ +.HitchhikerProductProminentVideo +{ + display: flex; + flex-direction: column; + font-size: var(--yxt-font-size-md); + line-height: var(--yxt-line-height-md); + background-color: var(--yxt-color-brand-white); + width: 100%; + height: 100%; + + &-header + { + display: flex; + flex-direction: column; + padding: calc(var(--yxt-base-spacing) * 3/4) var(--yxt-base-spacing); + } + + &-contentWrapper + { + display: flex; + flex-direction: column; + justify-content: space-between; + padding: calc(var(--yxt-base-spacing) * 3/4) var(--yxt-base-spacing); + } + + &-title + { + @include Text( + $size: var(--yxt-font-size-lg), + $line-height: var(--yxt-line-height-lg), + $weight: var(--yxt-font-weight-semibold)); + } + + &-titleLink + { + @include Link; + } + + &-subtitle + { + color: var(--yxt-color-text-secondary); + padding-bottom: 0; + } + + // This is the styling used by http://embedresponsively.com/ + &-videoWrapper + { + position: relative; + padding-bottom: 56.25%; + height: 0; + overflow: hidden; + max-width: 100%; + + iframe, object, embed + { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + } + } + + &-detailsText + { + @include rich_text_formatting; + } + + &-ctasWrapper + { + text-transform: uppercase; + margin-top: auto; + padding-top: calc(var(--yxt-base-spacing) / 2); + } + + &-primaryCTA, + &-secondaryCTA + { + display: flex; + margin-top: calc(var(--yxt-base-spacing) / 2); + } + + .js-hidden + { + display: none; + } +} diff --git a/tests/static/js/formatters-internal/getYoutubeUrl.js b/tests/static/js/formatters-internal/getYoutubeUrl.js new file mode 100644 index 000000000..ebd0a98f3 --- /dev/null +++ b/tests/static/js/formatters-internal/getYoutubeUrl.js @@ -0,0 +1,21 @@ +import Formatters from 'static/js/formatters.js'; + +describe('getYoutubeUrl formatter', () => { + it('returns null for no results', () => { + const actualResult = Formatters.getYoutubeUrl(); + expect(actualResult).toEqual(null); + }); + + it('correctly gets the embedded youtube url', () => { + const videos = [ + { + video: { + url: 'https://www.youtube.com/watch?v=Ww4EqJ1YUmw' + } + } + ]; + const actualUrl = Formatters.getYoutubeUrl(videos); + const expectedUrl = 'https://www.youtube.com/embed/Ww4EqJ1YUmw' + expect(actualUrl).toEqual(expectedUrl); + }) +}); \ No newline at end of file From d797247306acdf7a9999e87bc67f9d65669c52b5 Mon Sep 17 00:00:00 2001 From: Oliver Shi Date: Thu, 27 May 2021 17:43:34 -0400 Subject: [PATCH 18/56] use math.div instead of slash division in scss (#799) slash division is being deprecated in sass, and right now we're getting some warnings that might scare hitchhikers elseif is also deprecated for else if see: https://sass-lang.com/documentation/breaking-changes/slash-div J=SLAP-1348 TEST=manual ran a build, saw reduction in warnings --- static/scss/answers/_default.scss | 3 +- .../sdk-filter-overrides.scss | 2 +- static/scss/answers/common/util/Spacing.scss | 22 ++++----- .../answers/common/util/UtilityMixins.scss | 48 +++++++++---------- .../answers/common/util/_set-properties.scss | 4 +- 5 files changed, 39 insertions(+), 40 deletions(-) diff --git a/static/scss/answers/_default.scss b/static/scss/answers/_default.scss index e684277a3..e034db9af 100644 --- a/static/scss/answers/_default.scss +++ b/static/scss/answers/_default.scss @@ -1,5 +1,4 @@ -@import "vendor"; -@import "~font-awesome/scss/variables"; +@use "sass:math"; // Core variables and mixins @import "overlay/module"; diff --git a/static/scss/answers/collapsible-filters/sdk-filter-overrides.scss b/static/scss/answers/collapsible-filters/sdk-filter-overrides.scss index 148739240..98184c7f5 100644 --- a/static/scss/answers/collapsible-filters/sdk-filter-overrides.scss +++ b/static/scss/answers/collapsible-filters/sdk-filter-overrides.scss @@ -5,7 +5,7 @@ @mixin CollapsibleFiltersOverrides { .Answers-container { @media (min-width: #{$breakpoint-expanded-filters}) { - width: $container-width-at-collapsed-filters-breakpoint / $breakpoint-collapsed-filters * 100%; + width: math.div($container-width-at-collapsed-filters-breakpoint, $breakpoint-collapsed-filters) * 100%; } } diff --git a/static/scss/answers/common/util/Spacing.scss b/static/scss/answers/common/util/Spacing.scss index 439da8f84..b98a6eed4 100644 --- a/static/scss/answers/common/util/Spacing.scss +++ b/static/scss/answers/common/util/Spacing.scss @@ -1,25 +1,25 @@ @import "../variables"; @import "set-properties"; -$spacing-base: $grid-gutter-width/2 !default; +$spacing-base: math.div($grid-gutter-width, 2) !default; // see https://www.viget.com/articles/sass-with-maps // for explanation of why sass maps are great for stuff like spacing $spacing: ( zero: 0, - oneFifth: $spacing-base / 5, // 3px - oneThird: $spacing-base / 3, // 5px - half: $spacing-base / 2, // 7.5px - twoFifths: $spacing-base * (2 / 5), // 6px - twoThirds: $spacing-base * (2 / 3), // 10px - fourFifths: $spacing-base * (4 / 5), // 12px + oneFifth: math.div($spacing-base, 5), // 3px + oneThird: math.div($spacing-base, 3), // 5px + half: math.div($spacing-base, 2), // 7.5px + twoFifths: $spacing-base * math.div(2, 5), // 6px + twoThirds: $spacing-base * math.div(2, 3), // 10px + fourFifths: $spacing-base * math.div(4, 5), // 12px base: $spacing-base, // 15px ** - fourThirds: $spacing-base * (4 / 3), // 20px + fourThirds: $spacing-base * math.div(4, 3), // 20px double: $spacing-base * 2, // 30px - buttonHeight: $spacing-base * (7 / 3), // 35px - eightThirds: $spacing-base * (8 / 3), // 40px + buttonHeight: $spacing-base * math.div(7, 3), // 35px + eightThirds: $spacing-base * math.div(8, 3), // 40px triple: $spacing-base * 3, // 45px - tenThirds: $spacing-base * (10 / 3), // 50px + tenThirds: $spacing-base * math.div(10, 3), // 50px quadruple: $spacing-base * 4, // 60px ); diff --git a/static/scss/answers/common/util/UtilityMixins.scss b/static/scss/answers/common/util/UtilityMixins.scss index 6290d062d..e9cbf07c8 100644 --- a/static/scss/answers/common/util/UtilityMixins.scss +++ b/static/scss/answers/common/util/UtilityMixins.scss @@ -126,54 +126,54 @@ { margin-left: auto; margin-right: auto; - padding-left: $grid-gutter-width-xs/2; - padding-right: $grid-gutter-width-xs/2; + padding-left: math.div($grid-gutter-width-xs, 2); + padding-right: math.div($grid-gutter-width-xs, 2); width: 100%; @include bpgte(sm) { width: $container-tablet-base; - padding-left: $grid-gutter-width-sm/2; - padding-right: $grid-gutter-width-sm/2; + padding-left: math.div($grid-gutter-width-sm, 2); + padding-right: math.div($grid-gutter-width-sm, 2); } @include bpgte(md) { width: $container-desktop-base; - padding-left: $grid-gutter-width-md/2; - padding-right: $grid-gutter-width-md/2; + padding-left: math.div($grid-gutter-width-md, 2); + padding-right: math.div($grid-gutter-width-md, 2); } @include bpgte(lg) { width: $container-large-desktop-base; - padding-left: $grid-gutter-width-lg/2; - padding-right: $grid-gutter-width-lg/2; + padding-left: math.div($grid-gutter-width-lg, 2); + padding-right: math.div($grid-gutter-width-lg, 2); } } @mixin l-row { display: flex; - margin-left: -$grid-gutter-width-xs/2; - margin-right: -$grid-gutter-width-xs/2; + margin-left: -math.div($grid-gutter-width-xs, 2); + margin-right: -math.div($grid-gutter-width-xs, 2); @include bpgte(sm) { - margin-left: -$grid-gutter-width-sm/2; - margin-right: -$grid-gutter-width-sm/2; + margin-left: -math.div($grid-gutter-width-sm, 2); + margin-right: -math.div($grid-gutter-width-sm, 2); } @include bpgte(md) { - margin-left: -$grid-gutter-width-md/2; - margin-right: -$grid-gutter-width-md/2; + margin-left: -math.div($grid-gutter-width-md, 2); + margin-right: -math.div($grid-gutter-width-md, 2); } @include bpgte(lg) { - margin-left: -$grid-gutter-width-lg/2; - margin-right: -$grid-gutter-width-lg/2; + margin-left: -math.div($grid-gutter-width-lg, 2); + margin-right: -math.div($grid-gutter-width-lg, 2); } @include bplte(xs) @@ -190,25 +190,25 @@ @mixin l-col($num1, $num2) { width: percentage($num1/$num2); - padding-left: $grid-gutter-width-xs/2; - padding-right: $grid-gutter-width-xs/2; + padding-left: math.div($grid-gutter-width-xs, 2); + padding-right: math.div($grid-gutter-width-xs, 2); @include bp(sm,sm) { - padding-left: $grid-gutter-width-sm/2; - padding-right: $grid-gutter-width-sm/2; + padding-left: math.div($grid-gutter-width-sm, 2); + padding-right: math.div($grid-gutter-width-sm, 2); } @include bp(md,md) { - padding-left: $grid-gutter-width-md/2; - padding-right: $grid-gutter-width-md/2; + padding-left: math.div($grid-gutter-width-md, 2); + padding-right: math.div($grid-gutter-width-md, 2); } @include bpgte(lg) { - padding-left: $grid-gutter-width-lg/2; - padding-right: $grid-gutter-width-lg/2; + padding-left: math.div($grid-gutter-width-lg, 2); + padding-right: math.div($grid-gutter-width-lg, 2); } } diff --git a/static/scss/answers/common/util/_set-properties.scss b/static/scss/answers/common/util/_set-properties.scss index c44140549..9541bbfdd 100644 --- a/static/scss/answers/common/util/_set-properties.scss +++ b/static/scss/answers/common/util/_set-properties.scss @@ -14,12 +14,12 @@ } } - @elseif type-of($subproperties) == 'string' + @else if type-of($subproperties) == 'string' { @include set-property('#{$property}-#{$subproperties}', $value); } - @elseif type-of($subproperties) == 'null' + @else if type-of($subproperties) == 'null' { @include set-property($property, $value); } From 6040169fa103e42a8adace049d70cc2f2a06d7e2 Mon Sep 17 00:00:00 2001 From: Oliver Shi Date: Thu, 27 May 2021 17:45:26 -0400 Subject: [PATCH 19/56] remove font-awesome and bootstrap-sass deps (#798) These two dependencies provide sass variables and mixins that are not used anywhere in the code. In addition to that, after upgrading to dart-sass, we now get deprecation warnings for them because they still use the division operator `/` instead of math.div see https://sass-lang.com/documentation/breaking-changes/slash-div I believe the package-lock was out of date due to some specific way previous commits were merged. J=SLAP-1348 TEST=manual test that dart-sass will throw an error if you try to use a mixin or variable that is not defined (tested with the bootstrap and font-awesome vars/mixins) since no error is thrown, that further verifies that we are not using them anywhere in our code ran a build --- static/package-lock.json | 1245 +++++++++++++++++++++++++++++-- static/package.json | 2 - static/scss/answers/vendor.scss | 2 - 3 files changed, 1168 insertions(+), 81 deletions(-) delete mode 100644 static/scss/answers/vendor.scss diff --git a/static/package-lock.json b/static/package-lock.json index 0d767fbaa..c22bee611 100644 --- a/static/package-lock.json +++ b/static/package-lock.json @@ -1049,6 +1049,12 @@ "resolved": "https://registry.npmjs.org/@stroncium/procfs/-/procfs-1.2.1.tgz", "integrity": "sha512-X1Iui3FUNZP18EUvysTHxt+Avu2nlVzyf90YM8OYgP6SGzTzzX/0JgObfO1AQQDzuZtNNz29bVh8h5R97JrjxA==" }, + "@trysound/sax": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.1.1.tgz", + "integrity": "sha512-Z6DoceYb/1xSg5+e+ZlPZ9v0N16ZvZ+wYMraFue4HYrE4ttONKtsvruIRf6t9TBR0YvSOfi1hUU0fJfBLCDYow==", + "dev": true + }, "@types/anymatch": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", @@ -1113,6 +1119,12 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.14.tgz", "integrity": "sha512-syUgf67ZQpaJj01/tRTknkMNoBBLWJOBODF0Zm4NrXmiSuxjymFrxnTu1QVYRubhVkRcZLYZG8STTwJRdVm/WQ==" }, + "@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "dev": true + }, "@types/parse5": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-5.0.3.tgz", @@ -1514,6 +1526,12 @@ "integrity": "sha512-eyoaac3btgU8eJlvh01En8OCKzRqlLe2G5jDsCr3RiE2uLGMEEB1aaGwVVpwR8M95956tGH6R+9edC++OvzaVw==", "dev": true }, + "alphanum-sort": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", + "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", + "dev": true + }, "ansi-colors": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", @@ -1725,11 +1743,6 @@ "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", "dev": true }, - "bootstrap-sass": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/bootstrap-sass/-/bootstrap-sass-3.4.1.tgz", - "integrity": "sha512-p5rxsK/IyEDQm2CwiHxxUi0MZZtvVFbhWmyMOt4lLkA4bujDA1TGoKT0i1FKIWiugAdP+kK8T5KMDFIKQCLYIA==" - }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -1778,6 +1791,12 @@ "integrity": "sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=", "dev": true }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, "camel-case": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.1.tgz", @@ -1794,6 +1813,18 @@ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, + "caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, "caniuse-lite": { "version": "1.0.30001164", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001164.tgz", @@ -1918,6 +1949,12 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, + "colord": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.0.0.tgz", + "integrity": "sha512-WMDFJfoY3wqPZNpKUFdse3HhD5BHCbE9JCdxRzoVH+ywRITGOeWAHNkGEmyxLlErEpN9OLMWgdM9dWQtDk5dog==", + "dev": true + }, "colorette": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz", @@ -2043,6 +2080,19 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, + "cosmiconfig": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", + "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", + "dev": true, + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + } + }, "cp-file": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-6.2.0.tgz", @@ -2084,6 +2134,21 @@ } } }, + "css-color-names": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-1.0.1.tgz", + "integrity": "sha512-/loXYOch1qU1biStIFsHH8SxTmOseh1IJqFvy8IujXOm1h+QjUdDhkzOrR5HG8K8mlxREj0yfi8ewCHx0eMxzA==", + "dev": true + }, + "css-declaration-sorter": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.0.3.tgz", + "integrity": "sha512-52P95mvW1SMzuRZegvpluT6yEv0FqQusydKQPZsNN5Q7hh8EwQvN8E2nwuJ16BBvNN6LcoIZXu/Bk58DAhrrxw==", + "dev": true, + "requires": { + "timsort": "^0.3.0" + } + }, "css-loader": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.6.0.tgz", @@ -2175,6 +2240,24 @@ "integrity": "sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g==", "dev": true }, + "css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "dev": true, + "requires": { + "mdn-data": "2.0.14", + "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 + } + } + }, "css-vars-ponyfill": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/css-vars-ponyfill/-/css-vars-ponyfill-2.4.2.tgz", @@ -2192,6 +2275,69 @@ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "dev": true }, + "cssnano": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.0.4.tgz", + "integrity": "sha512-I+fDW74CJ4yb31765ov9xXe70XLZvFTXjwhmA//VgAAuSAU34Oblbe94Q9zffiCX1VhcSfQWARQnwhz+Nqgb4Q==", + "dev": true, + "requires": { + "cosmiconfig": "^7.0.0", + "cssnano-preset-default": "^5.1.1", + "is-resolvable": "^1.1.0" + } + }, + "cssnano-preset-default": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.1.1.tgz", + "integrity": "sha512-kAhR71Tascmnjlhl4UegGA3KGGbMLXHkkqVpA9idsRT1JmIhIsz1C3tDpBeQMUw5EX5Rfb1HGc/PRqD2AFk3Vg==", + "dev": true, + "requires": { + "css-declaration-sorter": "^6.0.3", + "cssnano-utils": "^2.0.1", + "postcss-calc": "^8.0.0", + "postcss-colormin": "^5.1.1", + "postcss-convert-values": "^5.0.1", + "postcss-discard-comments": "^5.0.1", + "postcss-discard-duplicates": "^5.0.1", + "postcss-discard-empty": "^5.0.1", + "postcss-discard-overridden": "^5.0.1", + "postcss-merge-longhand": "^5.0.2", + "postcss-merge-rules": "^5.0.1", + "postcss-minify-font-values": "^5.0.1", + "postcss-minify-gradients": "^5.0.1", + "postcss-minify-params": "^5.0.1", + "postcss-minify-selectors": "^5.1.0", + "postcss-normalize-charset": "^5.0.1", + "postcss-normalize-display-values": "^5.0.1", + "postcss-normalize-positions": "^5.0.1", + "postcss-normalize-repeat-style": "^5.0.1", + "postcss-normalize-string": "^5.0.1", + "postcss-normalize-timing-functions": "^5.0.1", + "postcss-normalize-unicode": "^5.0.1", + "postcss-normalize-url": "^5.0.1", + "postcss-normalize-whitespace": "^5.0.1", + "postcss-ordered-values": "^5.0.1", + "postcss-reduce-initial": "^5.0.1", + "postcss-reduce-transforms": "^5.0.1", + "postcss-svgo": "^5.0.1", + "postcss-unique-selectors": "^5.0.1" + } + }, + "cssnano-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-2.0.1.tgz", + "integrity": "sha512-i8vLRZTnEH9ubIyfdZCAdIdgnHAUeQeByEeQ2I7oTilvP9oHO6RScpeq3GsFUVqeB8uZgOQ9pw8utofNn32hhQ==", + "dev": true + }, + "csso": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "dev": true, + "requires": { + "css-tree": "^1.1.2" + } + }, "cssom": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", @@ -2514,6 +2660,15 @@ "string-template": "~0.2.1" } }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, "es-abstract": { "version": "1.17.6", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", @@ -2871,11 +3026,6 @@ "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", "dev": true }, - "font-awesome": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz", - "integrity": "sha1-j6jPBBGhoxr9B7BtKQK7n8gVoTM=" - }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -3448,6 +3598,12 @@ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, + "hex-color-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", + "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==", + "dev": true + }, "homedir-polyfill": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", @@ -3463,6 +3619,18 @@ "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=", "dev": true }, + "hsl-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", + "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=", + "dev": true + }, + "hsla-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", + "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=", + "dev": true + }, "html-encoding-sniffer": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", @@ -3718,6 +3886,24 @@ "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==" }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "dependencies": { + "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 + } + } + }, "import-local": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", @@ -3830,6 +4016,18 @@ "is-windows": "^1.0.1" } }, + "is-absolute-url": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", + "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -3845,6 +4043,28 @@ "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", "dev": true }, + "is-color-stop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", + "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=", + "dev": true, + "requires": { + "css-color-names": "^0.0.4", + "hex-color-regex": "^1.1.0", + "hsl-regex": "^1.0.0", + "hsla-regex": "^1.0.0", + "rgb-regex": "^1.0.1", + "rgba-regex": "^1.0.0" + }, + "dependencies": { + "css-color-names": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", + "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", + "dev": true + } + } + }, "is-core-module": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", @@ -3930,6 +4150,12 @@ "is-unc-path": "^1.0.0" } }, + "is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "dev": true + }, "is-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", @@ -4133,6 +4359,12 @@ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "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", @@ -4192,6 +4424,12 @@ "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true }, + "klona": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.4.tgz", + "integrity": "sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA==", + "dev": true + }, "leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -4266,6 +4504,12 @@ } } }, + "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 + }, "livereload-js": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.4.0.tgz", @@ -4333,12 +4577,24 @@ "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", "dev": true }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + }, "lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", "dev": true }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", + "dev": true + }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -4390,6 +4646,12 @@ "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", "dev": true }, + "mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", + "dev": true + }, "merge-options": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-2.0.0.tgz", @@ -4638,6 +4900,12 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, + "normalize-url": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", + "dev": true + }, "npm-run-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-1.0.0.tgz", @@ -4828,6 +5096,15 @@ "tslib": "^1.10.0" } }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, "parse-filepath": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", @@ -4839,6 +5116,18 @@ "path-root": "^0.1.1" } }, + "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" + } + }, "parse-passwd": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", @@ -4903,6 +5192,12 @@ "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", "dev": true }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -4973,108 +5268,423 @@ } } }, - "postcss-modules-extract-imports": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", - "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", + "postcss-calc": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.0.0.tgz", + "integrity": "sha512-5NglwDrcbiy8XXfPM11F3HeC6hoT9W7GUH/Zi5U/p7u3Irv4rHhdDcIZwG0llHXV4ftsBjpfWMXAnXNl4lnt8g==", "dev": true, "requires": { - "postcss": "^7.0.5" + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.0.2" + } + }, + "postcss-colormin": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.1.1.tgz", + "integrity": "sha512-SyTmqKKN6PyYNeeKEC0hqIP5CDuprO1hHurdW1aezDyfofDUOn7y7MaxcolbsW3oazPwFiGiY30XRiW1V4iZpA==", + "dev": true, + "requires": { + "browserslist": "^4.16.0", + "colord": "^2.0.0", + "postcss-value-parser": "^4.1.0" }, "dependencies": { - "postcss": { - "version": "7.0.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", - "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", + "browserslist": { + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", "dev": true, "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" } }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "caniuse-lite": { + "version": "1.0.30001230", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001230.tgz", + "integrity": "sha512-5yBd5nWCBS+jWKTcHOzXwo5xzcj4ePE/yjtkZyUV1BTUmrBaA9MRGC+e7mxnqXSA90CmCA8L3eKLaSUkt099IQ==", "dev": true }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } + "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 + }, + "electron-to-chromium": { + "version": "1.3.740", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.740.tgz", + "integrity": "sha512-Mi2m55JrX2BFbNZGKYR+2ItcGnR4O5HhrvgoRRyZQlaMGQULqDhoGkLWHzJoshSzi7k1PUofxcDbNhlFrDZNhg==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "node-releases": { + "version": "1.1.72", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", + "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", + "dev": true } } }, - "postcss-modules-local-by-default": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.2.tgz", - "integrity": "sha512-jM/V8eqM4oJ/22j0gx4jrp63GSvDH6v86OqyTHHUvk4/k1vceipZsaymiZ5PvocqZOl5SFHiFJqjs3la0wnfIQ==", + "postcss-convert-values": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.0.1.tgz", + "integrity": "sha512-C3zR1Do2BkKkCgC0g3sF8TS0koF2G+mN8xxayZx3f10cIRmTaAnpgpRQZjNekTZxM2ciSPoh2IWJm0VZx8NoQg==", "dev": true, "requires": { - "icss-utils": "^4.1.1", - "postcss": "^7.0.16", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.0.0" + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-discard-comments": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.0.1.tgz", + "integrity": "sha512-lgZBPTDvWrbAYY1v5GYEv8fEO/WhKOu/hmZqmCYfrpD6eyDWWzAOsl2rF29lpvziKO02Gc5GJQtlpkTmakwOWg==", + "dev": true + }, + "postcss-discard-duplicates": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.0.1.tgz", + "integrity": "sha512-svx747PWHKOGpAXXQkCc4k/DsWo+6bc5LsVrAsw+OU+Ibi7klFZCyX54gjYzX4TH+f2uzXjRviLARxkMurA2bA==", + "dev": true + }, + "postcss-discard-empty": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.0.1.tgz", + "integrity": "sha512-vfU8CxAQ6YpMxV2SvMcMIyF2LX1ZzWpy0lqHDsOdaKKLQVQGVP1pzhrI9JlsO65s66uQTfkQBKBD/A5gp9STFw==", + "dev": true + }, + "postcss-discard-overridden": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.0.1.tgz", + "integrity": "sha512-Y28H7y93L2BpJhrdUR2SR2fnSsT+3TVx1NmVQLbcnZWwIUpJ7mfcTC6Za9M2PG6w8j7UQRfzxqn8jU2VwFxo3Q==", + "dev": true + }, + "postcss-loader": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-5.3.0.tgz", + "integrity": "sha512-/+Z1RAmssdiSLgIZwnJHwBMnlABPgF7giYzTN2NOfr9D21IJZ4mQC1R2miwp80zno9M4zMD/umGI8cR+2EL5zw==", + "dev": true, + "requires": { + "cosmiconfig": "^7.0.0", + "klona": "^2.0.4", + "semver": "^7.3.4" }, "dependencies": { - "postcss": { - "version": "7.0.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", - "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" + "yallist": "^4.0.0" } }, - "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 - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "lru-cache": "^6.0.0" } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } }, - "postcss-modules-scope": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", - "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", + "postcss-merge-longhand": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.0.2.tgz", + "integrity": "sha512-BMlg9AXSI5G9TBT0Lo/H3PfUy63P84rVz3BjCFE9e9Y9RXQZD3+h3YO1kgTNsNJy7bBc1YQp8DmSnwLIW5VPcw==", "dev": true, "requires": { - "postcss": "^7.0.6", - "postcss-selector-parser": "^6.0.0" + "css-color-names": "^1.0.1", + "postcss-value-parser": "^4.1.0", + "stylehacks": "^5.0.1" + } + }, + "postcss-merge-rules": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.0.1.tgz", + "integrity": "sha512-UR6R5Ph0c96QB9TMBH3ml8/kvPCThPHepdhRqAbvMRDRHQACPC8iM5NpfIC03+VRMZTGXy4L/BvFzcDFCgb+fA==", + "dev": true, + "requires": { + "browserslist": "^4.16.0", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^2.0.1", + "postcss-selector-parser": "^6.0.5", + "vendors": "^1.0.3" }, "dependencies": { - "postcss": { - "version": "7.0.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", - "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", + "browserslist": { + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", "dev": true, "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" } }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "caniuse-lite": { + "version": "1.0.30001230", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001230.tgz", + "integrity": "sha512-5yBd5nWCBS+jWKTcHOzXwo5xzcj4ePE/yjtkZyUV1BTUmrBaA9MRGC+e7mxnqXSA90CmCA8L3eKLaSUkt099IQ==", + "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 + }, + "electron-to-chromium": { + "version": "1.3.740", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.740.tgz", + "integrity": "sha512-Mi2m55JrX2BFbNZGKYR+2ItcGnR4O5HhrvgoRRyZQlaMGQULqDhoGkLWHzJoshSzi7k1PUofxcDbNhlFrDZNhg==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "node-releases": { + "version": "1.1.72", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", + "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", + "dev": true + }, + "postcss-selector-parser": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz", + "integrity": "sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + } + } + }, + "postcss-minify-font-values": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.0.1.tgz", + "integrity": "sha512-7JS4qIsnqaxk+FXY1E8dHBDmraYFWmuL6cgt0T1SWGRO5bzJf8sUoelwa4P88LEWJZweHevAiDKxHlofuvtIoA==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-minify-gradients": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.0.1.tgz", + "integrity": "sha512-odOwBFAIn2wIv+XYRpoN2hUV3pPQlgbJ10XeXPq8UY2N+9ZG42xu45lTn/g9zZ+d70NKSQD6EOi6UiCMu3FN7g==", + "dev": true, + "requires": { + "cssnano-utils": "^2.0.1", + "is-color-stop": "^1.1.0", + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-minify-params": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.0.1.tgz", + "integrity": "sha512-4RUC4k2A/Q9mGco1Z8ODc7h+A0z7L7X2ypO1B6V8057eVK6mZ6xwz6QN64nHuHLbqbclkX1wyzRnIrdZehTEHw==", + "dev": true, + "requires": { + "alphanum-sort": "^1.0.2", + "browserslist": "^4.16.0", + "cssnano-utils": "^2.0.1", + "postcss-value-parser": "^4.1.0", + "uniqs": "^2.0.0" + }, + "dependencies": { + "browserslist": { + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" + } + }, + "caniuse-lite": { + "version": "1.0.30001230", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001230.tgz", + "integrity": "sha512-5yBd5nWCBS+jWKTcHOzXwo5xzcj4ePE/yjtkZyUV1BTUmrBaA9MRGC+e7mxnqXSA90CmCA8L3eKLaSUkt099IQ==", + "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 + }, + "electron-to-chromium": { + "version": "1.3.740", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.740.tgz", + "integrity": "sha512-Mi2m55JrX2BFbNZGKYR+2ItcGnR4O5HhrvgoRRyZQlaMGQULqDhoGkLWHzJoshSzi7k1PUofxcDbNhlFrDZNhg==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "node-releases": { + "version": "1.1.72", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", + "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", + "dev": true + } + } + }, + "postcss-minify-selectors": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.1.0.tgz", + "integrity": "sha512-NzGBXDa7aPsAcijXZeagnJBKBPMYLaJJzB8CQh6ncvyl2sIndLVWfbcDi0SBjRWk5VqEjXvf8tYwzoKf4Z07og==", + "dev": true, + "requires": { + "alphanum-sort": "^1.0.2", + "postcss-selector-parser": "^6.0.5" + }, + "dependencies": { + "postcss-selector-parser": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz", + "integrity": "sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + } + } + }, + "postcss-modules-extract-imports": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", + "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", + "dev": true, + "requires": { + "postcss": "^7.0.5" + }, + "dependencies": { + "postcss": { + "version": "7.0.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", + "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "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 + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-modules-local-by-default": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.2.tgz", + "integrity": "sha512-jM/V8eqM4oJ/22j0gx4jrp63GSvDH6v86OqyTHHUvk4/k1vceipZsaymiZ5PvocqZOl5SFHiFJqjs3la0wnfIQ==", + "dev": true, + "requires": { + "icss-utils": "^4.1.1", + "postcss": "^7.0.16", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.0.0" + }, + "dependencies": { + "postcss": { + "version": "7.0.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", + "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "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 + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-modules-scope": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", + "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", + "dev": true, + "requires": { + "postcss": "^7.0.6", + "postcss-selector-parser": "^6.0.0" + }, + "dependencies": { + "postcss": { + "version": "7.0.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", + "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "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 }, "supports-color": { @@ -5126,6 +5736,210 @@ } } }, + "postcss-normalize-charset": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.0.1.tgz", + "integrity": "sha512-6J40l6LNYnBdPSk+BHZ8SF+HAkS4q2twe5jnocgd+xWpz/mx/5Sa32m3W1AA8uE8XaXN+eg8trIlfu8V9x61eg==", + "dev": true + }, + "postcss-normalize-display-values": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.0.1.tgz", + "integrity": "sha512-uupdvWk88kLDXi5HEyI9IaAJTE3/Djbcrqq8YgjvAVuzgVuqIk3SuJWUisT2gaJbZm1H9g5k2w1xXilM3x8DjQ==", + "dev": true, + "requires": { + "cssnano-utils": "^2.0.1", + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-normalize-positions": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.0.1.tgz", + "integrity": "sha512-rvzWAJai5xej9yWqlCb1OWLd9JjW2Ex2BCPzUJrbaXmtKtgfL8dBMOOMTX6TnvQMtjk3ei1Lswcs78qKO1Skrg==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-normalize-repeat-style": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.0.1.tgz", + "integrity": "sha512-syZ2itq0HTQjj4QtXZOeefomckiV5TaUO6ReIEabCh3wgDs4Mr01pkif0MeVwKyU/LHEkPJnpwFKRxqWA/7O3w==", + "dev": true, + "requires": { + "cssnano-utils": "^2.0.1", + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-normalize-string": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.0.1.tgz", + "integrity": "sha512-Ic8GaQ3jPMVl1OEn2U//2pm93AXUcF3wz+OriskdZ1AOuYV25OdgS7w9Xu2LO5cGyhHCgn8dMXh9bO7vi3i9pA==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-normalize-timing-functions": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.0.1.tgz", + "integrity": "sha512-cPcBdVN5OsWCNEo5hiXfLUnXfTGtSFiBU9SK8k7ii8UD7OLuznzgNRYkLZow11BkQiiqMcgPyh4ZqXEEUrtQ1Q==", + "dev": true, + "requires": { + "cssnano-utils": "^2.0.1", + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-normalize-unicode": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.0.1.tgz", + "integrity": "sha512-kAtYD6V3pK0beqrU90gpCQB7g6AOfP/2KIPCVBKJM2EheVsBQmx/Iof+9zR9NFKLAx4Pr9mDhogB27pmn354nA==", + "dev": true, + "requires": { + "browserslist": "^4.16.0", + "postcss-value-parser": "^4.1.0" + }, + "dependencies": { + "browserslist": { + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" + } + }, + "caniuse-lite": { + "version": "1.0.30001230", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001230.tgz", + "integrity": "sha512-5yBd5nWCBS+jWKTcHOzXwo5xzcj4ePE/yjtkZyUV1BTUmrBaA9MRGC+e7mxnqXSA90CmCA8L3eKLaSUkt099IQ==", + "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 + }, + "electron-to-chromium": { + "version": "1.3.740", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.740.tgz", + "integrity": "sha512-Mi2m55JrX2BFbNZGKYR+2ItcGnR4O5HhrvgoRRyZQlaMGQULqDhoGkLWHzJoshSzi7k1PUofxcDbNhlFrDZNhg==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "node-releases": { + "version": "1.1.72", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", + "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", + "dev": true + } + } + }, + "postcss-normalize-url": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.0.1.tgz", + "integrity": "sha512-hkbG0j58Z1M830/CJ73VsP7gvlG1yF+4y7Fd1w4tD2c7CaA2Psll+pQ6eQhth9y9EaqZSLzamff/D0MZBMbYSg==", + "dev": true, + "requires": { + "is-absolute-url": "^3.0.3", + "normalize-url": "^4.5.0", + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-normalize-whitespace": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.0.1.tgz", + "integrity": "sha512-iPklmI5SBnRvwceb/XH568yyzK0qRVuAG+a1HFUsFRf11lEJTiQQa03a4RSCQvLKdcpX7XsI1Gen9LuLoqwiqA==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-ordered-values": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.0.1.tgz", + "integrity": "sha512-6mkCF5BQ25HvEcDfrMHCLLFHlraBSlOXFnQMHYhSpDO/5jSR1k8LdEXOkv+7+uzW6o6tBYea1Km0wQSRkPJkwA==", + "dev": true, + "requires": { + "cssnano-utils": "^2.0.1", + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-reduce-initial": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.0.1.tgz", + "integrity": "sha512-zlCZPKLLTMAqA3ZWH57HlbCjkD55LX9dsRyxlls+wfuRfqCi5mSlZVan0heX5cHr154Dq9AfbH70LyhrSAezJw==", + "dev": true, + "requires": { + "browserslist": "^4.16.0", + "caniuse-api": "^3.0.0" + }, + "dependencies": { + "browserslist": { + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" + } + }, + "caniuse-lite": { + "version": "1.0.30001230", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001230.tgz", + "integrity": "sha512-5yBd5nWCBS+jWKTcHOzXwo5xzcj4ePE/yjtkZyUV1BTUmrBaA9MRGC+e7mxnqXSA90CmCA8L3eKLaSUkt099IQ==", + "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 + }, + "electron-to-chromium": { + "version": "1.3.740", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.740.tgz", + "integrity": "sha512-Mi2m55JrX2BFbNZGKYR+2ItcGnR4O5HhrvgoRRyZQlaMGQULqDhoGkLWHzJoshSzi7k1PUofxcDbNhlFrDZNhg==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "node-releases": { + "version": "1.1.72", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", + "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", + "dev": true + } + } + }, + "postcss-reduce-transforms": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.0.1.tgz", + "integrity": "sha512-a//FjoPeFkRuAguPscTVmRQUODP+f3ke2HqFNgGPwdYnpeC29RZdCBvGRGTsKpMURb/I3p6jdKoBQ2zI+9Q7kA==", + "dev": true, + "requires": { + "cssnano-utils": "^2.0.1", + "postcss-value-parser": "^4.1.0" + } + }, "postcss-selector-parser": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz", @@ -5137,6 +5951,39 @@ "uniq": "^1.0.1" } }, + "postcss-svgo": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.0.1.tgz", + "integrity": "sha512-cD7DFo6tF9i5eWvwtI4irKOHCpmASFS0xvZ5EQIgEdA1AWfM/XiHHY/iss0gcKHhkqwgYmuo2M0KhJLd5Us6mg==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.1.0", + "svgo": "^2.3.0" + } + }, + "postcss-unique-selectors": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.0.1.tgz", + "integrity": "sha512-gwi1NhHV4FMmPn+qwBNuot1sG1t2OmacLQ/AX29lzyggnjd+MnVD5uqQmpXO3J17KGL2WAxQruj1qTd3H0gG/w==", + "dev": true, + "requires": { + "alphanum-sort": "^1.0.2", + "postcss-selector-parser": "^6.0.5", + "uniqs": "^2.0.0" + }, + "dependencies": { + "postcss-selector-parser": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz", + "integrity": "sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + } + } + }, "postcss-value-parser": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", @@ -5663,6 +6510,18 @@ "integrity": "sha1-mUWygD8hni96ygCtuLyfZA+ELJo=", "dev": true }, + "rgb-regex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", + "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=", + "dev": true + }, + "rgba-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", + "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=", + "dev": true + }, "run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -5881,6 +6740,12 @@ "tweetnacl": "~0.14.0" } }, + "stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "dev": true + }, "stealthy-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", @@ -5967,6 +6832,71 @@ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true }, + "stylehacks": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.0.1.tgz", + "integrity": "sha512-Es0rVnHIqbWzveU1b24kbw92HsebBepxfcqe5iix7t9j0PQqhs0IxXVXv0pY2Bxa08CgMkzD6OWql7kbGOuEdA==", + "dev": true, + "requires": { + "browserslist": "^4.16.0", + "postcss-selector-parser": "^6.0.4" + }, + "dependencies": { + "browserslist": { + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" + } + }, + "caniuse-lite": { + "version": "1.0.30001230", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001230.tgz", + "integrity": "sha512-5yBd5nWCBS+jWKTcHOzXwo5xzcj4ePE/yjtkZyUV1BTUmrBaA9MRGC+e7mxnqXSA90CmCA8L3eKLaSUkt099IQ==", + "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 + }, + "electron-to-chromium": { + "version": "1.3.740", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.740.tgz", + "integrity": "sha512-Mi2m55JrX2BFbNZGKYR+2ItcGnR4O5HhrvgoRRyZQlaMGQULqDhoGkLWHzJoshSzi7k1PUofxcDbNhlFrDZNhg==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "node-releases": { + "version": "1.1.72", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", + "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", + "dev": true + }, + "postcss-selector-parser": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz", + "integrity": "sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + } + } + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -5976,6 +6906,143 @@ "has-flag": "^3.0.0" } }, + "svgo": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.3.0.tgz", + "integrity": "sha512-fz4IKjNO6HDPgIQxu4IxwtubtbSfGEAJUq/IXyTPIkGhWck/faiiwfkvsB8LnBkKLvSoyNNIY6d13lZprJMc9Q==", + "dev": true, + "requires": { + "@trysound/sax": "0.1.1", + "chalk": "^4.1.0", + "commander": "^7.1.0", + "css-select": "^3.1.2", + "css-tree": "^1.1.2", + "csso": "^4.2.0", + "stable": "^0.1.8" + }, + "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.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "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 + }, + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true + }, + "css-select": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-3.1.2.tgz", + "integrity": "sha512-qmss1EihSuBNWNNhHjxzxSfJoFBM/lERB/Q4EnsJQQC62R2evJDW481091oAdOr9uh46/0n4nrg0It5cAnj1RA==", + "dev": true, + "requires": { + "boolbase": "^1.0.0", + "css-what": "^4.0.0", + "domhandler": "^4.0.0", + "domutils": "^2.4.3", + "nth-check": "^2.0.0" + } + }, + "css-what": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-4.0.0.tgz", + "integrity": "sha512-teijzG7kwYfNVsUh2H/YN62xW3KK9YhXEgSlbxMlcyjPNvdKJqFx5lrwlJgoFP1ZHlB89iGDlo/JyshKeRhv5A==", + "dev": true + }, + "dom-serializer": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", + "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + } + }, + "domelementtype": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", + "dev": true + }, + "domhandler": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.0.tgz", + "integrity": "sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA==", + "dev": true, + "requires": { + "domelementtype": "^2.2.0" + } + }, + "domutils": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.6.0.tgz", + "integrity": "sha512-y0BezHuy4MDYxh6OvolXYsH+1EMGmFbwv5FKW7ovwMG6zTPWqNPq3WF9ayZssFq+UlKdffGLbOEaghNdaOm1WA==", + "dev": true, + "requires": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.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 + }, + "nth-check": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.0.tgz", + "integrity": "sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q==", + "dev": true, + "requires": { + "boolbase": "^1.0.0" + } + }, + "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" + } + } + } + }, "symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -6116,6 +7183,12 @@ } } }, + "timsort": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", + "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", + "dev": true + }, "tiny-lr": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-1.1.1.tgz", @@ -6354,6 +7427,12 @@ "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", "dev": true }, + "uniqs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", + "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", + "dev": true + }, "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -6445,6 +7524,12 @@ "homedir-polyfill": "^1.0.1" } }, + "vendors": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz", + "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==", + "dev": true + }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", @@ -6979,6 +8064,12 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true + }, "yargs": { "version": "17.0.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.0.1.tgz", diff --git a/static/package.json b/static/package.json index 369d118da..401bfbeba 100644 --- a/static/package.json +++ b/static/package.json @@ -44,12 +44,10 @@ "webpack-merge": "^5.7.3" }, "dependencies": { - "bootstrap-sass": "^3.4.1", "comment-json": "^3.0.2", "core-js": "^3.6.5", "css-vars-ponyfill": "^2.3.1", "file-system": "^2.2.2", - "font-awesome": "^4.7.0", "fs-extra": "^8.1.0", "iframe-resizer": "^4.1.1", "is-mobile": "^2.2.2", diff --git a/static/scss/answers/vendor.scss b/static/scss/answers/vendor.scss deleted file mode 100644 index 9217d9ac2..000000000 --- a/static/scss/answers/vendor.scss +++ /dev/null @@ -1,2 +0,0 @@ -@import "~bootstrap-sass/assets/stylesheets/bootstrap/variables"; -@import "~bootstrap-sass/assets/stylesheets/bootstrap/mixins"; From 44c39d1b23227b01784973f76e2ef6f883ce564e Mon Sep 17 00:00:00 2001 From: Oliver Shi Date: Fri, 28 May 2021 11:02:15 -0400 Subject: [PATCH 20/56] fix google streetview man being invisible (#801) Mr. Pegman was being covered up due to our css reset setting his max-height to 100%, which happened to be 0 due to how the google maps js works. This commit adds a css override on top of that. I wanted to remove the actual line of the css reset causing this behavior, however it's likely that removing that line would cause ripples throughout the html-css continuum. T=409037 TEST=manual, auto see mr. pegman again add a percy snapshot for him --- static/scss/answers/templates/vertical-map.scss | 4 ++++ test-site/config-overrides/locations_google.json | 9 +++++++++ test-site/scripts/create-verticals.js | 5 +++++ tests/percy/photographer.js | 5 ++++- 4 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 test-site/config-overrides/locations_google.json diff --git a/static/scss/answers/templates/vertical-map.scss b/static/scss/answers/templates/vertical-map.scss index 2a04965b5..7a4f4452d 100644 --- a/static/scss/answers/templates/vertical-map.scss +++ b/static/scss/answers/templates/vertical-map.scss @@ -92,6 +92,10 @@ min-height: 950px; border-left: var(--yxt-border-default); + img { + max-height: none; + } + @include bplte(xs) { display: none; diff --git a/test-site/config-overrides/locations_google.json b/test-site/config-overrides/locations_google.json new file mode 100644 index 000000000..e9acb6d9f --- /dev/null +++ b/test-site/config-overrides/locations_google.json @@ -0,0 +1,9 @@ +{ + "verticalsToConfig": { + "KM": { + "mapConfig": { + "mapProvider": "Google" + } + } + } +} \ No newline at end of file diff --git a/test-site/scripts/create-verticals.js b/test-site/scripts/create-verticals.js index e14df49f3..6f6249b33 100644 --- a/test-site/scripts/create-verticals.js +++ b/test-site/scripts/create-verticals.js @@ -20,6 +20,11 @@ const verticalConfiguration = { template: 'vertical-map', cardName: 'location-standard' }, + locations_google: { + verticalKey: 'KM', + template: 'vertical-map', + cardName: 'location-standard' + }, locations_full_page_map: { verticalKey: 'KM', template: 'vertical-full-page-map', diff --git a/tests/percy/photographer.js b/tests/percy/photographer.js index ee5f50e44..66889cf22 100644 --- a/tests/percy/photographer.js +++ b/tests/percy/photographer.js @@ -57,8 +57,11 @@ class Photographer { async _captureVerticalMapSearch () { await this._pageNavigator.gotoVerticalPage('locations', { query: 'a' }); await this._camera.snapshot('vertical-map-search'); + + await this._pageNavigator.gotoVerticalPage('locations_google', { query: 'virginia' }); + await this._camera.snapshot('vertical-map-search--google'); } - + async _captureVerticalFullPageMapSearch () { await this._pageNavigator .gotoVerticalPage('locations_full_page_map', { query: '' }); From c03b0e4a20fbc356d747d5eb8c75433cf32139fe Mon Sep 17 00:00:00 2001 From: Oliver Shi Date: Fri, 28 May 2021 16:25:25 -0400 Subject: [PATCH 21/56] add static placeholders for the searchbar and nav components (#797) This component adds static html placeholders for the searchbar and nav components, which will be displayed prior to the SDK loading and components being added to the page. Also adds the `Answers-navigation` css class to navigation markup templates that were missing it and the `js-answersSearchBar` id to all searchbar markup templates that were missing it. J=SLAP-1336 TEST=manual see that on each of the 5 page templates, the searchbar and nav placeholders will display for a brief second before the page finishes loading --- .../universal-standard/markup/navigation.hbs | 20 ++++++++++++++++++- .../universal-standard/markup/searchbar.hbs | 15 +++++++++++++- .../universal-standard/script/navigation.hbs | 5 ++++- .../universal-standard/script/searchbar.hbs | 3 +++ .../markup/navigation.hbs | 20 ++++++++++++++++++- .../markup/searchbar.hbs | 15 +++++++++++++- .../script/navigation.hbs | 5 ++++- .../script/searchbar.hbs | 3 +++ templates/vertical-grid/markup/navigation.hbs | 20 ++++++++++++++++++- templates/vertical-grid/markup/searchbar.hbs | 15 +++++++++++++- templates/vertical-grid/script/navigation.hbs | 5 ++++- templates/vertical-grid/script/searchbar.hbs | 3 +++ templates/vertical-map/markup/navigation.hbs | 20 ++++++++++++++++++- templates/vertical-map/markup/searchbar.hbs | 15 +++++++++++++- templates/vertical-map/script/navigation.hbs | 5 ++++- templates/vertical-map/script/searchbar.hbs | 3 +++ .../vertical-standard/markup/navigation.hbs | 20 ++++++++++++++++++- .../vertical-standard/markup/searchbar.hbs | 15 +++++++++++++- .../vertical-standard/script/navigation.hbs | 5 ++++- .../vertical-standard/script/searchbar.hbs | 3 +++ 20 files changed, 200 insertions(+), 15 deletions(-) diff --git a/templates/universal-standard/markup/navigation.hbs b/templates/universal-standard/markup/navigation.hbs index 9c2e1b6b6..2dba42714 100644 --- a/templates/universal-standard/markup/navigation.hbs +++ b/templates/universal-standard/markup/navigation.hbs @@ -1 +1,19 @@ -
\ No newline at end of file +
+ +
\ No newline at end of file diff --git a/templates/universal-standard/markup/searchbar.hbs b/templates/universal-standard/markup/searchbar.hbs index 601076ab4..e639b87d7 100644 --- a/templates/universal-standard/markup/searchbar.hbs +++ b/templates/universal-standard/markup/searchbar.hbs @@ -1 +1,14 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/templates/universal-standard/script/navigation.hbs b/templates/universal-standard/script/navigation.hbs index 348fe0cd5..002182e7b 100644 --- a/templates/universal-standard/script/navigation.hbs +++ b/templates/universal-standard/script/navigation.hbs @@ -39,7 +39,10 @@ verticalPages: [ }{{#unless @last}},{{/unless}} {{/if}} {{/each}} -] +], +onCreate: function() { + this._container.textContent = ''; +} }, {{{ json componentSettings.Navigation }}})); {{!-- diff --git a/templates/universal-standard/script/searchbar.hbs b/templates/universal-standard/script/searchbar.hbs index 35a262ad8..3368c73ac 100644 --- a/templates/universal-standard/script/searchbar.hbs +++ b/templates/universal-standard/script/searchbar.hbs @@ -24,4 +24,7 @@ const shouldAddOverlayConfig = window.isOverlay && document.querySelector('.js-A ANSWERS.addComponent("SearchBar", Object.assign({}, { container: ".js-answersSearch", ...(shouldAddOverlayConfig ? overlayConfig : {}), + onCreate: function() { + this._container.textContent = ''; + } }, {{{ json componentSettings.SearchBar }}})); \ No newline at end of file diff --git a/templates/vertical-full-page-map/markup/navigation.hbs b/templates/vertical-full-page-map/markup/navigation.hbs index 1b04f675d..2dba42714 100644 --- a/templates/vertical-full-page-map/markup/navigation.hbs +++ b/templates/vertical-full-page-map/markup/navigation.hbs @@ -1 +1,19 @@ -
\ No newline at end of file +
+ +
\ No newline at end of file diff --git a/templates/vertical-full-page-map/markup/searchbar.hbs b/templates/vertical-full-page-map/markup/searchbar.hbs index 9bd9ac070..e639b87d7 100644 --- a/templates/vertical-full-page-map/markup/searchbar.hbs +++ b/templates/vertical-full-page-map/markup/searchbar.hbs @@ -1 +1,14 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/templates/vertical-full-page-map/script/navigation.hbs b/templates/vertical-full-page-map/script/navigation.hbs index 1af27da3e..292b2f92a 100644 --- a/templates/vertical-full-page-map/script/navigation.hbs +++ b/templates/vertical-full-page-map/script/navigation.hbs @@ -39,7 +39,10 @@ verticalPages: [ }{{#unless @last}},{{/unless}} {{/if}} {{/each}} -] +], +onCreate: function() { + this._container.textContent = ''; +} }, {{{ json componentSettings.Navigation }}})); {{!-- diff --git a/templates/vertical-full-page-map/script/searchbar.hbs b/templates/vertical-full-page-map/script/searchbar.hbs index 97e49dad4..892e426b6 100644 --- a/templates/vertical-full-page-map/script/searchbar.hbs +++ b/templates/vertical-full-page-map/script/searchbar.hbs @@ -27,4 +27,7 @@ ANSWERS.addComponent("SearchBar", Object.assign({}, { verticalKey: "{{{verticalKey}}}", {{/if}} ...(shouldAddOverlayConfig ? overlayConfig : {}), + onCreate: function() { + this._container.textContent = ''; + } }, {{{ json componentSettings.SearchBar }}})); \ No newline at end of file diff --git a/templates/vertical-grid/markup/navigation.hbs b/templates/vertical-grid/markup/navigation.hbs index 9c2e1b6b6..2dba42714 100644 --- a/templates/vertical-grid/markup/navigation.hbs +++ b/templates/vertical-grid/markup/navigation.hbs @@ -1 +1,19 @@ -
\ No newline at end of file +
+ +
\ No newline at end of file diff --git a/templates/vertical-grid/markup/searchbar.hbs b/templates/vertical-grid/markup/searchbar.hbs index 601076ab4..e639b87d7 100644 --- a/templates/vertical-grid/markup/searchbar.hbs +++ b/templates/vertical-grid/markup/searchbar.hbs @@ -1 +1,14 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/templates/vertical-grid/script/navigation.hbs b/templates/vertical-grid/script/navigation.hbs index 7f3397ba1..152c75557 100644 --- a/templates/vertical-grid/script/navigation.hbs +++ b/templates/vertical-grid/script/navigation.hbs @@ -39,7 +39,10 @@ verticalPages: [ }{{#unless @last}},{{/unless}} {{/if}} {{/each}} -] +], +onCreate: function() { + this._container.textContent = ''; +} }, {{{ json componentSettings.Navigation }}})); {{!-- diff --git a/templates/vertical-grid/script/searchbar.hbs b/templates/vertical-grid/script/searchbar.hbs index 97e49dad4..892e426b6 100644 --- a/templates/vertical-grid/script/searchbar.hbs +++ b/templates/vertical-grid/script/searchbar.hbs @@ -27,4 +27,7 @@ ANSWERS.addComponent("SearchBar", Object.assign({}, { verticalKey: "{{{verticalKey}}}", {{/if}} ...(shouldAddOverlayConfig ? overlayConfig : {}), + onCreate: function() { + this._container.textContent = ''; + } }, {{{ json componentSettings.SearchBar }}})); \ No newline at end of file diff --git a/templates/vertical-map/markup/navigation.hbs b/templates/vertical-map/markup/navigation.hbs index 1b04f675d..2dba42714 100644 --- a/templates/vertical-map/markup/navigation.hbs +++ b/templates/vertical-map/markup/navigation.hbs @@ -1 +1,19 @@ -
\ No newline at end of file +
+ +
\ No newline at end of file diff --git a/templates/vertical-map/markup/searchbar.hbs b/templates/vertical-map/markup/searchbar.hbs index 9bd9ac070..e639b87d7 100644 --- a/templates/vertical-map/markup/searchbar.hbs +++ b/templates/vertical-map/markup/searchbar.hbs @@ -1 +1,14 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/templates/vertical-map/script/navigation.hbs b/templates/vertical-map/script/navigation.hbs index 1af27da3e..292b2f92a 100644 --- a/templates/vertical-map/script/navigation.hbs +++ b/templates/vertical-map/script/navigation.hbs @@ -39,7 +39,10 @@ verticalPages: [ }{{#unless @last}},{{/unless}} {{/if}} {{/each}} -] +], +onCreate: function() { + this._container.textContent = ''; +} }, {{{ json componentSettings.Navigation }}})); {{!-- diff --git a/templates/vertical-map/script/searchbar.hbs b/templates/vertical-map/script/searchbar.hbs index 97e49dad4..892e426b6 100644 --- a/templates/vertical-map/script/searchbar.hbs +++ b/templates/vertical-map/script/searchbar.hbs @@ -27,4 +27,7 @@ ANSWERS.addComponent("SearchBar", Object.assign({}, { verticalKey: "{{{verticalKey}}}", {{/if}} ...(shouldAddOverlayConfig ? overlayConfig : {}), + onCreate: function() { + this._container.textContent = ''; + } }, {{{ json componentSettings.SearchBar }}})); \ No newline at end of file diff --git a/templates/vertical-standard/markup/navigation.hbs b/templates/vertical-standard/markup/navigation.hbs index 9c2e1b6b6..2dba42714 100644 --- a/templates/vertical-standard/markup/navigation.hbs +++ b/templates/vertical-standard/markup/navigation.hbs @@ -1 +1,19 @@ -
\ No newline at end of file +
+ +
\ No newline at end of file diff --git a/templates/vertical-standard/markup/searchbar.hbs b/templates/vertical-standard/markup/searchbar.hbs index 9bd9ac070..e639b87d7 100644 --- a/templates/vertical-standard/markup/searchbar.hbs +++ b/templates/vertical-standard/markup/searchbar.hbs @@ -1 +1,14 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/templates/vertical-standard/script/navigation.hbs b/templates/vertical-standard/script/navigation.hbs index 7f3397ba1..152c75557 100644 --- a/templates/vertical-standard/script/navigation.hbs +++ b/templates/vertical-standard/script/navigation.hbs @@ -39,7 +39,10 @@ verticalPages: [ }{{#unless @last}},{{/unless}} {{/if}} {{/each}} -] +], +onCreate: function() { + this._container.textContent = ''; +} }, {{{ json componentSettings.Navigation }}})); {{!-- diff --git a/templates/vertical-standard/script/searchbar.hbs b/templates/vertical-standard/script/searchbar.hbs index 97e49dad4..892e426b6 100644 --- a/templates/vertical-standard/script/searchbar.hbs +++ b/templates/vertical-standard/script/searchbar.hbs @@ -27,4 +27,7 @@ ANSWERS.addComponent("SearchBar", Object.assign({}, { verticalKey: "{{{verticalKey}}}", {{/if}} ...(shouldAddOverlayConfig ? overlayConfig : {}), + onCreate: function() { + this._container.textContent = ''; + } }, {{{ json componentSettings.SearchBar }}})); \ No newline at end of file From b77e9f28e82124c83672cb00004bb8ec9196591f Mon Sep 17 00:00:00 2001 From: Oliver Shi Date: Tue, 1 Jun 2021 12:02:59 -0400 Subject: [PATCH 22/56] fix google streetview pegman on universal (#805) A previous commit fixed this on the vertical-map page template. We also need a fix for the map on universal, which also uses the SDK's map component. T=409037 TEST=manual, auto see mr.pegman on universal update the test-site's universal config to display a google maps component --- static/scss/answers/universalsectiontemplates/common.scss | 4 ++++ test-site/config/index.json | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/static/scss/answers/universalsectiontemplates/common.scss b/static/scss/answers/universalsectiontemplates/common.scss index c2312ced1..4536877c7 100644 --- a/static/scss/answers/universalsectiontemplates/common.scss +++ b/static/scss/answers/universalsectiontemplates/common.scss @@ -33,6 +33,10 @@ { height: 300px; border-bottom: var(--yxt-border-default); + + img { + max-height: none; + } } &-items { diff --git a/test-site/config/index.json b/test-site/config/index.json index 06d8cbe22..2a5bebc5e 100644 --- a/test-site/config/index.json +++ b/test-site/config/index.json @@ -36,7 +36,10 @@ }, "KM": { "universalSectionTemplate": "grid-two-columns", - "cardType": "multilang-financial-professional-location" + "cardType": "multilang-financial-professional-location", + "mapConfig": { + "mapProvider": "Google" + } } } } \ No newline at end of file From 911d215a10fa25eac41c71d97e192aecb8db1e4c Mon Sep 17 00:00:00 2001 From: Oliver Shi Date: Fri, 4 Jun 2021 15:11:57 -0400 Subject: [PATCH 23/56] fix PinImages and ClusterPinImages not changing pin size (#807) One of the requirements of the vertical-full-page-map is that users can jambo override the PinImages and ClusterPinImages files in order to change the pin size. @rosiegrant says that this was tested at some point, and since none of this code has been changed since the initial 8000+ line full page map commit, it's likely this was dropped somewhere during prototyping. Talked with @rosiegrant about the interface change. J=TECHOPS-603 TEST=manual see that I can resize both the regular pin and the cluster pin, on both chrome and ie11, for both google and mapbox check that the default pin/cluster pin sizes did not change before and after this commit check that pinCount is passed to propertiesForStatus correctly --- static/js/theme-map/ClusterPinImages.js | 28 ++++++++--------- .../js/theme-map/PinClusterer/PinClusterer.js | 2 +- static/js/theme-map/PinImages.js | 30 +++++++++--------- static/js/theme-map/ThemeMap.js | 31 ++++++++++--------- 4 files changed, 47 insertions(+), 44 deletions(-) diff --git a/static/js/theme-map/ClusterPinImages.js b/static/js/theme-map/ClusterPinImages.js index a82feaaec..1d0405d8d 100644 --- a/static/js/theme-map/ClusterPinImages.js +++ b/static/js/theme-map/ClusterPinImages.js @@ -20,20 +20,20 @@ class ClusterPinImages { * @param {string} pin.backgroundColor Background color for the pin * @param {string} pin.strokeColor Stroke (border) color for the pin * @param {string} pin.labelColor Label (text) color for the pin - * @param {string} pin.width The width of the pin - * @param {string} pin.height The height of the pin + * @param {number} pin.width The width of the pin + * @param {number} pin.height The height of the pin * @param {string} pin.labelText The label text for the cluster pin (normally size of cluster) - * @return string The SVG of the pin + * @return {Object} The SVG of the pin, and its width and height */ generatePin ({ backgroundColor = '#00759e', strokeColor = 'black', labelColor = 'white', - width = '24px', - height= '24px', + width = 24, + height= 24, labelText = '' } = {}) { - return ` + const svg = ` @@ -41,8 +41,8 @@ class ClusterPinImages { ${labelText} - - `; + `; + return { svg, width, height }; }; /** @@ -55,8 +55,8 @@ class ClusterPinImages { backgroundColor: this.defaultPinConfig.backgroundColor, strokeColor: this.defaultPinConfig.strokeColor, labelColor: this.defaultPinConfig.labelColor, - width: '24px', - height: '24px', + width: 24, + height: 24, labelText: pinCount, }); } @@ -71,8 +71,8 @@ class ClusterPinImages { backgroundColor: this.hoveredPinConfig.backgroundColor, strokeColor: this.hoveredPinConfig.strokeColor, labelColor: this.hoveredPinConfig.labelColor, - width: '24px', - height: '24px', + width: 24, + height: 24, labelText: pinCount, }); } @@ -87,8 +87,8 @@ class ClusterPinImages { backgroundColor: this.selectedPinConfig.backgroundColor, strokeColor: this.selectedPinConfig.strokeColor, labelColor: this.selectedPinConfig.labelColor, - width: '24px', - height: '24px', + width: 24, + height: 24, labelText: pinCount, }); } diff --git a/static/js/theme-map/PinClusterer/PinClusterer.js b/static/js/theme-map/PinClusterer/PinClusterer.js index 67d5e5b3c..5caf83119 100644 --- a/static/js/theme-map/PinClusterer/PinClusterer.js +++ b/static/js/theme-map/PinClusterer/PinClusterer.js @@ -342,7 +342,7 @@ class PinClusterer { const pinOptions = this._map.newPinOptions() .withCoordinate(GeoBounds.fit(coordinates).getCenter(this._mapProjection)) .withHideOffscreen(this._hideOffscreen) - .withPropertiesForStatus(this._propertiesForStatus); + .withPropertiesForStatus(status => this._propertiesForStatus(status, pinCluster.length)); // Build cluster icon(s) from template for (const [icon, template] of Object.entries(this._iconTemplates)) { diff --git a/static/js/theme-map/PinImages.js b/static/js/theme-map/PinImages.js index c49739177..f56f15379 100644 --- a/static/js/theme-map/PinImages.js +++ b/static/js/theme-map/PinImages.js @@ -20,22 +20,22 @@ class PinImages { * @param {string} pin.backgroundColor Background color for the pin * @param {string} pin.strokeColor Stroke (border) color for the pin * @param {string} pin.labelColor Label (text) color for the pin - * @param {string} pin.width The width of the pin - * @param {string} pin.height The height of the pin + * @param {number} pin.width The width of the pin + * @param {number} pin.height The height of the pin * @param {string} pin.pinCount The index of the pin for the pin text - * @return string The SVG of the pin + * @return {Object} The SVG of the pin, and its width and height */ generatePin ({ backgroundColor = '#00759e', strokeColor = 'black', labelColor = 'white', - width = '20px', - height= '27px', + width = 20, + height= 27, index = '', profile = '' } = {}) { - return ` - + const svg = ` + Path @@ -46,8 +46,8 @@ class PinImages { ${index} - - `; + `; + return { svg, width, height }; }; /** @@ -60,8 +60,8 @@ class PinImages { backgroundColor: this.defaultPinConfig.backgroundColor, strokeColor: this.defaultPinConfig.strokeColor, labelColor: this.defaultPinConfig.labelColor, - width: '24', - height: '28', + width: 24, + height: 28, index: '', profile: profile }); @@ -77,8 +77,8 @@ class PinImages { backgroundColor: this.hoveredPinConfig.backgroundColor, strokeColor: this.hoveredPinConfig.strokeColor, labelColor: this.hoveredPinConfig.labelColor, - width: '24', - height: '34', + width: 24, + height: 34, index: '', profile: profile }); @@ -94,8 +94,8 @@ class PinImages { backgroundColor: this.selectedPinConfig.backgroundColor, strokeColor: this.selectedPinConfig.strokeColor, labelColor: this.selectedPinConfig.labelColor, - width: '24', - height: '34', + width: 24, + height: 34, index: '', profile: profile }); diff --git a/static/js/theme-map/ThemeMap.js b/static/js/theme-map/ThemeMap.js index 20c52cd2b..37347ce99 100644 --- a/static/js/theme-map/ThemeMap.js +++ b/static/js/theme-map/ThemeMap.js @@ -294,23 +294,23 @@ class ThemeMap extends ANSWERS.Component { this.config.pinClusterClickListener(); }) .withIconTemplate('default', (pinDetails) => { - return getEncodedSvg(this.config.pinClusterImages.getDefaultPin(pinDetails.pinCount)); + return getEncodedSvg(this.config.pinClusterImages.getDefaultPin(pinDetails.pinCount).svg); }) .withIconTemplate('hovered', (pinDetails) => { - return getEncodedSvg(this.config.pinClusterImages.getHoveredPin(pinDetails.pinCount)); + return getEncodedSvg(this.config.pinClusterImages.getHoveredPin(pinDetails.pinCount).svg); }) .withIconTemplate('selected', (pinDetails) => { - return getEncodedSvg(this.config.pinClusterImages.getSelectedPin(pinDetails.pinCount)); + return getEncodedSvg(this.config.pinClusterImages.getSelectedPin(pinDetails.pinCount).svg); }) - .withPropertiesForStatus(status => { + .withPropertiesForStatus((status, pinCount) => { + const defaultPin = this.config.pinClusterImages.getDefaultPin(pinCount); const properties = new PinProperties() .setIcon(status.hovered || status.focused || status.selected ? 'hovered' : 'default') - .setWidth(28) - .setHeight(28) + .setWidth(defaultPin.width) + .setHeight(defaultPin.height) .setAnchorX(this.config.pinClusterAnchors.anchorX) .setAnchorY(this.config.pinClusterAnchors.anchorY); - return properties; }) .withMinClusterSize(this.config.minClusterSize) @@ -328,17 +328,20 @@ class ThemeMap extends ANSWERS.Component { */ buildPin(pinOptions, entity, index) { const id = 'js-yl-' + entity.profile.meta.id; + const defaultPin = this.config.pinImages.getDefaultPin(index, entity.profile); + const hoveredPin = this.config.pinImages.getHoveredPin(index, entity.profile); + const selectedPin = this.config.pinImages.getSelectedPin(index, entity.profile); const pin = pinOptions .withId(id) .withIcon( 'default', - getEncodedSvg(this.config.pinImages.getDefaultPin(index, entity.profile))) + getEncodedSvg(defaultPin.svg)) .withIcon( 'hovered', - getEncodedSvg(this.config.pinImages.getHoveredPin(index, entity.profile))) + getEncodedSvg(hoveredPin.svg)) .withIcon( 'selected', - getEncodedSvg(this.config.pinImages.getSelectedPin(index, entity.profile))) + getEncodedSvg(selectedPin.svg)) .withHideOffscreen(false) .withCoordinate(new Coordinate(entity.profile.yextDisplayCoordinate)) .withPropertiesForStatus(status => { @@ -349,12 +352,12 @@ class ThemeMap extends ANSWERS.Component { .setAnchorX(this.config.pinAnchors.anchorX) .setAnchorY(this.config.pinAnchors.anchorY); - properties.setWidth(24); - properties.setHeight(28); + properties.setWidth(defaultPin.width); + properties.setHeight(defaultPin.height); if (status.selected) { - properties.setWidth(24); - properties.setHeight(34); + properties.setWidth(selectedPin.width); + properties.setHeight(selectedPin.height); } return properties; From b6408c559f9dec1666e6e082694f625264571efd Mon Sep 17 00:00:00 2001 From: cea2aj <42848445+cea2aj@users.noreply.github.com> Date: Mon, 7 Jun 2021 13:13:32 -0400 Subject: [PATCH 24/56] Visual tests for all cards (#820) Add visual tests to all of the cards J=SLAP-1361 TEST=visual Inspect Percy snapshots --- test-site/config/index.json | 12 ++++++- test-site/scripts/create-verticals.js | 35 ++++++++++++++++++ tests/percy/photographer.js | 52 ++++++++++++++++++++++----- 3 files changed, 89 insertions(+), 10 deletions(-) diff --git a/test-site/config/index.json b/test-site/config/index.json index 2a5bebc5e..b88c26b3d 100644 --- a/test-site/config/index.json +++ b/test-site/config/index.json @@ -36,10 +36,20 @@ }, "KM": { "universalSectionTemplate": "grid-two-columns", - "cardType": "multilang-financial-professional-location", + "cardType": "financial-professional-location", "mapConfig": { "mapProvider": "Google" } + }, + "products": { + "universalSectionTemplate": "grid-three-columns", + "cardType": "product-prominentimage" + }, + "links": { + "cardType": "link-standard" + }, + "healthcare_professionals": { + "cardType": "professional-location" } } } \ No newline at end of file diff --git a/test-site/scripts/create-verticals.js b/test-site/scripts/create-verticals.js index 6f6249b33..4dcdd4172 100644 --- a/test-site/scripts/create-verticals.js +++ b/test-site/scripts/create-verticals.js @@ -39,6 +39,41 @@ const verticalConfiguration = { verticalKey: 'people', template: 'vertical-grid', cardName: 'standard' + }, + products: { + verticalKey: 'products', + template: 'vertical-grid', + cardName: 'multilang-product-prominentvideo' + }, + products_clickable_image: { + verticalKey: 'products', + template: 'vertical-grid', + cardName: 'product-prominentimage-clickable' + }, + financial_professionals: { + verticalKey: 'financial_professionals', + template: 'vertical-standard', + cardName: 'financial-professional-location' + }, + healthcare_professionals: { + verticalKey: 'healthcare_professionals', + template: 'vertical-grid', + cardName: 'professional-standard' + }, + jobs: { + verticalKey: 'jobs', + template: 'vertical-standard', + cardName: 'job-standard' + }, + help_articles: { + verticalKey: 'help_articles', + template: 'vertical-standard', + cardName: 'document-standard' + }, + menu_items: { + verticalKey: 'menu_items', + template: 'vertical-grid', + cardName: 'menuitem-standard' } }; diff --git a/tests/percy/photographer.js b/tests/percy/photographer.js index 66889cf22..c8a14cae5 100644 --- a/tests/percy/photographer.js +++ b/tests/percy/photographer.js @@ -17,33 +17,53 @@ class Photographer { } async captureSnapshots() { - await this._captureHomepage(); await this._captureUniversalSearch(); await this._captureVerticalSearch(); await this._captureVerticalGridSearch(); await this._captureVerticalMapSearch(); await this._captureVerticalFullPageMapSearch(); - } - - async _captureHomepage () { - await this._pageNavigator.gotoUniversalPage(); - await this._camera.snapshot('homepage'); + await this._captureDirectAnswers(); } async _captureUniversalSearch () { - await this._pageNavigator.gotoUniversalPage({ query: 'a' }); + await this._pageNavigator.gotoUniversalPage(); await this._camera.snapshot('universal-search'); + await this._pageNavigator.gotoUniversalPage({ query: 'a' }); + await this._camera.snapshot('universal-search--no-results'); + await this._pageNavigator.gotoUniversalPage({ query: 'office sparce'}); await this._camera.snapshot('universal-search--spellcheck'); + + await this._pageNavigator.gotoUniversalPage({ query: 'what if i forget my password?'}); + await this._pageNavigator.click('.HitchhikerFaqAccordion-toggle') + await this._camera.snapshot('universal-search--faq-accordion'); + + await this._pageNavigator.gotoUniversalPage({ query: 'yext answers'}); + await this._camera.snapshot('universal-search--product-prominentimage'); } async _captureVerticalSearch () { - await this._pageNavigator.gotoVerticalPage('events', { query: 'a' }); + await this._pageNavigator.gotoVerticalPage('events'); await this._camera.snapshot('vertical-search'); - await this._pageNavigator.gotoVerticalPage('events',{ query: 'vrginia' }); + await this._pageNavigator.gotoVerticalPage('events', { query: 'a' }); + await this._camera.snapshot('vertical-search--no-results'); + + await this._pageNavigator.gotoVerticalPage('events', { query: 'vrginia' }); await this._camera.snapshot('vertical-search--spellcheck'); + + await this._pageNavigator.gotoVerticalPage('financial_professionals', { query: 'connor' }); + await this._camera.snapshot('vertical-search--financial-professional-location'); + + await this._pageNavigator.gotoVerticalPage('jobs', { query: 'job' }); + await this._camera.snapshot('vertical-search--job-standard'); + + await this._pageNavigator.gotoVerticalPage('help_articles', { query: 'slap chop' }); + await this._camera.snapshot('vertical-search--document-standard'); + + await this._pageNavigator.gotoVerticalPage('menu_items', { query: 'roll' }); + await this._camera.snapshot('vertical-search--menuitem-standard'); } async _captureVerticalGridSearch () { @@ -52,6 +72,12 @@ class Photographer { await this._pageNavigator.gotoVerticalPage('people', { query: 'vrginia' }); await this._camera.snapshot('vertical-grid-search--spellcheck'); + + await this._pageNavigator.gotoVerticalPage('products', { query: 'yext answers' }); + await this._camera.snapshot('vertical-grid-search--product-prominentvideo'); + + await this._pageNavigator.gotoVerticalPage('products_clickable_image', { query: 'yext answers' }); + await this._camera.snapshot('vertical-grid-search--product-prominentimage-clickable'); } async _captureVerticalMapSearch () { @@ -88,6 +114,14 @@ class Photographer { .gotoVerticalPage('locations_full_page_map_with_filters', { query: 'virginia' }); await this._camera.snapshotDesktopOnly('vertical-full-page-map-with-filters--nlp-filters__desktop-view'); } + + async _captureDirectAnswers () { + await this._pageNavigator.gotoUniversalPage({ query: 'bryan reed phone number' }); + await this._camera.snapshot('field-direct-answer'); + + await this._pageNavigator.gotoUniversalPage({ query: 'where was joe exotic born?' }); + await this._camera.snapshot('documentsearch-direct-answer') + } } module.exports = Photographer; \ No newline at end of file From 49be977b82186d0b73d8026e433f5e0d7ee4d52e Mon Sep 17 00:00:00 2001 From: Christopher Jiang Date: Mon, 7 Jun 2021 17:16:40 -0400 Subject: [PATCH 25/56] Created common partial for searchbar --- .../common-partials/markup/searchbar.hbs | 14 ++++++++ .../common-partials/script/searchbar.hbs | 33 ++++++++++++++++++ .../universal-standard/markup/searchbar.hbs | 15 +------- .../universal-standard/script/searchbar.hbs | 31 +---------------- .../markup/searchbar.hbs | 15 +------- .../script/searchbar.hbs | 34 +------------------ templates/vertical-grid/markup/searchbar.hbs | 15 +------- templates/vertical-grid/script/searchbar.hbs | 34 +------------------ templates/vertical-map/markup/searchbar.hbs | 15 +------- templates/vertical-map/script/searchbar.hbs | 34 +------------------ .../vertical-standard/markup/searchbar.hbs | 15 +------- .../vertical-standard/script/searchbar.hbs | 34 +------------------ 12 files changed, 57 insertions(+), 232 deletions(-) create mode 100644 templates/common-partials/markup/searchbar.hbs create mode 100644 templates/common-partials/script/searchbar.hbs diff --git a/templates/common-partials/markup/searchbar.hbs b/templates/common-partials/markup/searchbar.hbs new file mode 100644 index 000000000..e639b87d7 --- /dev/null +++ b/templates/common-partials/markup/searchbar.hbs @@ -0,0 +1,14 @@ + \ No newline at end of file diff --git a/templates/common-partials/script/searchbar.hbs b/templates/common-partials/script/searchbar.hbs new file mode 100644 index 000000000..892e426b6 --- /dev/null +++ b/templates/common-partials/script/searchbar.hbs @@ -0,0 +1,33 @@ +const overlayConfig = { + customHooks: { + onConductSearch: function (query) { + window.Overlay.grow(); + }, + onClearSearch: function () { + window.Overlay.shrink(); + } + }, + autocomplete: { + onOpen: function() { + const overlaySuggestionsEl = document.querySelector('.js-Answers-overlaySuggestions'); + overlaySuggestionsEl && overlaySuggestionsEl.classList.add('hidden'); + }, + onClose: function() { + const overlaySuggestionsEl = document.querySelector('.js-Answers-overlaySuggestions'); + overlaySuggestionsEl && overlaySuggestionsEl.classList.remove('hidden'); + }, + shouldHideOnEmptySearch: true + } +}; +const shouldAddOverlayConfig = window.isOverlay && document.querySelector('.js-Answers-overlaySuggestions'); + +ANSWERS.addComponent("SearchBar", Object.assign({}, { + container: ".js-answersSearch", + {{#if verticalKey}} + verticalKey: "{{{verticalKey}}}", + {{/if}} + ...(shouldAddOverlayConfig ? overlayConfig : {}), + onCreate: function() { + this._container.textContent = ''; + } +}, {{{ json componentSettings.SearchBar }}})); \ No newline at end of file diff --git a/templates/universal-standard/markup/searchbar.hbs b/templates/universal-standard/markup/searchbar.hbs index e639b87d7..09c64c469 100644 --- a/templates/universal-standard/markup/searchbar.hbs +++ b/templates/universal-standard/markup/searchbar.hbs @@ -1,14 +1 @@ - \ No newline at end of file +{{> templates/common-partials/markup/searchbar }} \ No newline at end of file diff --git a/templates/universal-standard/script/searchbar.hbs b/templates/universal-standard/script/searchbar.hbs index 3368c73ac..82ab74e19 100644 --- a/templates/universal-standard/script/searchbar.hbs +++ b/templates/universal-standard/script/searchbar.hbs @@ -1,30 +1 @@ -const overlayConfig = { - customHooks: { - onConductSearch: function (query) { - window.Overlay.grow(); - }, - onClearSearch: function () { - window.Overlay.shrink(); - } - }, - autocomplete: { - onOpen: function() { - const overlaySuggestionsEl = document.querySelector('.js-Answers-overlaySuggestions'); - overlaySuggestionsEl && overlaySuggestionsEl.classList.add('hidden'); - }, - onClose: function() { - const overlaySuggestionsEl = document.querySelector('.js-Answers-overlaySuggestions'); - overlaySuggestionsEl && overlaySuggestionsEl.classList.remove('hidden'); - }, - shouldHideOnEmptySearch: true - } -}; -const shouldAddOverlayConfig = window.isOverlay && document.querySelector('.js-Answers-overlaySuggestions'); - -ANSWERS.addComponent("SearchBar", Object.assign({}, { - container: ".js-answersSearch", - ...(shouldAddOverlayConfig ? overlayConfig : {}), - onCreate: function() { - this._container.textContent = ''; - } -}, {{{ json componentSettings.SearchBar }}})); \ No newline at end of file +{{> templates/common-partials/script/searchbar }} \ No newline at end of file diff --git a/templates/vertical-full-page-map/markup/searchbar.hbs b/templates/vertical-full-page-map/markup/searchbar.hbs index e639b87d7..09c64c469 100644 --- a/templates/vertical-full-page-map/markup/searchbar.hbs +++ b/templates/vertical-full-page-map/markup/searchbar.hbs @@ -1,14 +1 @@ - \ No newline at end of file +{{> templates/common-partials/markup/searchbar }} \ No newline at end of file diff --git a/templates/vertical-full-page-map/script/searchbar.hbs b/templates/vertical-full-page-map/script/searchbar.hbs index 892e426b6..82ab74e19 100644 --- a/templates/vertical-full-page-map/script/searchbar.hbs +++ b/templates/vertical-full-page-map/script/searchbar.hbs @@ -1,33 +1 @@ -const overlayConfig = { - customHooks: { - onConductSearch: function (query) { - window.Overlay.grow(); - }, - onClearSearch: function () { - window.Overlay.shrink(); - } - }, - autocomplete: { - onOpen: function() { - const overlaySuggestionsEl = document.querySelector('.js-Answers-overlaySuggestions'); - overlaySuggestionsEl && overlaySuggestionsEl.classList.add('hidden'); - }, - onClose: function() { - const overlaySuggestionsEl = document.querySelector('.js-Answers-overlaySuggestions'); - overlaySuggestionsEl && overlaySuggestionsEl.classList.remove('hidden'); - }, - shouldHideOnEmptySearch: true - } -}; -const shouldAddOverlayConfig = window.isOverlay && document.querySelector('.js-Answers-overlaySuggestions'); - -ANSWERS.addComponent("SearchBar", Object.assign({}, { - container: ".js-answersSearch", - {{#if verticalKey}} - verticalKey: "{{{verticalKey}}}", - {{/if}} - ...(shouldAddOverlayConfig ? overlayConfig : {}), - onCreate: function() { - this._container.textContent = ''; - } -}, {{{ json componentSettings.SearchBar }}})); \ No newline at end of file +{{> templates/common-partials/script/searchbar }} \ No newline at end of file diff --git a/templates/vertical-grid/markup/searchbar.hbs b/templates/vertical-grid/markup/searchbar.hbs index e639b87d7..09c64c469 100644 --- a/templates/vertical-grid/markup/searchbar.hbs +++ b/templates/vertical-grid/markup/searchbar.hbs @@ -1,14 +1 @@ - \ No newline at end of file +{{> templates/common-partials/markup/searchbar }} \ No newline at end of file diff --git a/templates/vertical-grid/script/searchbar.hbs b/templates/vertical-grid/script/searchbar.hbs index 892e426b6..82ab74e19 100644 --- a/templates/vertical-grid/script/searchbar.hbs +++ b/templates/vertical-grid/script/searchbar.hbs @@ -1,33 +1 @@ -const overlayConfig = { - customHooks: { - onConductSearch: function (query) { - window.Overlay.grow(); - }, - onClearSearch: function () { - window.Overlay.shrink(); - } - }, - autocomplete: { - onOpen: function() { - const overlaySuggestionsEl = document.querySelector('.js-Answers-overlaySuggestions'); - overlaySuggestionsEl && overlaySuggestionsEl.classList.add('hidden'); - }, - onClose: function() { - const overlaySuggestionsEl = document.querySelector('.js-Answers-overlaySuggestions'); - overlaySuggestionsEl && overlaySuggestionsEl.classList.remove('hidden'); - }, - shouldHideOnEmptySearch: true - } -}; -const shouldAddOverlayConfig = window.isOverlay && document.querySelector('.js-Answers-overlaySuggestions'); - -ANSWERS.addComponent("SearchBar", Object.assign({}, { - container: ".js-answersSearch", - {{#if verticalKey}} - verticalKey: "{{{verticalKey}}}", - {{/if}} - ...(shouldAddOverlayConfig ? overlayConfig : {}), - onCreate: function() { - this._container.textContent = ''; - } -}, {{{ json componentSettings.SearchBar }}})); \ No newline at end of file +{{> templates/common-partials/script/searchbar }} \ No newline at end of file diff --git a/templates/vertical-map/markup/searchbar.hbs b/templates/vertical-map/markup/searchbar.hbs index e639b87d7..09c64c469 100644 --- a/templates/vertical-map/markup/searchbar.hbs +++ b/templates/vertical-map/markup/searchbar.hbs @@ -1,14 +1 @@ - \ No newline at end of file +{{> templates/common-partials/markup/searchbar }} \ No newline at end of file diff --git a/templates/vertical-map/script/searchbar.hbs b/templates/vertical-map/script/searchbar.hbs index 892e426b6..82ab74e19 100644 --- a/templates/vertical-map/script/searchbar.hbs +++ b/templates/vertical-map/script/searchbar.hbs @@ -1,33 +1 @@ -const overlayConfig = { - customHooks: { - onConductSearch: function (query) { - window.Overlay.grow(); - }, - onClearSearch: function () { - window.Overlay.shrink(); - } - }, - autocomplete: { - onOpen: function() { - const overlaySuggestionsEl = document.querySelector('.js-Answers-overlaySuggestions'); - overlaySuggestionsEl && overlaySuggestionsEl.classList.add('hidden'); - }, - onClose: function() { - const overlaySuggestionsEl = document.querySelector('.js-Answers-overlaySuggestions'); - overlaySuggestionsEl && overlaySuggestionsEl.classList.remove('hidden'); - }, - shouldHideOnEmptySearch: true - } -}; -const shouldAddOverlayConfig = window.isOverlay && document.querySelector('.js-Answers-overlaySuggestions'); - -ANSWERS.addComponent("SearchBar", Object.assign({}, { - container: ".js-answersSearch", - {{#if verticalKey}} - verticalKey: "{{{verticalKey}}}", - {{/if}} - ...(shouldAddOverlayConfig ? overlayConfig : {}), - onCreate: function() { - this._container.textContent = ''; - } -}, {{{ json componentSettings.SearchBar }}})); \ No newline at end of file +{{> templates/common-partials/script/searchbar }} \ No newline at end of file diff --git a/templates/vertical-standard/markup/searchbar.hbs b/templates/vertical-standard/markup/searchbar.hbs index e639b87d7..09c64c469 100644 --- a/templates/vertical-standard/markup/searchbar.hbs +++ b/templates/vertical-standard/markup/searchbar.hbs @@ -1,14 +1 @@ - \ No newline at end of file +{{> templates/common-partials/markup/searchbar }} \ No newline at end of file diff --git a/templates/vertical-standard/script/searchbar.hbs b/templates/vertical-standard/script/searchbar.hbs index 892e426b6..82ab74e19 100644 --- a/templates/vertical-standard/script/searchbar.hbs +++ b/templates/vertical-standard/script/searchbar.hbs @@ -1,33 +1 @@ -const overlayConfig = { - customHooks: { - onConductSearch: function (query) { - window.Overlay.grow(); - }, - onClearSearch: function () { - window.Overlay.shrink(); - } - }, - autocomplete: { - onOpen: function() { - const overlaySuggestionsEl = document.querySelector('.js-Answers-overlaySuggestions'); - overlaySuggestionsEl && overlaySuggestionsEl.classList.add('hidden'); - }, - onClose: function() { - const overlaySuggestionsEl = document.querySelector('.js-Answers-overlaySuggestions'); - overlaySuggestionsEl && overlaySuggestionsEl.classList.remove('hidden'); - }, - shouldHideOnEmptySearch: true - } -}; -const shouldAddOverlayConfig = window.isOverlay && document.querySelector('.js-Answers-overlaySuggestions'); - -ANSWERS.addComponent("SearchBar", Object.assign({}, { - container: ".js-answersSearch", - {{#if verticalKey}} - verticalKey: "{{{verticalKey}}}", - {{/if}} - ...(shouldAddOverlayConfig ? overlayConfig : {}), - onCreate: function() { - this._container.textContent = ''; - } -}, {{{ json componentSettings.SearchBar }}})); \ No newline at end of file +{{> templates/common-partials/script/searchbar }} \ No newline at end of file From ca7f942b0e059b695e7061797cf311521eddd021 Mon Sep 17 00:00:00 2001 From: Christopher Jiang Date: Mon, 7 Jun 2021 17:38:41 -0400 Subject: [PATCH 26/56] Created common partial for navigation --- .../common-partials/markup/navigation.hbs | 19 ++++++ .../common-partials/script/navigation.hbs | 65 ++++++++++++++++++ .../universal-standard/markup/navigation.hbs | 20 +----- .../universal-standard/script/navigation.hbs | 65 +----------------- .../markup/navigation.hbs | 20 +----- .../script/navigation.hbs | 66 +------------------ templates/vertical-grid/markup/navigation.hbs | 20 +----- templates/vertical-grid/script/navigation.hbs | 66 +------------------ templates/vertical-map/markup/navigation.hbs | 20 +----- templates/vertical-map/script/navigation.hbs | 66 +------------------ .../vertical-standard/markup/navigation.hbs | 20 +----- .../vertical-standard/script/navigation.hbs | 66 +------------------ 12 files changed, 94 insertions(+), 419 deletions(-) create mode 100644 templates/common-partials/markup/navigation.hbs create mode 100644 templates/common-partials/script/navigation.hbs diff --git a/templates/common-partials/markup/navigation.hbs b/templates/common-partials/markup/navigation.hbs new file mode 100644 index 000000000..2dba42714 --- /dev/null +++ b/templates/common-partials/markup/navigation.hbs @@ -0,0 +1,19 @@ +
+ +
\ No newline at end of file diff --git a/templates/common-partials/script/navigation.hbs b/templates/common-partials/script/navigation.hbs new file mode 100644 index 000000000..292b2f92a --- /dev/null +++ b/templates/common-partials/script/navigation.hbs @@ -0,0 +1,65 @@ +ANSWERS.addComponent("Navigation", Object.assign({}, { +container: "#js-answersNavigation", +verticalPages: [ +{{#each verticalConfigs}} +{{#if (any verticalKey (lookup verticalsToConfig 'Universal'))}} + { + verticalKey: "{{{verticalKey}}}", + {{#each ../excludedVerticals}}{{#ifeq this ../verticalKey}}hideInNavigation: true,{{/ifeq}}{{/each}} + {{#ifeq ../verticalKey verticalKey}}isActive: true,{{/ifeq}} + {{#if verticalKey}} + {{#with (lookup verticalsToConfig verticalKey)}} + {{#if isFirst}}isFirst: {{isFirst}},{{/if}} + {{#if icon}}icon: "{{{icon}}}",{{/if}} + label: {{> verticalLabel overridedLabel=label verticalKey=../verticalKey fallback=@key}}, + url: + {{#if url}} + "{{{relativePathHandler url=url relativePath=@root.relativePath}}}", + {{else if ../url}} + "{{{relativePathHandler url=../url relativePath=@root.relativePath}}}", + {{else}} + "{{{@key}}}.html", + {{/if}} + {{/with}} + {{else}} + {{#with (lookup verticalsToConfig "Universal")}} + {{#if isFirst}}isFirst: {{isFirst}},{{/if}} + {{#if icon}}icon: "{{{icon}}}",{{/if}} + label: {{#if label}}"{{{label}}}"{{else}}"{{{@key}}}"{{/if}}, + url: + {{#if url}} + "{{{relativePathHandler url=url relativePath=@root.relativePath}}}", + {{else if ../url}} + "{{{relativePathHandler url=../url relativePath=@root.relativePath}}}", + {{else}} + "{{{@key}}}.html", + {{/if}} + {{/with}} + {{/if}} + }{{#unless @last}},{{/unless}} +{{/if}} +{{/each}} +], +onCreate: function() { + this._container.textContent = ''; +} +}, {{{ json componentSettings.Navigation }}})); + +{{!-- + Prints the vertical label according to specific logic + Assumes @root has environment variables and global_config + @param overridedLabel The hardcoded label from configuration in repo, meant to supercede defaults + @param verticalKey The current vertical key, if it exists + @param fallback The fallback for the label if all else doesn't exist +--}} +{{#*inline 'verticalLabel'}} + {{~#if overridedLabel ~}} + "{{{overridedLabel}}}" + {{~ else ~}} + HitchhikerJS.getInjectedProp( + "{{{@root.global_config.experienceKey}}}", + ["verticals", "{{{verticalKey}}}", "displayName"]) + {{~#if verticalKey ~}} || "{{{verticalKey}}}" {{~/if ~}} + {{~#if fallback ~}} || "{{{fallback}}}" {{~/if ~}} + {{~/if ~}} +{{/inline}} diff --git a/templates/universal-standard/markup/navigation.hbs b/templates/universal-standard/markup/navigation.hbs index 2dba42714..02dbb2959 100644 --- a/templates/universal-standard/markup/navigation.hbs +++ b/templates/universal-standard/markup/navigation.hbs @@ -1,19 +1 @@ -
- -
\ No newline at end of file +{{> templates/common-partials/markup/navigation }} \ No newline at end of file diff --git a/templates/universal-standard/script/navigation.hbs b/templates/universal-standard/script/navigation.hbs index 002182e7b..f9a3443fb 100644 --- a/templates/universal-standard/script/navigation.hbs +++ b/templates/universal-standard/script/navigation.hbs @@ -1,64 +1 @@ -ANSWERS.addComponent("Navigation", Object.assign({}, { -container: ".js-answersNavigation", -verticalPages: [ -{{#each verticalConfigs}} -{{#if (any verticalKey (lookup verticalsToConfig 'Universal'))}} - { - verticalKey: "{{{verticalKey}}}", - {{#each ../excludedVerticals}}{{#ifeq this ../verticalKey}}hideInNavigation: true,{{/ifeq}}{{/each}} - {{#ifeq ../verticalKey verticalKey}}isActive: true,{{/ifeq}} - {{#if verticalKey}} - {{#with (lookup verticalsToConfig verticalKey)}} - {{#if isFirst}}isFirst: {{isFirst}},{{/if}} - {{#if icon}}icon: "{{{icon}}}",{{/if}} - label: {{> verticalLabel overridedLabel=label verticalKey=../verticalKey fallback=@key}}, - url: - {{#if url}} - "{{{relativePathHandler url=url relativePath=@root.relativePath}}}", - {{else if ../url}} - "{{{relativePathHandler url=../url relativePath=@root.relativePath}}}", - {{else}} - "{{{@key}}}.html", - {{/if}} - {{/with}} - {{else}} - {{#with (lookup verticalsToConfig "Universal")}} - {{#if isFirst}}isFirst: {{isFirst}},{{/if}} - {{#if icon}}icon: "{{{icon}}}",{{/if}} - label: {{#if label}}"{{{label}}}"{{else}}"{{{@key}}}"{{/if}}, - url: - {{#if url}} - "{{{relativePathHandler url=url relativePath=@root.relativePath}}}", - {{else if ../url}} - "{{{relativePathHandler url=../url relativePath=@root.relativePath}}}", - {{else}} - "{{{@key}}}.html", - {{/if}} - {{/with}} - {{/if}} - }{{#unless @last}},{{/unless}} -{{/if}} -{{/each}} -], -onCreate: function() { - this._container.textContent = ''; -} -}, {{{ json componentSettings.Navigation }}})); - -{{!-- - Prints the vertical label according to specific logic - Assumes @root has environment variables and global_config - @param overridedLabel The hardcoded label from configuration in repo, meant to supercede defaults - @param verticalKey The current vertical key, if it exists - @param fallback The fallback for the label if all else doesn't exist ---}} -{{#*inline 'verticalLabel'}} - {{~#if overridedLabel ~}} - "{{{overridedLabel}}}" - {{~ else ~}} - HitchhikerJS.getInjectedProp( - "{{{@root.global_config.experienceKey}}}", - ["verticals", "{{{verticalKey}}}", "displayName"]) - || "{{{verticalKey}}}" || "{{{fallback}}}" - {{~/if ~}} -{{/inline}} +{{> templates/common-partials/script/navigation }} \ No newline at end of file diff --git a/templates/vertical-full-page-map/markup/navigation.hbs b/templates/vertical-full-page-map/markup/navigation.hbs index 2dba42714..02dbb2959 100644 --- a/templates/vertical-full-page-map/markup/navigation.hbs +++ b/templates/vertical-full-page-map/markup/navigation.hbs @@ -1,19 +1 @@ -
- -
\ No newline at end of file +{{> templates/common-partials/markup/navigation }} \ No newline at end of file diff --git a/templates/vertical-full-page-map/script/navigation.hbs b/templates/vertical-full-page-map/script/navigation.hbs index 292b2f92a..f9a3443fb 100644 --- a/templates/vertical-full-page-map/script/navigation.hbs +++ b/templates/vertical-full-page-map/script/navigation.hbs @@ -1,65 +1 @@ -ANSWERS.addComponent("Navigation", Object.assign({}, { -container: "#js-answersNavigation", -verticalPages: [ -{{#each verticalConfigs}} -{{#if (any verticalKey (lookup verticalsToConfig 'Universal'))}} - { - verticalKey: "{{{verticalKey}}}", - {{#each ../excludedVerticals}}{{#ifeq this ../verticalKey}}hideInNavigation: true,{{/ifeq}}{{/each}} - {{#ifeq ../verticalKey verticalKey}}isActive: true,{{/ifeq}} - {{#if verticalKey}} - {{#with (lookup verticalsToConfig verticalKey)}} - {{#if isFirst}}isFirst: {{isFirst}},{{/if}} - {{#if icon}}icon: "{{{icon}}}",{{/if}} - label: {{> verticalLabel overridedLabel=label verticalKey=../verticalKey fallback=@key}}, - url: - {{#if url}} - "{{{relativePathHandler url=url relativePath=@root.relativePath}}}", - {{else if ../url}} - "{{{relativePathHandler url=../url relativePath=@root.relativePath}}}", - {{else}} - "{{{@key}}}.html", - {{/if}} - {{/with}} - {{else}} - {{#with (lookup verticalsToConfig "Universal")}} - {{#if isFirst}}isFirst: {{isFirst}},{{/if}} - {{#if icon}}icon: "{{{icon}}}",{{/if}} - label: {{#if label}}"{{{label}}}"{{else}}"{{{@key}}}"{{/if}}, - url: - {{#if url}} - "{{{relativePathHandler url=url relativePath=@root.relativePath}}}", - {{else if ../url}} - "{{{relativePathHandler url=../url relativePath=@root.relativePath}}}", - {{else}} - "{{{@key}}}.html", - {{/if}} - {{/with}} - {{/if}} - }{{#unless @last}},{{/unless}} -{{/if}} -{{/each}} -], -onCreate: function() { - this._container.textContent = ''; -} -}, {{{ json componentSettings.Navigation }}})); - -{{!-- - Prints the vertical label according to specific logic - Assumes @root has environment variables and global_config - @param overridedLabel The hardcoded label from configuration in repo, meant to supercede defaults - @param verticalKey The current vertical key, if it exists - @param fallback The fallback for the label if all else doesn't exist ---}} -{{#*inline 'verticalLabel'}} - {{~#if overridedLabel ~}} - "{{{overridedLabel}}}" - {{~ else ~}} - HitchhikerJS.getInjectedProp( - "{{{@root.global_config.experienceKey}}}", - ["verticals", "{{{verticalKey}}}", "displayName"]) - {{~#if verticalKey ~}} || "{{{verticalKey}}}" {{~/if ~}} - {{~#if fallback ~}} || "{{{fallback}}}" {{~/if ~}} - {{~/if ~}} -{{/inline}} +{{> templates/common-partials/script/navigation }} \ No newline at end of file diff --git a/templates/vertical-grid/markup/navigation.hbs b/templates/vertical-grid/markup/navigation.hbs index 2dba42714..02dbb2959 100644 --- a/templates/vertical-grid/markup/navigation.hbs +++ b/templates/vertical-grid/markup/navigation.hbs @@ -1,19 +1 @@ -
- -
\ No newline at end of file +{{> templates/common-partials/markup/navigation }} \ No newline at end of file diff --git a/templates/vertical-grid/script/navigation.hbs b/templates/vertical-grid/script/navigation.hbs index 152c75557..f9a3443fb 100644 --- a/templates/vertical-grid/script/navigation.hbs +++ b/templates/vertical-grid/script/navigation.hbs @@ -1,65 +1 @@ -ANSWERS.addComponent("Navigation", Object.assign({}, { -container: ".js-answersNavigation", -verticalPages: [ -{{#each verticalConfigs}} -{{#if (any verticalKey (lookup verticalsToConfig 'Universal'))}} - { - verticalKey: "{{{verticalKey}}}", - {{#each ../excludedVerticals}}{{#ifeq this ../verticalKey}}hideInNavigation: true,{{/ifeq}}{{/each}} - {{#ifeq ../verticalKey verticalKey}}isActive: true,{{/ifeq}} - {{#if verticalKey}} - {{#with (lookup verticalsToConfig verticalKey)}} - {{#if isFirst}}isFirst: {{isFirst}},{{/if}} - {{#if icon}}icon: "{{{icon}}}",{{/if}} - label: {{> verticalLabel overridedLabel=label verticalKey=../verticalKey fallback=@key}}, - url: - {{#if url}} - "{{{relativePathHandler url=url relativePath=@root.relativePath}}}", - {{else if ../url}} - "{{{relativePathHandler url=../url relativePath=@root.relativePath}}}", - {{else}} - "{{{@key}}}.html", - {{/if}} - {{/with}} - {{else}} - {{#with (lookup verticalsToConfig "Universal")}} - {{#if isFirst}}isFirst: {{isFirst}},{{/if}} - {{#if icon}}icon: "{{{icon}}}",{{/if}} - label: {{#if label}}"{{{label}}}"{{else}}"{{{@key}}}"{{/if}}, - url: - {{#if url}} - "{{{relativePathHandler url=url relativePath=@root.relativePath}}}", - {{else if ../url}} - "{{{relativePathHandler url=../url relativePath=@root.relativePath}}}", - {{else}} - "{{{@key}}}.html", - {{/if}} - {{/with}} - {{/if}} - }{{#unless @last}},{{/unless}} -{{/if}} -{{/each}} -], -onCreate: function() { - this._container.textContent = ''; -} -}, {{{ json componentSettings.Navigation }}})); - -{{!-- - Prints the vertical label according to specific logic - Assumes @root has environment variables and global_config - @param overridedLabel The hardcoded label from configuration in repo, meant to supercede defaults - @param verticalKey The current vertical key, if it exists - @param fallback The fallback for the label if all else doesn't exist ---}} -{{#*inline 'verticalLabel'}} - {{~#if overridedLabel ~}} - "{{{overridedLabel}}}" - {{~ else ~}} - HitchhikerJS.getInjectedProp( - "{{{@root.global_config.experienceKey}}}", - ["verticals", "{{{verticalKey}}}", "displayName"]) - {{~#if verticalKey ~}} || "{{{verticalKey}}}" {{~/if ~}} - {{~#if fallback ~}} || "{{{fallback}}}" {{~/if ~}} - {{~/if ~}} -{{/inline}} +{{> templates/common-partials/script/navigation }} \ No newline at end of file diff --git a/templates/vertical-map/markup/navigation.hbs b/templates/vertical-map/markup/navigation.hbs index 2dba42714..02dbb2959 100644 --- a/templates/vertical-map/markup/navigation.hbs +++ b/templates/vertical-map/markup/navigation.hbs @@ -1,19 +1 @@ -
- -
\ No newline at end of file +{{> templates/common-partials/markup/navigation }} \ No newline at end of file diff --git a/templates/vertical-map/script/navigation.hbs b/templates/vertical-map/script/navigation.hbs index 292b2f92a..f9a3443fb 100644 --- a/templates/vertical-map/script/navigation.hbs +++ b/templates/vertical-map/script/navigation.hbs @@ -1,65 +1 @@ -ANSWERS.addComponent("Navigation", Object.assign({}, { -container: "#js-answersNavigation", -verticalPages: [ -{{#each verticalConfigs}} -{{#if (any verticalKey (lookup verticalsToConfig 'Universal'))}} - { - verticalKey: "{{{verticalKey}}}", - {{#each ../excludedVerticals}}{{#ifeq this ../verticalKey}}hideInNavigation: true,{{/ifeq}}{{/each}} - {{#ifeq ../verticalKey verticalKey}}isActive: true,{{/ifeq}} - {{#if verticalKey}} - {{#with (lookup verticalsToConfig verticalKey)}} - {{#if isFirst}}isFirst: {{isFirst}},{{/if}} - {{#if icon}}icon: "{{{icon}}}",{{/if}} - label: {{> verticalLabel overridedLabel=label verticalKey=../verticalKey fallback=@key}}, - url: - {{#if url}} - "{{{relativePathHandler url=url relativePath=@root.relativePath}}}", - {{else if ../url}} - "{{{relativePathHandler url=../url relativePath=@root.relativePath}}}", - {{else}} - "{{{@key}}}.html", - {{/if}} - {{/with}} - {{else}} - {{#with (lookup verticalsToConfig "Universal")}} - {{#if isFirst}}isFirst: {{isFirst}},{{/if}} - {{#if icon}}icon: "{{{icon}}}",{{/if}} - label: {{#if label}}"{{{label}}}"{{else}}"{{{@key}}}"{{/if}}, - url: - {{#if url}} - "{{{relativePathHandler url=url relativePath=@root.relativePath}}}", - {{else if ../url}} - "{{{relativePathHandler url=../url relativePath=@root.relativePath}}}", - {{else}} - "{{{@key}}}.html", - {{/if}} - {{/with}} - {{/if}} - }{{#unless @last}},{{/unless}} -{{/if}} -{{/each}} -], -onCreate: function() { - this._container.textContent = ''; -} -}, {{{ json componentSettings.Navigation }}})); - -{{!-- - Prints the vertical label according to specific logic - Assumes @root has environment variables and global_config - @param overridedLabel The hardcoded label from configuration in repo, meant to supercede defaults - @param verticalKey The current vertical key, if it exists - @param fallback The fallback for the label if all else doesn't exist ---}} -{{#*inline 'verticalLabel'}} - {{~#if overridedLabel ~}} - "{{{overridedLabel}}}" - {{~ else ~}} - HitchhikerJS.getInjectedProp( - "{{{@root.global_config.experienceKey}}}", - ["verticals", "{{{verticalKey}}}", "displayName"]) - {{~#if verticalKey ~}} || "{{{verticalKey}}}" {{~/if ~}} - {{~#if fallback ~}} || "{{{fallback}}}" {{~/if ~}} - {{~/if ~}} -{{/inline}} +{{> templates/common-partials/script/navigation }} \ No newline at end of file diff --git a/templates/vertical-standard/markup/navigation.hbs b/templates/vertical-standard/markup/navigation.hbs index 2dba42714..02dbb2959 100644 --- a/templates/vertical-standard/markup/navigation.hbs +++ b/templates/vertical-standard/markup/navigation.hbs @@ -1,19 +1 @@ -
- -
\ No newline at end of file +{{> templates/common-partials/markup/navigation }} \ No newline at end of file diff --git a/templates/vertical-standard/script/navigation.hbs b/templates/vertical-standard/script/navigation.hbs index 152c75557..f9a3443fb 100644 --- a/templates/vertical-standard/script/navigation.hbs +++ b/templates/vertical-standard/script/navigation.hbs @@ -1,65 +1 @@ -ANSWERS.addComponent("Navigation", Object.assign({}, { -container: ".js-answersNavigation", -verticalPages: [ -{{#each verticalConfigs}} -{{#if (any verticalKey (lookup verticalsToConfig 'Universal'))}} - { - verticalKey: "{{{verticalKey}}}", - {{#each ../excludedVerticals}}{{#ifeq this ../verticalKey}}hideInNavigation: true,{{/ifeq}}{{/each}} - {{#ifeq ../verticalKey verticalKey}}isActive: true,{{/ifeq}} - {{#if verticalKey}} - {{#with (lookup verticalsToConfig verticalKey)}} - {{#if isFirst}}isFirst: {{isFirst}},{{/if}} - {{#if icon}}icon: "{{{icon}}}",{{/if}} - label: {{> verticalLabel overridedLabel=label verticalKey=../verticalKey fallback=@key}}, - url: - {{#if url}} - "{{{relativePathHandler url=url relativePath=@root.relativePath}}}", - {{else if ../url}} - "{{{relativePathHandler url=../url relativePath=@root.relativePath}}}", - {{else}} - "{{{@key}}}.html", - {{/if}} - {{/with}} - {{else}} - {{#with (lookup verticalsToConfig "Universal")}} - {{#if isFirst}}isFirst: {{isFirst}},{{/if}} - {{#if icon}}icon: "{{{icon}}}",{{/if}} - label: {{#if label}}"{{{label}}}"{{else}}"{{{@key}}}"{{/if}}, - url: - {{#if url}} - "{{{relativePathHandler url=url relativePath=@root.relativePath}}}", - {{else if ../url}} - "{{{relativePathHandler url=../url relativePath=@root.relativePath}}}", - {{else}} - "{{{@key}}}.html", - {{/if}} - {{/with}} - {{/if}} - }{{#unless @last}},{{/unless}} -{{/if}} -{{/each}} -], -onCreate: function() { - this._container.textContent = ''; -} -}, {{{ json componentSettings.Navigation }}})); - -{{!-- - Prints the vertical label according to specific logic - Assumes @root has environment variables and global_config - @param overridedLabel The hardcoded label from configuration in repo, meant to supercede defaults - @param verticalKey The current vertical key, if it exists - @param fallback The fallback for the label if all else doesn't exist ---}} -{{#*inline 'verticalLabel'}} - {{~#if overridedLabel ~}} - "{{{overridedLabel}}}" - {{~ else ~}} - HitchhikerJS.getInjectedProp( - "{{{@root.global_config.experienceKey}}}", - ["verticals", "{{{verticalKey}}}", "displayName"]) - {{~#if verticalKey ~}} || "{{{verticalKey}}}" {{~/if ~}} - {{~#if fallback ~}} || "{{{fallback}}}" {{~/if ~}} - {{~/if ~}} -{{/inline}} +{{> templates/common-partials/script/navigation }} \ No newline at end of file From 632ca5f670b5bf957b54bed86ff8ec13eba209d3 Mon Sep 17 00:00:00 2001 From: Christopher Jiang Date: Mon, 7 Jun 2021 17:43:58 -0400 Subject: [PATCH 27/56] Created common partial for spellcheck --- templates/common-partials/markup/spellcheck.hbs | 1 + templates/common-partials/script/spellcheck.hbs | 3 +++ templates/universal-standard/markup/spellcheck.hbs | 2 +- templates/universal-standard/script/spellcheck.hbs | 4 +--- templates/vertical-full-page-map/markup/spellcheck.hbs | 2 +- templates/vertical-full-page-map/script/spellcheck.hbs | 4 +--- templates/vertical-grid/markup/spellcheck.hbs | 2 +- templates/vertical-grid/script/spellcheck.hbs | 4 +--- templates/vertical-map/markup/spellcheck.hbs | 2 +- templates/vertical-map/script/spellcheck.hbs | 4 +--- templates/vertical-standard/markup/spellcheck.hbs | 2 +- templates/vertical-standard/script/spellcheck.hbs | 4 +--- 12 files changed, 14 insertions(+), 20 deletions(-) create mode 100644 templates/common-partials/markup/spellcheck.hbs create mode 100644 templates/common-partials/script/spellcheck.hbs diff --git a/templates/common-partials/markup/spellcheck.hbs b/templates/common-partials/markup/spellcheck.hbs new file mode 100644 index 000000000..afb50153f --- /dev/null +++ b/templates/common-partials/markup/spellcheck.hbs @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/templates/common-partials/script/spellcheck.hbs b/templates/common-partials/script/spellcheck.hbs new file mode 100644 index 000000000..8c1ac95b6 --- /dev/null +++ b/templates/common-partials/script/spellcheck.hbs @@ -0,0 +1,3 @@ +ANSWERS.addComponent("SpellCheck", Object.assign({}, { + container: "#js-answersSpellCheck", +}, {{{ json componentSettings.SpellCheck }}})); \ No newline at end of file diff --git a/templates/universal-standard/markup/spellcheck.hbs b/templates/universal-standard/markup/spellcheck.hbs index 650b1523a..ac024baf5 100644 --- a/templates/universal-standard/markup/spellcheck.hbs +++ b/templates/universal-standard/markup/spellcheck.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/spellcheck }} \ No newline at end of file diff --git a/templates/universal-standard/script/spellcheck.hbs b/templates/universal-standard/script/spellcheck.hbs index 6f23a0a83..bc08a85b8 100644 --- a/templates/universal-standard/script/spellcheck.hbs +++ b/templates/universal-standard/script/spellcheck.hbs @@ -1,3 +1 @@ -ANSWERS.addComponent("SpellCheck", Object.assign({}, { - container: ".js-answersSpellCheck", -}, {{{ json componentSettings.SpellCheck }}})); \ No newline at end of file +{{> templates/common-partials/script/spellcheck }} \ No newline at end of file diff --git a/templates/vertical-full-page-map/markup/spellcheck.hbs b/templates/vertical-full-page-map/markup/spellcheck.hbs index afb50153f..ac024baf5 100644 --- a/templates/vertical-full-page-map/markup/spellcheck.hbs +++ b/templates/vertical-full-page-map/markup/spellcheck.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/spellcheck }} \ No newline at end of file diff --git a/templates/vertical-full-page-map/script/spellcheck.hbs b/templates/vertical-full-page-map/script/spellcheck.hbs index 8c1ac95b6..bc08a85b8 100644 --- a/templates/vertical-full-page-map/script/spellcheck.hbs +++ b/templates/vertical-full-page-map/script/spellcheck.hbs @@ -1,3 +1 @@ -ANSWERS.addComponent("SpellCheck", Object.assign({}, { - container: "#js-answersSpellCheck", -}, {{{ json componentSettings.SpellCheck }}})); \ No newline at end of file +{{> templates/common-partials/script/spellcheck }} \ No newline at end of file diff --git a/templates/vertical-grid/markup/spellcheck.hbs b/templates/vertical-grid/markup/spellcheck.hbs index 650b1523a..ac024baf5 100644 --- a/templates/vertical-grid/markup/spellcheck.hbs +++ b/templates/vertical-grid/markup/spellcheck.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/spellcheck }} \ No newline at end of file diff --git a/templates/vertical-grid/script/spellcheck.hbs b/templates/vertical-grid/script/spellcheck.hbs index f11979b05..bc08a85b8 100644 --- a/templates/vertical-grid/script/spellcheck.hbs +++ b/templates/vertical-grid/script/spellcheck.hbs @@ -1,3 +1 @@ -ANSWERS.addComponent("SpellCheck", Object.assign({}, { - container: ".js-answersSpellCheck", -}, {{{ json componentSettings.SpellCheck }}})); \ No newline at end of file +{{> templates/common-partials/script/spellcheck }} \ No newline at end of file diff --git a/templates/vertical-map/markup/spellcheck.hbs b/templates/vertical-map/markup/spellcheck.hbs index afb50153f..ac024baf5 100644 --- a/templates/vertical-map/markup/spellcheck.hbs +++ b/templates/vertical-map/markup/spellcheck.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/spellcheck }} \ No newline at end of file diff --git a/templates/vertical-map/script/spellcheck.hbs b/templates/vertical-map/script/spellcheck.hbs index 8c1ac95b6..bc08a85b8 100644 --- a/templates/vertical-map/script/spellcheck.hbs +++ b/templates/vertical-map/script/spellcheck.hbs @@ -1,3 +1 @@ -ANSWERS.addComponent("SpellCheck", Object.assign({}, { - container: "#js-answersSpellCheck", -}, {{{ json componentSettings.SpellCheck }}})); \ No newline at end of file +{{> templates/common-partials/script/spellcheck }} \ No newline at end of file diff --git a/templates/vertical-standard/markup/spellcheck.hbs b/templates/vertical-standard/markup/spellcheck.hbs index 650b1523a..ac024baf5 100644 --- a/templates/vertical-standard/markup/spellcheck.hbs +++ b/templates/vertical-standard/markup/spellcheck.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/spellcheck }} \ No newline at end of file diff --git a/templates/vertical-standard/script/spellcheck.hbs b/templates/vertical-standard/script/spellcheck.hbs index f11979b05..bc08a85b8 100644 --- a/templates/vertical-standard/script/spellcheck.hbs +++ b/templates/vertical-standard/script/spellcheck.hbs @@ -1,3 +1 @@ -ANSWERS.addComponent("SpellCheck", Object.assign({}, { - container: ".js-answersSpellCheck", -}, {{{ json componentSettings.SpellCheck }}})); \ No newline at end of file +{{> templates/common-partials/script/spellcheck }} \ No newline at end of file From 2200e42739465c8100e72f706e5b7ddeb5ca4a35 Mon Sep 17 00:00:00 2001 From: Christopher Jiang Date: Tue, 8 Jun 2021 13:24:47 -0400 Subject: [PATCH 28/56] Created common partial for location-bias --- templates/common-partials/markup/locationbias.hbs | 3 +++ templates/common-partials/script/locationbias.hbs | 7 +++++++ templates/universal-standard/markup/locationbias.hbs | 2 +- templates/universal-standard/script/locationbias.hbs | 4 +--- templates/vertical-full-page-map/markup/locationbias.hbs | 4 +--- templates/vertical-full-page-map/script/locationbias.hbs | 8 +------- templates/vertical-grid/markup/locationbias.hbs | 2 +- templates/vertical-grid/script/locationbias.hbs | 7 +------ templates/vertical-map/markup/locationbias.hbs | 2 +- templates/vertical-map/script/locationbias.hbs | 7 +------ templates/vertical-standard/markup/locationbias.hbs | 2 +- templates/vertical-standard/script/locationbias.hbs | 7 +------ 12 files changed, 20 insertions(+), 35 deletions(-) create mode 100644 templates/common-partials/markup/locationbias.hbs create mode 100644 templates/common-partials/script/locationbias.hbs diff --git a/templates/common-partials/markup/locationbias.hbs b/templates/common-partials/markup/locationbias.hbs new file mode 100644 index 000000000..d73284f08 --- /dev/null +++ b/templates/common-partials/markup/locationbias.hbs @@ -0,0 +1,3 @@ +
+
diff --git a/templates/common-partials/script/locationbias.hbs b/templates/common-partials/script/locationbias.hbs new file mode 100644 index 000000000..34689ae6a --- /dev/null +++ b/templates/common-partials/script/locationbias.hbs @@ -0,0 +1,7 @@ +ANSWERS.addComponent("LocationBias", Object.assign({}, { + container: "#js-answersLocationBias{{#if modifier}}--{{modifier}}{{/if}}", + updateLocationEl: "#js-answersLocationBias{{#if modifier}}--{{modifier}}{{/if}} .js-locationBias-update-location", + {{#if verticalKey}} + verticalKey: "{{{verticalKey}}}" + {{/if}} +}, {{{ json componentSettings.LocationBias }}})); diff --git a/templates/universal-standard/markup/locationbias.hbs b/templates/universal-standard/markup/locationbias.hbs index 7770d29b8..be269d864 100644 --- a/templates/universal-standard/markup/locationbias.hbs +++ b/templates/universal-standard/markup/locationbias.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/locationbias }} \ No newline at end of file diff --git a/templates/universal-standard/script/locationbias.hbs b/templates/universal-standard/script/locationbias.hbs index 483d81ef0..afbbda335 100644 --- a/templates/universal-standard/script/locationbias.hbs +++ b/templates/universal-standard/script/locationbias.hbs @@ -1,3 +1 @@ -ANSWERS.addComponent("LocationBias", Object.assign({}, { - container: "#js-answersLocationBias" -}, {{{ json componentSettings.LocationBias }}})); \ No newline at end of file +{{> templates/common-partials/script/locationbias }} \ No newline at end of file diff --git a/templates/vertical-full-page-map/markup/locationbias.hbs b/templates/vertical-full-page-map/markup/locationbias.hbs index d73284f08..be269d864 100644 --- a/templates/vertical-full-page-map/markup/locationbias.hbs +++ b/templates/vertical-full-page-map/markup/locationbias.hbs @@ -1,3 +1 @@ -
-
+{{> templates/common-partials/markup/locationbias }} \ No newline at end of file diff --git a/templates/vertical-full-page-map/script/locationbias.hbs b/templates/vertical-full-page-map/script/locationbias.hbs index 34689ae6a..afbbda335 100644 --- a/templates/vertical-full-page-map/script/locationbias.hbs +++ b/templates/vertical-full-page-map/script/locationbias.hbs @@ -1,7 +1 @@ -ANSWERS.addComponent("LocationBias", Object.assign({}, { - container: "#js-answersLocationBias{{#if modifier}}--{{modifier}}{{/if}}", - updateLocationEl: "#js-answersLocationBias{{#if modifier}}--{{modifier}}{{/if}} .js-locationBias-update-location", - {{#if verticalKey}} - verticalKey: "{{{verticalKey}}}" - {{/if}} -}, {{{ json componentSettings.LocationBias }}})); +{{> templates/common-partials/script/locationbias }} \ No newline at end of file diff --git a/templates/vertical-grid/markup/locationbias.hbs b/templates/vertical-grid/markup/locationbias.hbs index 13d8b63b9..be269d864 100644 --- a/templates/vertical-grid/markup/locationbias.hbs +++ b/templates/vertical-grid/markup/locationbias.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/locationbias }} \ No newline at end of file diff --git a/templates/vertical-grid/script/locationbias.hbs b/templates/vertical-grid/script/locationbias.hbs index 4a50d56b6..afbbda335 100644 --- a/templates/vertical-grid/script/locationbias.hbs +++ b/templates/vertical-grid/script/locationbias.hbs @@ -1,6 +1 @@ -ANSWERS.addComponent("LocationBias", Object.assign({}, { - container: ".js-answersLocationBias", - {{#if verticalKey}} - verticalKey: "{{{verticalKey}}}" - {{/if}} -}, {{{ json componentSettings.LocationBias }}})); \ No newline at end of file +{{> templates/common-partials/script/locationbias }} \ No newline at end of file diff --git a/templates/vertical-map/markup/locationbias.hbs b/templates/vertical-map/markup/locationbias.hbs index 7770d29b8..be269d864 100644 --- a/templates/vertical-map/markup/locationbias.hbs +++ b/templates/vertical-map/markup/locationbias.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/locationbias }} \ No newline at end of file diff --git a/templates/vertical-map/script/locationbias.hbs b/templates/vertical-map/script/locationbias.hbs index 4a50d56b6..afbbda335 100644 --- a/templates/vertical-map/script/locationbias.hbs +++ b/templates/vertical-map/script/locationbias.hbs @@ -1,6 +1 @@ -ANSWERS.addComponent("LocationBias", Object.assign({}, { - container: ".js-answersLocationBias", - {{#if verticalKey}} - verticalKey: "{{{verticalKey}}}" - {{/if}} -}, {{{ json componentSettings.LocationBias }}})); \ No newline at end of file +{{> templates/common-partials/script/locationbias }} \ No newline at end of file diff --git a/templates/vertical-standard/markup/locationbias.hbs b/templates/vertical-standard/markup/locationbias.hbs index 13d8b63b9..be269d864 100644 --- a/templates/vertical-standard/markup/locationbias.hbs +++ b/templates/vertical-standard/markup/locationbias.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/locationbias }} \ No newline at end of file diff --git a/templates/vertical-standard/script/locationbias.hbs b/templates/vertical-standard/script/locationbias.hbs index 4a50d56b6..afbbda335 100644 --- a/templates/vertical-standard/script/locationbias.hbs +++ b/templates/vertical-standard/script/locationbias.hbs @@ -1,6 +1 @@ -ANSWERS.addComponent("LocationBias", Object.assign({}, { - container: ".js-answersLocationBias", - {{#if verticalKey}} - verticalKey: "{{{verticalKey}}}" - {{/if}} -}, {{{ json componentSettings.LocationBias }}})); \ No newline at end of file +{{> templates/common-partials/script/locationbias }} \ No newline at end of file From b2c06c9f2aa11e6e55326330ec0abf70e6cd1cfd Mon Sep 17 00:00:00 2001 From: Christopher Jiang Date: Tue, 8 Jun 2021 13:30:35 -0400 Subject: [PATCH 29/56] Created common partial for qasubmission --- templates/common-partials/markup/qasubmission.hbs | 1 + templates/common-partials/script/qasubmission.hbs | 3 +++ templates/universal-standard/markup/qasubmission.hbs | 2 +- templates/universal-standard/script/qasubmission.hbs | 4 +--- templates/vertical-full-page-map/markup/qasubmission.hbs | 2 +- templates/vertical-full-page-map/script/qasubmission.hbs | 4 +--- templates/vertical-grid/markup/qasubmission.hbs | 2 +- templates/vertical-grid/script/qasubmission.hbs | 4 +--- templates/vertical-map/markup/qasubmission.hbs | 2 +- templates/vertical-map/script/qasubmission.hbs | 4 +--- templates/vertical-standard/markup/qasubmission.hbs | 2 +- templates/vertical-standard/script/qasubmission.hbs | 4 +--- 12 files changed, 14 insertions(+), 20 deletions(-) create mode 100644 templates/common-partials/markup/qasubmission.hbs create mode 100644 templates/common-partials/script/qasubmission.hbs diff --git a/templates/common-partials/markup/qasubmission.hbs b/templates/common-partials/markup/qasubmission.hbs new file mode 100644 index 000000000..4493cfb7d --- /dev/null +++ b/templates/common-partials/markup/qasubmission.hbs @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/templates/common-partials/script/qasubmission.hbs b/templates/common-partials/script/qasubmission.hbs new file mode 100644 index 000000000..fdd3628c4 --- /dev/null +++ b/templates/common-partials/script/qasubmission.hbs @@ -0,0 +1,3 @@ +ANSWERS.addComponent("QASubmission", Object.assign({}, { + container: "#js-answersQASubmission", +}, {{{ json componentSettings.QASubmission }}})); \ No newline at end of file diff --git a/templates/universal-standard/markup/qasubmission.hbs b/templates/universal-standard/markup/qasubmission.hbs index 2d9f94d41..17c7b9647 100644 --- a/templates/universal-standard/markup/qasubmission.hbs +++ b/templates/universal-standard/markup/qasubmission.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/qasubmission }} \ No newline at end of file diff --git a/templates/universal-standard/script/qasubmission.hbs b/templates/universal-standard/script/qasubmission.hbs index 97f907e89..c5d780012 100644 --- a/templates/universal-standard/script/qasubmission.hbs +++ b/templates/universal-standard/script/qasubmission.hbs @@ -1,3 +1 @@ -ANSWERS.addComponent("QASubmission", Object.assign({}, { - container: ".js-answersQASubmission", -}, {{{ json componentSettings.QASubmission }}})); \ No newline at end of file +{{> templates/common-partials/script/qasubmission }} \ No newline at end of file diff --git a/templates/vertical-full-page-map/markup/qasubmission.hbs b/templates/vertical-full-page-map/markup/qasubmission.hbs index 4493cfb7d..17c7b9647 100644 --- a/templates/vertical-full-page-map/markup/qasubmission.hbs +++ b/templates/vertical-full-page-map/markup/qasubmission.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/qasubmission }} \ No newline at end of file diff --git a/templates/vertical-full-page-map/script/qasubmission.hbs b/templates/vertical-full-page-map/script/qasubmission.hbs index fdd3628c4..c5d780012 100644 --- a/templates/vertical-full-page-map/script/qasubmission.hbs +++ b/templates/vertical-full-page-map/script/qasubmission.hbs @@ -1,3 +1 @@ -ANSWERS.addComponent("QASubmission", Object.assign({}, { - container: "#js-answersQASubmission", -}, {{{ json componentSettings.QASubmission }}})); \ No newline at end of file +{{> templates/common-partials/script/qasubmission }} \ No newline at end of file diff --git a/templates/vertical-grid/markup/qasubmission.hbs b/templates/vertical-grid/markup/qasubmission.hbs index 2d9f94d41..17c7b9647 100644 --- a/templates/vertical-grid/markup/qasubmission.hbs +++ b/templates/vertical-grid/markup/qasubmission.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/qasubmission }} \ No newline at end of file diff --git a/templates/vertical-grid/script/qasubmission.hbs b/templates/vertical-grid/script/qasubmission.hbs index 18d33c065..c5d780012 100644 --- a/templates/vertical-grid/script/qasubmission.hbs +++ b/templates/vertical-grid/script/qasubmission.hbs @@ -1,3 +1 @@ -ANSWERS.addComponent("QASubmission", Object.assign({}, { - container: ".js-answersQASubmission", -}, {{{ json componentSettings.QASubmission }}})); \ No newline at end of file +{{> templates/common-partials/script/qasubmission }} \ No newline at end of file diff --git a/templates/vertical-map/markup/qasubmission.hbs b/templates/vertical-map/markup/qasubmission.hbs index 4493cfb7d..17c7b9647 100644 --- a/templates/vertical-map/markup/qasubmission.hbs +++ b/templates/vertical-map/markup/qasubmission.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/qasubmission }} \ No newline at end of file diff --git a/templates/vertical-map/script/qasubmission.hbs b/templates/vertical-map/script/qasubmission.hbs index fdd3628c4..c5d780012 100644 --- a/templates/vertical-map/script/qasubmission.hbs +++ b/templates/vertical-map/script/qasubmission.hbs @@ -1,3 +1 @@ -ANSWERS.addComponent("QASubmission", Object.assign({}, { - container: "#js-answersQASubmission", -}, {{{ json componentSettings.QASubmission }}})); \ No newline at end of file +{{> templates/common-partials/script/qasubmission }} \ No newline at end of file diff --git a/templates/vertical-standard/markup/qasubmission.hbs b/templates/vertical-standard/markup/qasubmission.hbs index 2d9f94d41..17c7b9647 100644 --- a/templates/vertical-standard/markup/qasubmission.hbs +++ b/templates/vertical-standard/markup/qasubmission.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/qasubmission }} \ No newline at end of file diff --git a/templates/vertical-standard/script/qasubmission.hbs b/templates/vertical-standard/script/qasubmission.hbs index 18d33c065..c5d780012 100644 --- a/templates/vertical-standard/script/qasubmission.hbs +++ b/templates/vertical-standard/script/qasubmission.hbs @@ -1,3 +1 @@ -ANSWERS.addComponent("QASubmission", Object.assign({}, { - container: ".js-answersQASubmission", -}, {{{ json componentSettings.QASubmission }}})); \ No newline at end of file +{{> templates/common-partials/script/qasubmission }} \ No newline at end of file From 6e300de492f9a4fa40e7776ffc61fb3e591a201d Mon Sep 17 00:00:00 2001 From: Christopher Jiang Date: Tue, 8 Jun 2021 13:44:46 -0400 Subject: [PATCH 30/56] Created common partial for appliedfilters --- templates/common-partials/markup/appliedfilters.hbs | 1 + templates/common-partials/script/appliedfilters.hbs | 7 +++++++ .../vertical-full-page-map/markup/appliedfilters.hbs | 2 +- .../vertical-full-page-map/script/appliedfilters.hbs | 8 +------- templates/vertical-grid/markup/appliedfilters.hbs | 2 +- templates/vertical-grid/script/appliedfilters.hbs | 8 +------- templates/vertical-map/markup/appliedfilters.hbs | 2 +- templates/vertical-map/script/appliedfilters.hbs | 8 +------- templates/vertical-standard/markup/appliedfilters.hbs | 2 +- templates/vertical-standard/script/appliedfilters.hbs | 8 +------- 10 files changed, 16 insertions(+), 32 deletions(-) create mode 100644 templates/common-partials/markup/appliedfilters.hbs create mode 100644 templates/common-partials/script/appliedfilters.hbs diff --git a/templates/common-partials/markup/appliedfilters.hbs b/templates/common-partials/markup/appliedfilters.hbs new file mode 100644 index 000000000..45d6c20b5 --- /dev/null +++ b/templates/common-partials/markup/appliedfilters.hbs @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/templates/common-partials/script/appliedfilters.hbs b/templates/common-partials/script/appliedfilters.hbs new file mode 100644 index 000000000..b1875e649 --- /dev/null +++ b/templates/common-partials/script/appliedfilters.hbs @@ -0,0 +1,7 @@ +ANSWERS.addComponent('AppliedFilters', { + container: '#js-answersAppliedFilters', + {{#if verticalKey}} + verticalKey: '{{{verticalKey}}}', + {{/if}} + ...{{{ json componentSettings.AppliedFilters }}} +}); \ No newline at end of file diff --git a/templates/vertical-full-page-map/markup/appliedfilters.hbs b/templates/vertical-full-page-map/markup/appliedfilters.hbs index 45d6c20b5..b5631f8de 100644 --- a/templates/vertical-full-page-map/markup/appliedfilters.hbs +++ b/templates/vertical-full-page-map/markup/appliedfilters.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/appliedfilters }} \ No newline at end of file diff --git a/templates/vertical-full-page-map/script/appliedfilters.hbs b/templates/vertical-full-page-map/script/appliedfilters.hbs index b1875e649..1e7333f02 100644 --- a/templates/vertical-full-page-map/script/appliedfilters.hbs +++ b/templates/vertical-full-page-map/script/appliedfilters.hbs @@ -1,7 +1 @@ -ANSWERS.addComponent('AppliedFilters', { - container: '#js-answersAppliedFilters', - {{#if verticalKey}} - verticalKey: '{{{verticalKey}}}', - {{/if}} - ...{{{ json componentSettings.AppliedFilters }}} -}); \ No newline at end of file +{{> templates/common-partials/script/appliedfilters }} \ No newline at end of file diff --git a/templates/vertical-grid/markup/appliedfilters.hbs b/templates/vertical-grid/markup/appliedfilters.hbs index 45d6c20b5..b5631f8de 100644 --- a/templates/vertical-grid/markup/appliedfilters.hbs +++ b/templates/vertical-grid/markup/appliedfilters.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/appliedfilters }} \ No newline at end of file diff --git a/templates/vertical-grid/script/appliedfilters.hbs b/templates/vertical-grid/script/appliedfilters.hbs index b1875e649..1e7333f02 100644 --- a/templates/vertical-grid/script/appliedfilters.hbs +++ b/templates/vertical-grid/script/appliedfilters.hbs @@ -1,7 +1 @@ -ANSWERS.addComponent('AppliedFilters', { - container: '#js-answersAppliedFilters', - {{#if verticalKey}} - verticalKey: '{{{verticalKey}}}', - {{/if}} - ...{{{ json componentSettings.AppliedFilters }}} -}); \ No newline at end of file +{{> templates/common-partials/script/appliedfilters }} \ No newline at end of file diff --git a/templates/vertical-map/markup/appliedfilters.hbs b/templates/vertical-map/markup/appliedfilters.hbs index 45d6c20b5..b5631f8de 100644 --- a/templates/vertical-map/markup/appliedfilters.hbs +++ b/templates/vertical-map/markup/appliedfilters.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/appliedfilters }} \ No newline at end of file diff --git a/templates/vertical-map/script/appliedfilters.hbs b/templates/vertical-map/script/appliedfilters.hbs index b1875e649..1e7333f02 100644 --- a/templates/vertical-map/script/appliedfilters.hbs +++ b/templates/vertical-map/script/appliedfilters.hbs @@ -1,7 +1 @@ -ANSWERS.addComponent('AppliedFilters', { - container: '#js-answersAppliedFilters', - {{#if verticalKey}} - verticalKey: '{{{verticalKey}}}', - {{/if}} - ...{{{ json componentSettings.AppliedFilters }}} -}); \ No newline at end of file +{{> templates/common-partials/script/appliedfilters }} \ No newline at end of file diff --git a/templates/vertical-standard/markup/appliedfilters.hbs b/templates/vertical-standard/markup/appliedfilters.hbs index 45d6c20b5..b5631f8de 100644 --- a/templates/vertical-standard/markup/appliedfilters.hbs +++ b/templates/vertical-standard/markup/appliedfilters.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/appliedfilters }} \ No newline at end of file diff --git a/templates/vertical-standard/script/appliedfilters.hbs b/templates/vertical-standard/script/appliedfilters.hbs index b1875e649..1e7333f02 100644 --- a/templates/vertical-standard/script/appliedfilters.hbs +++ b/templates/vertical-standard/script/appliedfilters.hbs @@ -1,7 +1 @@ -ANSWERS.addComponent('AppliedFilters', { - container: '#js-answersAppliedFilters', - {{#if verticalKey}} - verticalKey: '{{{verticalKey}}}', - {{/if}} - ...{{{ json componentSettings.AppliedFilters }}} -}); \ No newline at end of file +{{> templates/common-partials/script/appliedfilters }} \ No newline at end of file From 2d4d09797876070483c1d3ca849fa84ff4dec54b Mon Sep 17 00:00:00 2001 From: Christopher Jiang Date: Tue, 8 Jun 2021 13:54:14 -0400 Subject: [PATCH 31/56] Created common partial for facets --- templates/common-partials/markup/facets.hbs | 1 + templates/common-partials/script/facets.hbs | 15 +++++++++++++++ .../vertical-full-page-map/markup/facets.hbs | 2 +- .../vertical-full-page-map/script/facets.hbs | 16 +--------------- templates/vertical-grid/markup/facets.hbs | 2 +- templates/vertical-grid/script/facets.hbs | 16 +--------------- templates/vertical-map/markup/facets.hbs | 2 +- templates/vertical-map/script/facets.hbs | 16 +--------------- templates/vertical-standard/markup/facets.hbs | 2 +- templates/vertical-standard/script/facets.hbs | 16 +--------------- 10 files changed, 24 insertions(+), 64 deletions(-) create mode 100644 templates/common-partials/markup/facets.hbs create mode 100644 templates/common-partials/script/facets.hbs diff --git a/templates/common-partials/markup/facets.hbs b/templates/common-partials/markup/facets.hbs new file mode 100644 index 000000000..dea947748 --- /dev/null +++ b/templates/common-partials/markup/facets.hbs @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/templates/common-partials/script/facets.hbs b/templates/common-partials/script/facets.hbs new file mode 100644 index 000000000..2c7305c6d --- /dev/null +++ b/templates/common-partials/script/facets.hbs @@ -0,0 +1,15 @@ +ANSWERS.addComponent('Facets', { + container: '#js-answersFacets', + {{#if verticalKey}} + verticalKey: "{{{verticalKey}}}", + {{/if}} + onMount: function() { + if (typeof IS_COLLAPSIBLE_FILTERS !== 'undefined') { + facetsDecorator.onMount(this); + } + }, + {{#if componentSettings.Facets.fields}} + transformFacets: HitchhikerJS.transformFacets, + {{/if}} + ...{{{ json componentSettings.Facets }}}, +}); diff --git a/templates/vertical-full-page-map/markup/facets.hbs b/templates/vertical-full-page-map/markup/facets.hbs index dea947748..06807b3a2 100644 --- a/templates/vertical-full-page-map/markup/facets.hbs +++ b/templates/vertical-full-page-map/markup/facets.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/facets }} \ No newline at end of file diff --git a/templates/vertical-full-page-map/script/facets.hbs b/templates/vertical-full-page-map/script/facets.hbs index 2c7305c6d..0dbba794f 100644 --- a/templates/vertical-full-page-map/script/facets.hbs +++ b/templates/vertical-full-page-map/script/facets.hbs @@ -1,15 +1 @@ -ANSWERS.addComponent('Facets', { - container: '#js-answersFacets', - {{#if verticalKey}} - verticalKey: "{{{verticalKey}}}", - {{/if}} - onMount: function() { - if (typeof IS_COLLAPSIBLE_FILTERS !== 'undefined') { - facetsDecorator.onMount(this); - } - }, - {{#if componentSettings.Facets.fields}} - transformFacets: HitchhikerJS.transformFacets, - {{/if}} - ...{{{ json componentSettings.Facets }}}, -}); +{{> templates/common-partials/script/facets }} \ No newline at end of file diff --git a/templates/vertical-grid/markup/facets.hbs b/templates/vertical-grid/markup/facets.hbs index dea947748..06807b3a2 100644 --- a/templates/vertical-grid/markup/facets.hbs +++ b/templates/vertical-grid/markup/facets.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/facets }} \ No newline at end of file diff --git a/templates/vertical-grid/script/facets.hbs b/templates/vertical-grid/script/facets.hbs index 2c7305c6d..0dbba794f 100644 --- a/templates/vertical-grid/script/facets.hbs +++ b/templates/vertical-grid/script/facets.hbs @@ -1,15 +1 @@ -ANSWERS.addComponent('Facets', { - container: '#js-answersFacets', - {{#if verticalKey}} - verticalKey: "{{{verticalKey}}}", - {{/if}} - onMount: function() { - if (typeof IS_COLLAPSIBLE_FILTERS !== 'undefined') { - facetsDecorator.onMount(this); - } - }, - {{#if componentSettings.Facets.fields}} - transformFacets: HitchhikerJS.transformFacets, - {{/if}} - ...{{{ json componentSettings.Facets }}}, -}); +{{> templates/common-partials/script/facets }} \ No newline at end of file diff --git a/templates/vertical-map/markup/facets.hbs b/templates/vertical-map/markup/facets.hbs index dea947748..06807b3a2 100644 --- a/templates/vertical-map/markup/facets.hbs +++ b/templates/vertical-map/markup/facets.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/facets }} \ No newline at end of file diff --git a/templates/vertical-map/script/facets.hbs b/templates/vertical-map/script/facets.hbs index 2c7305c6d..0dbba794f 100644 --- a/templates/vertical-map/script/facets.hbs +++ b/templates/vertical-map/script/facets.hbs @@ -1,15 +1 @@ -ANSWERS.addComponent('Facets', { - container: '#js-answersFacets', - {{#if verticalKey}} - verticalKey: "{{{verticalKey}}}", - {{/if}} - onMount: function() { - if (typeof IS_COLLAPSIBLE_FILTERS !== 'undefined') { - facetsDecorator.onMount(this); - } - }, - {{#if componentSettings.Facets.fields}} - transformFacets: HitchhikerJS.transformFacets, - {{/if}} - ...{{{ json componentSettings.Facets }}}, -}); +{{> templates/common-partials/script/facets }} \ No newline at end of file diff --git a/templates/vertical-standard/markup/facets.hbs b/templates/vertical-standard/markup/facets.hbs index dea947748..06807b3a2 100644 --- a/templates/vertical-standard/markup/facets.hbs +++ b/templates/vertical-standard/markup/facets.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/facets }} \ No newline at end of file diff --git a/templates/vertical-standard/script/facets.hbs b/templates/vertical-standard/script/facets.hbs index f681ee63b..0dbba794f 100644 --- a/templates/vertical-standard/script/facets.hbs +++ b/templates/vertical-standard/script/facets.hbs @@ -1,15 +1 @@ -ANSWERS.addComponent("Facets", { - container: "#js-answersFacets", - {{#if verticalKey}} - verticalKey: "{{{verticalKey}}}", - {{/if}} - onMount: function() { - if (typeof IS_COLLAPSIBLE_FILTERS !== 'undefined') { - facetsDecorator.onMount(this); - } - }, - {{#if componentSettings.Facets.fields}} - transformFacets: HitchhikerJS.transformFacets, - {{/if}} - ...{{{ json componentSettings.Facets }}}, -}); +{{> templates/common-partials/script/facets }} \ No newline at end of file From 00be107f4f568e12c1fdff5b334af36f23b0cccd Mon Sep 17 00:00:00 2001 From: Christopher Jiang Date: Tue, 8 Jun 2021 14:02:25 -0400 Subject: [PATCH 32/56] Created common partial for filterbox --- templates/common-partials/markup/filterbox.hbs | 1 + templates/common-partials/script/filterbox.hbs | 6 ++++++ templates/vertical-full-page-map/markup/filterbox.hbs | 2 +- templates/vertical-full-page-map/script/filterbox.hbs | 7 +------ templates/vertical-grid/markup/filterbox.hbs | 2 +- templates/vertical-grid/script/filterbox.hbs | 7 +------ templates/vertical-map/markup/filterbox.hbs | 2 +- templates/vertical-map/script/filterbox.hbs | 7 +------ templates/vertical-standard/markup/filterbox.hbs | 2 +- templates/vertical-standard/script/filterbox.hbs | 11 +---------- 10 files changed, 15 insertions(+), 32 deletions(-) create mode 100644 templates/common-partials/markup/filterbox.hbs create mode 100644 templates/common-partials/script/filterbox.hbs diff --git a/templates/common-partials/markup/filterbox.hbs b/templates/common-partials/markup/filterbox.hbs new file mode 100644 index 000000000..c4de7520d --- /dev/null +++ b/templates/common-partials/markup/filterbox.hbs @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/templates/common-partials/script/filterbox.hbs b/templates/common-partials/script/filterbox.hbs new file mode 100644 index 000000000..a0f72be29 --- /dev/null +++ b/templates/common-partials/script/filterbox.hbs @@ -0,0 +1,6 @@ +ANSWERS.addComponent("FilterBox", Object.assign({}, { + container: "#js-answersFilterBox", + {{#if verticalKey}} + verticalKey: "{{{verticalKey}}}", + {{/if}} +}, {{{ json componentSettings.FilterBox }}})); diff --git a/templates/vertical-full-page-map/markup/filterbox.hbs b/templates/vertical-full-page-map/markup/filterbox.hbs index c4de7520d..72bd17515 100644 --- a/templates/vertical-full-page-map/markup/filterbox.hbs +++ b/templates/vertical-full-page-map/markup/filterbox.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/filterbox }} \ No newline at end of file diff --git a/templates/vertical-full-page-map/script/filterbox.hbs b/templates/vertical-full-page-map/script/filterbox.hbs index a0f72be29..4eb05f3e9 100644 --- a/templates/vertical-full-page-map/script/filterbox.hbs +++ b/templates/vertical-full-page-map/script/filterbox.hbs @@ -1,6 +1 @@ -ANSWERS.addComponent("FilterBox", Object.assign({}, { - container: "#js-answersFilterBox", - {{#if verticalKey}} - verticalKey: "{{{verticalKey}}}", - {{/if}} -}, {{{ json componentSettings.FilterBox }}})); +{{> templates/common-partials/script/filterbox }} \ No newline at end of file diff --git a/templates/vertical-grid/markup/filterbox.hbs b/templates/vertical-grid/markup/filterbox.hbs index c4de7520d..72bd17515 100644 --- a/templates/vertical-grid/markup/filterbox.hbs +++ b/templates/vertical-grid/markup/filterbox.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/filterbox }} \ No newline at end of file diff --git a/templates/vertical-grid/script/filterbox.hbs b/templates/vertical-grid/script/filterbox.hbs index a0f72be29..4eb05f3e9 100644 --- a/templates/vertical-grid/script/filterbox.hbs +++ b/templates/vertical-grid/script/filterbox.hbs @@ -1,6 +1 @@ -ANSWERS.addComponent("FilterBox", Object.assign({}, { - container: "#js-answersFilterBox", - {{#if verticalKey}} - verticalKey: "{{{verticalKey}}}", - {{/if}} -}, {{{ json componentSettings.FilterBox }}})); +{{> templates/common-partials/script/filterbox }} \ No newline at end of file diff --git a/templates/vertical-map/markup/filterbox.hbs b/templates/vertical-map/markup/filterbox.hbs index c4de7520d..72bd17515 100644 --- a/templates/vertical-map/markup/filterbox.hbs +++ b/templates/vertical-map/markup/filterbox.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/filterbox }} \ No newline at end of file diff --git a/templates/vertical-map/script/filterbox.hbs b/templates/vertical-map/script/filterbox.hbs index a0f72be29..4eb05f3e9 100644 --- a/templates/vertical-map/script/filterbox.hbs +++ b/templates/vertical-map/script/filterbox.hbs @@ -1,6 +1 @@ -ANSWERS.addComponent("FilterBox", Object.assign({}, { - container: "#js-answersFilterBox", - {{#if verticalKey}} - verticalKey: "{{{verticalKey}}}", - {{/if}} -}, {{{ json componentSettings.FilterBox }}})); +{{> templates/common-partials/script/filterbox }} \ No newline at end of file diff --git a/templates/vertical-standard/markup/filterbox.hbs b/templates/vertical-standard/markup/filterbox.hbs index c4de7520d..72bd17515 100644 --- a/templates/vertical-standard/markup/filterbox.hbs +++ b/templates/vertical-standard/markup/filterbox.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/filterbox }} \ No newline at end of file diff --git a/templates/vertical-standard/script/filterbox.hbs b/templates/vertical-standard/script/filterbox.hbs index 813a78dd0..4eb05f3e9 100644 --- a/templates/vertical-standard/script/filterbox.hbs +++ b/templates/vertical-standard/script/filterbox.hbs @@ -1,10 +1 @@ -ANSWERS.addComponent("FilterBox", Object.assign({}, { - container: "#js-answersFilterBox", - {{#if componentSettings.FilterBox.verticalKey}} - verticalKey: "{{componentSettings.FilterBox.verticalKey}}", - {{else}} - {{#if verticalKey}} - verticalKey: "{{{verticalKey}}}", - {{/if}} - {{/if}} -}, {{{ json componentSettings.FilterBox }}})); +{{> templates/common-partials/script/filterbox }} \ No newline at end of file From cc7f70d1d67694dbf61ad56585f44e778e52f533 Mon Sep 17 00:00:00 2001 From: cea2aj <42848445+cea2aj@users.noreply.github.com> Date: Wed, 9 Jun 2021 15:25:20 -0400 Subject: [PATCH 33/56] Use the esbuild-loader for production minification (#825) Use the esbuild-loader in order to speed up our production build javascript and css minification This changes speeds up the production webpack build by approximately 30 to 40%. The trade-off with esbuild is that the resulting minimized file is not quite as small. For index.html of the test site, the page size is about 2% larger. We can remove cssnano and let esbuild handle css minification because the esbuild css minimizer leads to 8% faster webpack builds than CSS nano, and the resulting pages are 0.5% larger. esbuild-loader does not support sourcemaps for css minification, however we currently don't provide css sourcemaps so this is not a regression J=SLAP-1374 TEST=manual Use the time program to measure the performance difference. Smoke test the site on chrome and on IE11. --- static/package-lock.json | 2181 +++++++------------------------- static/package.json | 4 +- static/webpack-config.js | 11 - static/webpack/webpack.prod.js | 12 +- 4 files changed, 491 insertions(+), 1717 deletions(-) diff --git a/static/package-lock.json b/static/package-lock.json index da580915e..541bef080 100644 --- a/static/package-lock.json +++ b/static/package-lock.json @@ -1049,21 +1049,15 @@ "resolved": "https://registry.npmjs.org/@stroncium/procfs/-/procfs-1.2.1.tgz", "integrity": "sha512-X1Iui3FUNZP18EUvysTHxt+Avu2nlVzyf90YM8OYgP6SGzTzzX/0JgObfO1AQQDzuZtNNz29bVh8h5R97JrjxA==" }, - "@trysound/sax": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.1.1.tgz", - "integrity": "sha512-Z6DoceYb/1xSg5+e+ZlPZ9v0N16ZvZ+wYMraFue4HYrE4ttONKtsvruIRf6t9TBR0YvSOfi1hUU0fJfBLCDYow==", - "dev": true - }, "@types/anymatch": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==" }, "@types/eslint": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.4.tgz", - "integrity": "sha512-YCY4kzHMsHoyKspQH+nwSe+70Kep7Vjt2X+dZe5Vs2vkRudqtoFoUIv1RlJmZB8Hbp7McneupoZij4PadxsK5Q==", + "version": "7.2.13", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.13.tgz", + "integrity": "sha512-LKmQCWAlnVHvvXq4oasNUMTJJb2GwSyTY8+1C7OH5ILR8mPLaljv1jxL1bXW3xB3jFbQxTKxJAvI8PyjB09aBg==", "dev": true, "requires": { "@types/estree": "*", @@ -1081,9 +1075,9 @@ } }, "@types/estree": { - "version": "0.0.45", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.45.tgz", - "integrity": "sha512-jnqIUKDUqJbDIUxm0Uj7bnlMnRm1T/eZ9N+AVMqhPgzrba2GhGG5o/jCTwmdPK709nEZsGoMzXEDUjcXHa3W0g==", + "version": "0.0.47", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.47.tgz", + "integrity": "sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg==", "dev": true }, "@types/glob": { @@ -1097,9 +1091,9 @@ } }, "@types/html-minifier-terser": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.0.tgz", - "integrity": "sha512-iYCgjm1dGPRuo12+BStjd1HiVQqhlRhWDOQigNxn023HcjnhsiFz9pc6CzJj4HwDCSQca9bxTL4PxJDbkdm3PA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", + "integrity": "sha512-giAlZwstKbmvMk1OO7WXSj4OZ0keXAcl2TQq4LWHiiPH2ByaH7WeUzng+Qej8UPxxv+8lRTuouo0iaNDBuzIBA==", "dev": true }, "@types/json-schema": { @@ -1119,12 +1113,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.14.tgz", "integrity": "sha512-syUgf67ZQpaJj01/tRTknkMNoBBLWJOBODF0Zm4NrXmiSuxjymFrxnTu1QVYRubhVkRcZLYZG8STTwJRdVm/WQ==" }, - "@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", - "dev": true - }, "@types/parse5": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-5.0.3.tgz", @@ -1156,28 +1144,6 @@ } } }, - "@types/webpack": { - "version": "4.41.18", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.18.tgz", - "integrity": "sha512-mQm2R8vV2BZE/qIDVYqmBVLfX73a8muwjs74SpjEyJWJxeXBbsI9L65Pcia9XfYLYWzD1c1V8m+L0p30y2N7MA==", - "dev": true, - "requires": { - "@types/anymatch": "*", - "@types/node": "*", - "@types/tapable": "*", - "@types/uglify-js": "*", - "@types/webpack-sources": "*", - "source-map": "^0.6.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==", - "dev": true - } - } - }, "@types/webpack-sources": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-1.4.0.tgz", @@ -1196,177 +1162,148 @@ } }, "@webassemblyjs/ast": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", - "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.0.tgz", + "integrity": "sha512-kX2W49LWsbthrmIRMbQZuQDhGtjyqXfEmmHyEi4XWnSZtPmxY0+3anPIzsnRb45VH/J55zlOfWvZuY47aJZTJg==", "dev": true, "requires": { - "@webassemblyjs/helper-module-context": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/wast-parser": "1.9.0" + "@webassemblyjs/helper-numbers": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0" } }, "@webassemblyjs/floating-point-hex-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", - "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.0.tgz", + "integrity": "sha512-Q/aVYs/VnPDVYvsCBL/gSgwmfjeCb4LW8+TMrO3cSzJImgv8lxxEPM2JA5jMrivE7LSz3V+PFqtMbls3m1exDA==", "dev": true }, "@webassemblyjs/helper-api-error": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", - "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.0.tgz", + "integrity": "sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w==", "dev": true }, "@webassemblyjs/helper-buffer": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", - "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", - "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.9.0" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", - "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.0.tgz", + "integrity": "sha512-u9HPBEl4DS+vA8qLQdEQ6N/eJQ7gT7aNvMIo8AAWvAl/xMrcOSiI2M0MAnMCy3jIFke7bEee/JwdX1nUpCtdyA==", "dev": true }, - "@webassemblyjs/helper-module-context": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", - "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", + "@webassemblyjs/helper-numbers": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.0.tgz", + "integrity": "sha512-DhRQKelIj01s5IgdsOJMKLppI+4zpmcMQ3XboFPLwCpSNH6Hqo1ritgHgD0nqHeSYqofA6aBN/NmXuGjM1jEfQ==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.9.0" + "@webassemblyjs/floating-point-hex-parser": "1.11.0", + "@webassemblyjs/helper-api-error": "1.11.0", + "@xtuc/long": "4.2.2" } }, "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", - "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.0.tgz", + "integrity": "sha512-MbmhvxXExm542tWREgSFnOVo07fDpsBJg3sIl6fSp9xuu75eGz5lz31q7wTLffwL3Za7XNRCMZy210+tnsUSEA==", "dev": true }, "@webassemblyjs/helper-wasm-section": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", - "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.0.tgz", + "integrity": "sha512-3Eb88hcbfY/FCukrg6i3EH8H2UsD7x8Vy47iVJrP967A9JGqgBVL9aH71SETPx1JrGsOUVLo0c7vMCN22ytJew==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0" + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-buffer": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0", + "@webassemblyjs/wasm-gen": "1.11.0" } }, "@webassemblyjs/ieee754": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", - "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.0.tgz", + "integrity": "sha512-KXzOqpcYQwAfeQ6WbF6HXo+0udBNmw0iXDmEK5sFlmQdmND+tr773Ti8/5T/M6Tl/413ArSJErATd8In3B+WBA==", "dev": true, "requires": { "@xtuc/ieee754": "^1.2.0" } }, "@webassemblyjs/leb128": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", - "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.0.tgz", + "integrity": "sha512-aqbsHa1mSQAbeeNcl38un6qVY++hh8OpCOzxhixSYgbRfNWcxJNJQwe2rezK9XEcssJbbWIkblaJRwGMS9zp+g==", "dev": true, "requires": { "@xtuc/long": "4.2.2" } }, "@webassemblyjs/utf8": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", - "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.0.tgz", + "integrity": "sha512-A/lclGxH6SpSLSyFowMzO/+aDEPU4hvEiooCMXQPcQFPPJaYcPQNKGOCLUySJsYJ4trbpr+Fs08n4jelkVTGVw==", "dev": true }, "@webassemblyjs/wasm-edit": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", - "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.0.tgz", + "integrity": "sha512-JHQ0damXy0G6J9ucyKVXO2j08JVJ2ntkdJlq1UTiUrIgfGMmA7Ik5VdC/L8hBK46kVJgujkBIoMtT8yVr+yVOQ==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/helper-wasm-section": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0", - "@webassemblyjs/wasm-opt": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0", - "@webassemblyjs/wast-printer": "1.9.0" + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-buffer": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0", + "@webassemblyjs/helper-wasm-section": "1.11.0", + "@webassemblyjs/wasm-gen": "1.11.0", + "@webassemblyjs/wasm-opt": "1.11.0", + "@webassemblyjs/wasm-parser": "1.11.0", + "@webassemblyjs/wast-printer": "1.11.0" } }, "@webassemblyjs/wasm-gen": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", - "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.0.tgz", + "integrity": "sha512-BEUv1aj0WptCZ9kIS30th5ILASUnAPEvE3tVMTrItnZRT9tXCLW2LEXT8ezLw59rqPP9klh9LPmpU+WmRQmCPQ==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/ieee754": "1.9.0", - "@webassemblyjs/leb128": "1.9.0", - "@webassemblyjs/utf8": "1.9.0" + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0", + "@webassemblyjs/ieee754": "1.11.0", + "@webassemblyjs/leb128": "1.11.0", + "@webassemblyjs/utf8": "1.11.0" } }, "@webassemblyjs/wasm-opt": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", - "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.0.tgz", + "integrity": "sha512-tHUSP5F4ywyh3hZ0+fDQuWxKx3mJiPeFufg+9gwTpYp324mPCQgnuVKwzLTZVqj0duRDovnPaZqDwoyhIO8kYg==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0" + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-buffer": "1.11.0", + "@webassemblyjs/wasm-gen": "1.11.0", + "@webassemblyjs/wasm-parser": "1.11.0" } }, "@webassemblyjs/wasm-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", - "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-api-error": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/ieee754": "1.9.0", - "@webassemblyjs/leb128": "1.9.0", - "@webassemblyjs/utf8": "1.9.0" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", - "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.0.tgz", + "integrity": "sha512-6L285Sgu9gphrcpDXINvm0M9BskznnzJTE7gYkjDbxET28shDqp27wpruyx3C2S/dvEwiigBwLA1cz7lNUi0kw==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/floating-point-hex-parser": "1.9.0", - "@webassemblyjs/helper-api-error": "1.9.0", - "@webassemblyjs/helper-code-frame": "1.9.0", - "@webassemblyjs/helper-fsm": "1.9.0", - "@xtuc/long": "4.2.2" + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-api-error": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0", + "@webassemblyjs/ieee754": "1.11.0", + "@webassemblyjs/leb128": "1.11.0", + "@webassemblyjs/utf8": "1.11.0" } }, "@webassemblyjs/wast-printer": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", - "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.0.tgz", + "integrity": "sha512-Fg5OX46pRdTgB7rKIUojkh9vXaVN6sGYCnEiJN1GYkb0RPwShZXp6KTDqmoMdQPKhcroOXh3fEzmkWmCYaKYhQ==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/wast-parser": "1.9.0", + "@webassemblyjs/ast": "1.11.0", "@xtuc/long": "4.2.2" } }, @@ -1416,9 +1353,9 @@ "dev": true }, "acorn": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.0.4.tgz", - "integrity": "sha512-XNP0PqF1XD19ZlLKvB7cMmnZswW4C/03pRHgirB30uSJTaS3A3V1/P4sS3HPvFmjoriPCJQs+JDSbm4bL1TxGQ==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.3.0.tgz", + "integrity": "sha512-tqPKHZ5CaBJw0Xmy0ZZvLs1qTV+BNFSyvn77ASXkpBNfIRk8ev26fKrD9iLGwGA9zedPao52GSHzq8lyZG0NUw==", "dev": true }, "acorn-globals": { @@ -1526,12 +1463,6 @@ "integrity": "sha512-eyoaac3btgU8eJlvh01En8OCKzRqlLe2G5jDsCr3RiE2uLGMEEB1aaGwVVpwR8M95956tGH6R+9edC++OvzaVw==", "dev": true }, - "alphanum-sort": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", - "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", - "dev": true - }, "ansi-colors": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", @@ -1539,9 +1470,9 @@ "dev": true }, "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, "ansi-styles": { @@ -1791,12 +1722,6 @@ "integrity": "sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=", "dev": true }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, "camel-case": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.1.tgz", @@ -1813,18 +1738,6 @@ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, - "caniuse-api": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", - "dev": true, - "requires": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } - }, "caniuse-lite": { "version": "1.0.30001164", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001164.tgz", @@ -1865,13 +1778,10 @@ } }, "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true }, "clean-css": { "version": "4.2.3", @@ -1949,12 +1859,6 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, - "colord": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.0.0.tgz", - "integrity": "sha512-WMDFJfoY3wqPZNpKUFdse3HhD5BHCbE9JCdxRzoVH+ywRITGOeWAHNkGEmyxLlErEpN9OLMWgdM9dWQtDk5dog==", - "dev": true - }, "colorette": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz", @@ -2080,19 +1984,6 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, - "cosmiconfig": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", - "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", - "dev": true, - "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - } - }, "cp-file": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-6.2.0.tgz", @@ -2134,21 +2025,6 @@ } } }, - "css-color-names": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-1.0.1.tgz", - "integrity": "sha512-/loXYOch1qU1biStIFsHH8SxTmOseh1IJqFvy8IujXOm1h+QjUdDhkzOrR5HG8K8mlxREj0yfi8ewCHx0eMxzA==", - "dev": true - }, - "css-declaration-sorter": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.0.3.tgz", - "integrity": "sha512-52P95mvW1SMzuRZegvpluT6yEv0FqQusydKQPZsNN5Q7hh8EwQvN8E2nwuJ16BBvNN6LcoIZXu/Bk58DAhrrxw==", - "dev": true, - "requires": { - "timsort": "^0.3.0" - } - }, "css-loader": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.6.0.tgz", @@ -2205,31 +2081,53 @@ } }, "css-select": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", - "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.1.3.tgz", + "integrity": "sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA==", "dev": true, "requires": { - "boolbase": "~1.0.0", - "css-what": "2.1", - "domutils": "1.5.1", - "nth-check": "~1.0.1" + "boolbase": "^1.0.0", + "css-what": "^5.0.0", + "domhandler": "^4.2.0", + "domutils": "^2.6.0", + "nth-check": "^2.0.0" }, "dependencies": { + "dom-serializer": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", + "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + } + }, "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", "dev": true }, + "domhandler": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.0.tgz", + "integrity": "sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA==", + "dev": true, + "requires": { + "domelementtype": "^2.2.0" + } + }, "domutils": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", - "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.7.0.tgz", + "integrity": "sha512-8eaHa17IwJUPAiB+SoTYBo5mCdeMgdcAoXJ59m6DT1vw+5iLS3gNoqYaRowaBKtGVrOF1Jz4yDTgYKLK2kvfJg==", "dev": true, "requires": { - "dom-serializer": "0", - "domelementtype": "1" + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" } } } @@ -2240,33 +2138,15 @@ "integrity": "sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g==", "dev": true }, - "css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "dev": true, - "requires": { - "mdn-data": "2.0.14", - "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 - } - } - }, "css-vars-ponyfill": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/css-vars-ponyfill/-/css-vars-ponyfill-2.4.2.tgz", "integrity": "sha512-kp8Ufs7jJDoaSym1hw/deawtakLJJTAQMB4ZgkdyOwCTJHqEClbpXI910ovQU4Guxt37EcdRiqppG9ihFyCjPQ==" }, "css-what": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", - "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.0.1.tgz", + "integrity": "sha512-FYDTSHb/7KXsWICVsxdmiExPjCfRC4qRFBdVwv7Ax9hMnvMmEjP9RfxTEZ3qPZGmADDn2vAKSo9UcN1jKVYscg==", "dev": true }, "cssesc": { @@ -2275,69 +2155,6 @@ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "dev": true }, - "cssnano": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.0.4.tgz", - "integrity": "sha512-I+fDW74CJ4yb31765ov9xXe70XLZvFTXjwhmA//VgAAuSAU34Oblbe94Q9zffiCX1VhcSfQWARQnwhz+Nqgb4Q==", - "dev": true, - "requires": { - "cosmiconfig": "^7.0.0", - "cssnano-preset-default": "^5.1.1", - "is-resolvable": "^1.1.0" - } - }, - "cssnano-preset-default": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.1.1.tgz", - "integrity": "sha512-kAhR71Tascmnjlhl4UegGA3KGGbMLXHkkqVpA9idsRT1JmIhIsz1C3tDpBeQMUw5EX5Rfb1HGc/PRqD2AFk3Vg==", - "dev": true, - "requires": { - "css-declaration-sorter": "^6.0.3", - "cssnano-utils": "^2.0.1", - "postcss-calc": "^8.0.0", - "postcss-colormin": "^5.1.1", - "postcss-convert-values": "^5.0.1", - "postcss-discard-comments": "^5.0.1", - "postcss-discard-duplicates": "^5.0.1", - "postcss-discard-empty": "^5.0.1", - "postcss-discard-overridden": "^5.0.1", - "postcss-merge-longhand": "^5.0.2", - "postcss-merge-rules": "^5.0.1", - "postcss-minify-font-values": "^5.0.1", - "postcss-minify-gradients": "^5.0.1", - "postcss-minify-params": "^5.0.1", - "postcss-minify-selectors": "^5.1.0", - "postcss-normalize-charset": "^5.0.1", - "postcss-normalize-display-values": "^5.0.1", - "postcss-normalize-positions": "^5.0.1", - "postcss-normalize-repeat-style": "^5.0.1", - "postcss-normalize-string": "^5.0.1", - "postcss-normalize-timing-functions": "^5.0.1", - "postcss-normalize-unicode": "^5.0.1", - "postcss-normalize-url": "^5.0.1", - "postcss-normalize-whitespace": "^5.0.1", - "postcss-ordered-values": "^5.0.1", - "postcss-reduce-initial": "^5.0.1", - "postcss-reduce-transforms": "^5.0.1", - "postcss-svgo": "^5.0.1", - "postcss-unique-selectors": "^5.0.1" - } - }, - "cssnano-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-2.0.1.tgz", - "integrity": "sha512-i8vLRZTnEH9ubIyfdZCAdIdgnHAUeQeByEeQ2I7oTilvP9oHO6RScpeq3GsFUVqeB8uZgOQ9pw8utofNn32hhQ==", - "dev": true - }, - "csso": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", - "dev": true, - "requires": { - "css-tree": "^1.1.2" - } - }, "cssom": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", @@ -2613,21 +2430,13 @@ } }, "enhanced-resolve": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.3.1.tgz", - "integrity": "sha512-G1XD3MRGrGfNcf6Hg0LVZG7GIKcYkbfHa5QMxt1HDUTdYoXH0JR1xXyg+MaKLF73E9A27uWNVxvFivNRYeUB6w==", + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz", + "integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==", "dev": true, "requires": { "graceful-fs": "^4.2.4", - "tapable": "^2.0.0" - }, - "dependencies": { - "tapable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.1.1.tgz", - "integrity": "sha512-Wib1S8m2wdpLbmQz0RBEVosIyvb/ykfKXf3ZIDqvWoMg/zTNm6G/tDSuUM61J1kNCDXWJrLHGSFeMhAG+gAGpQ==", - "dev": true - } + "tapable": "^2.2.0" } }, "enquirer": { @@ -2660,44 +2469,11 @@ "string-template": "~0.2.1" } }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } + "es-module-lexer": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.4.1.tgz", + "integrity": "sha512-ooYciCUtfw6/d2w56UVeqHPcoCFAiJdz5XOkYpv/Txl1HMUozpXjz/2RIQgqwKdXNDPSF1W7mJCFse3G+HDyAA==", + "dev": true }, "es5-ext": { "version": "0.10.53", @@ -2731,6 +2507,65 @@ "ext": "^1.1.2" } }, + "esbuild": { + "version": "0.11.23", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.11.23.tgz", + "integrity": "sha512-iaiZZ9vUF5wJV8ob1tl+5aJTrwDczlvGP0JoMmnpC2B0ppiMCu8n8gmy5ZTGl5bcG081XBVn+U+jP+mPFm5T5Q==", + "dev": true + }, + "esbuild-loader": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-2.13.1.tgz", + "integrity": "sha512-Tzc5nB5tVUmigXz6m4j1OYozJCjdix7E9vtd5RaE54fqz2Rz34Is9S8FbAf8uqR4xvQUBAXIi6Jkn1OeMxw2aQ==", + "dev": true, + "requires": { + "esbuild": "^0.11.19", + "joycon": "^3.0.1", + "json5": "^2.2.0", + "loader-utils": "^2.0.0", + "tapable": "^2.2.0", + "type-fest": "^1.0.1", + "webpack-sources": "^2.2.0" + }, + "dependencies": { + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "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 + }, + "webpack-sources": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.0.tgz", + "integrity": "sha512-WyOdtwSvOML1kbgtXbTDnEW0jkJ7hZr/bDByIwszhWd/4XX1A3XMkrbFMsuH4+/MfLlZCUzlAdg4r7jaGKEIgQ==", + "dev": true, + "requires": { + "source-list-map": "^2.0.1", + "source-map": "^0.6.1" + } + } + } + }, "escalade": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.0.1.tgz", @@ -2816,9 +2651,9 @@ "dev": true }, "events": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz", - "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "dev": true }, "execa": { @@ -3598,12 +3433,6 @@ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, - "hex-color-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", - "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==", - "dev": true - }, "homedir-polyfill": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", @@ -3619,18 +3448,6 @@ "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=", "dev": true }, - "hsl-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", - "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=", - "dev": true - }, - "hsla-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", - "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=", - "dev": true - }, "html-encoding-sniffer": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", @@ -3682,20 +3499,16 @@ } }, "html-webpack-plugin": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.3.0.tgz", - "integrity": "sha512-C0fzKN8yQoVLTelcJxZfJCE+aAvQiY2VUf3UuKrR4a9k5UMWYOtpDLsaXwATbcVCnI05hUS7L9ULQHWLZhyi3w==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.3.1.tgz", + "integrity": "sha512-rZsVvPXUYFyME0cuGkyOHfx9hmkFa4pWfxY/mdY38PsBEaVNsRoA+Id+8z6DBDgyv3zaw6XQszdF8HLwfQvcdQ==", "dev": true, "requires": { "@types/html-minifier-terser": "^5.0.0", - "@types/tapable": "^1.0.5", - "@types/webpack": "^4.41.8", "html-minifier-terser": "^5.0.1", - "loader-utils": "^1.2.3", - "lodash": "^4.17.15", + "lodash": "^4.17.20", "pretty-error": "^2.1.1", - "tapable": "^1.1.3", - "util.promisify": "1.0.0" + "tapable": "^2.0.0" } }, "htmlparser2": { @@ -3886,24 +3699,6 @@ "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==" }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "dependencies": { - "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 - } - } - }, "import-local": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", @@ -4016,18 +3811,6 @@ "is-windows": "^1.0.1" } }, - "is-absolute-url": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", - "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", - "dev": true - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -4037,34 +3820,6 @@ "binary-extensions": "^2.0.0" } }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, - "is-color-stop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", - "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=", - "dev": true, - "requires": { - "css-color-names": "^0.0.4", - "hex-color-regex": "^1.1.0", - "hsl-regex": "^1.0.0", - "hsla-regex": "^1.0.0", - "rgb-regex": "^1.0.1", - "rgba-regex": "^1.0.0" - }, - "dependencies": { - "css-color-names": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", - "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", - "dev": true - } - } - }, "is-core-module": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", @@ -4074,12 +3829,6 @@ "has": "^1.0.3" } }, - "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-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -4132,15 +3881,6 @@ "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=", "dev": true }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, "is-relative": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", @@ -4150,27 +3890,12 @@ "is-unc-path": "^1.0.0" } }, - "is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", - "dev": true - }, "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 }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -4245,14 +3970,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.0.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.0.2.tgz", + "integrity": "sha512-EoBdilOTTyOgmHXtw/cPc+ZrCA0KJMrkXzkrPGNwLmnvvlN1nj7MPrxpT7m+otSv2e1TLaVffzDnE/LB14zJMg==", "dev": true, "requires": { "@types/node": "*", "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" + "supports-color": "^8.0.0" }, "dependencies": { "has-flag": { @@ -4262,9 +3987,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" @@ -4272,6 +3997,12 @@ } } }, + "joycon": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.0.1.tgz", + "integrity": "sha512-SJcJNBg32dGgxhPtM0wQqxqV0ax9k/9TaUskGDSJkSFSQOEWWvQ3zzWdGQRIUry2j1zA5+ReH13t0Mf3StuVZA==", + "dev": true + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -4359,12 +4090,6 @@ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "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", @@ -4424,12 +4149,6 @@ "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true }, - "klona": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.4.tgz", - "integrity": "sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA==", - "dev": true - }, "leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -4504,12 +4223,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 - }, "livereload-js": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.4.0.tgz", @@ -4517,9 +4230,9 @@ "dev": true }, "loader-runner": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.1.0.tgz", - "integrity": "sha512-oR4lB4WvwFoC70ocraKhn5nkKSs23t57h9udUgw8o0iH8hMXeEoRuUgfcvgUwAJ1ZpRqBvcou4N2SMvM1DwMrA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", + "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==", "dev": true }, "loader-utils": { @@ -4577,24 +4290,12 @@ "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", "dev": true }, - "lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", - "dev": true - }, "lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", "dev": true }, - "lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", - "dev": true - }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -4646,12 +4347,6 @@ "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", "dev": true }, - "mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", - "dev": true - }, "merge-options": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-2.0.0.tgz", @@ -4837,12 +4532,6 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "nanoid": { - "version": "3.1.23", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz", - "integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==", - "dev": true - }, "neo-async": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", @@ -4900,12 +4589,6 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, - "normalize-url": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", - "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", - "dev": true - }, "npm-run-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-1.0.0.tgz", @@ -4915,12 +4598,12 @@ } }, "nth-check": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", - "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.0.tgz", + "integrity": "sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q==", "dev": true, "requires": { - "boolbase": "~1.0.0" + "boolbase": "^1.0.0" } }, "nwsapi": { @@ -4940,12 +4623,6 @@ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - }, "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", @@ -4982,16 +4659,6 @@ "isobject": "^3.0.0" } }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, "object.map": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", @@ -5096,15 +4763,6 @@ "tslib": "^1.10.0" } }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, "parse-filepath": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", @@ -5116,18 +4774,6 @@ "path-root": "^0.1.1" } }, - "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" - } - }, "parse-passwd": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", @@ -5192,12 +4838,6 @@ "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", "dev": true }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -5243,745 +4883,168 @@ "integrity": "sha512-Vy9eH1dRD9wHjYt/QqXcTz+RnX/zg53xK+KljFSX30PvdDMb2z+c6uDUeblUGqqJgz3QFsdlA0IJvHziPmWtQg==", "dev": true }, - "postcss": { - "version": "8.2.15", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.15.tgz", - "integrity": "sha512-2zO3b26eJD/8rb106Qu2o7Qgg52ND5HPjcyQiK2B98O388h43A448LCslC0dI2P97wCAQRJsFvwTRcXxTKds+Q==", + "postcss-modules-extract-imports": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", + "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", "dev": true, "requires": { - "colorette": "^1.2.2", - "nanoid": "^3.1.23", - "source-map": "^0.6.1" + "postcss": "^7.0.5" }, "dependencies": { - "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 + "postcss": { + "version": "7.0.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", + "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } }, "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 + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } } } }, - "postcss-calc": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.0.0.tgz", - "integrity": "sha512-5NglwDrcbiy8XXfPM11F3HeC6hoT9W7GUH/Zi5U/p7u3Irv4rHhdDcIZwG0llHXV4ftsBjpfWMXAnXNl4lnt8g==", + "postcss-modules-local-by-default": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.2.tgz", + "integrity": "sha512-jM/V8eqM4oJ/22j0gx4jrp63GSvDH6v86OqyTHHUvk4/k1vceipZsaymiZ5PvocqZOl5SFHiFJqjs3la0wnfIQ==", "dev": true, "requires": { + "icss-utils": "^4.1.1", + "postcss": "^7.0.16", "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.0.2" - } - }, - "postcss-colormin": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.1.1.tgz", - "integrity": "sha512-SyTmqKKN6PyYNeeKEC0hqIP5CDuprO1hHurdW1aezDyfofDUOn7y7MaxcolbsW3oazPwFiGiY30XRiW1V4iZpA==", - "dev": true, - "requires": { - "browserslist": "^4.16.0", - "colord": "^2.0.0", - "postcss-value-parser": "^4.1.0" + "postcss-value-parser": "^4.0.0" }, "dependencies": { - "browserslist": { - "version": "4.16.6", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", - "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "postcss": { + "version": "7.0.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", + "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001219", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.723", - "escalade": "^3.1.1", - "node-releases": "^1.1.71" + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" } }, - "caniuse-lite": { - "version": "1.0.30001230", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001230.tgz", - "integrity": "sha512-5yBd5nWCBS+jWKTcHOzXwo5xzcj4ePE/yjtkZyUV1BTUmrBaA9MRGC+e7mxnqXSA90CmCA8L3eKLaSUkt099IQ==", - "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 - }, - "electron-to-chromium": { - "version": "1.3.740", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.740.tgz", - "integrity": "sha512-Mi2m55JrX2BFbNZGKYR+2ItcGnR4O5HhrvgoRRyZQlaMGQULqDhoGkLWHzJoshSzi7k1PUofxcDbNhlFrDZNhg==", - "dev": true - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "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 }, - "node-releases": { - "version": "1.1.72", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", - "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", - "dev": true + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } } } }, - "postcss-convert-values": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.0.1.tgz", - "integrity": "sha512-C3zR1Do2BkKkCgC0g3sF8TS0koF2G+mN8xxayZx3f10cIRmTaAnpgpRQZjNekTZxM2ciSPoh2IWJm0VZx8NoQg==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-discard-comments": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.0.1.tgz", - "integrity": "sha512-lgZBPTDvWrbAYY1v5GYEv8fEO/WhKOu/hmZqmCYfrpD6eyDWWzAOsl2rF29lpvziKO02Gc5GJQtlpkTmakwOWg==", - "dev": true - }, - "postcss-discard-duplicates": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.0.1.tgz", - "integrity": "sha512-svx747PWHKOGpAXXQkCc4k/DsWo+6bc5LsVrAsw+OU+Ibi7klFZCyX54gjYzX4TH+f2uzXjRviLARxkMurA2bA==", - "dev": true - }, - "postcss-discard-empty": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.0.1.tgz", - "integrity": "sha512-vfU8CxAQ6YpMxV2SvMcMIyF2LX1ZzWpy0lqHDsOdaKKLQVQGVP1pzhrI9JlsO65s66uQTfkQBKBD/A5gp9STFw==", - "dev": true - }, - "postcss-discard-overridden": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.0.1.tgz", - "integrity": "sha512-Y28H7y93L2BpJhrdUR2SR2fnSsT+3TVx1NmVQLbcnZWwIUpJ7mfcTC6Za9M2PG6w8j7UQRfzxqn8jU2VwFxo3Q==", - "dev": true - }, - "postcss-loader": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-5.3.0.tgz", - "integrity": "sha512-/+Z1RAmssdiSLgIZwnJHwBMnlABPgF7giYzTN2NOfr9D21IJZ4mQC1R2miwp80zno9M4zMD/umGI8cR+2EL5zw==", + "postcss-modules-scope": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", + "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", "dev": true, "requires": { - "cosmiconfig": "^7.0.0", - "klona": "^2.0.4", - "semver": "^7.3.4" + "postcss": "^7.0.6", + "postcss-selector-parser": "^6.0.0" }, "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "postcss": { + "version": "7.0.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", + "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", "dev": true, "requires": { - "yallist": "^4.0.0" + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" } }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "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 + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dev": true, "requires": { - "lru-cache": "^6.0.0" + "has-flag": "^3.0.0" } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true } } }, - "postcss-merge-longhand": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.0.2.tgz", - "integrity": "sha512-BMlg9AXSI5G9TBT0Lo/H3PfUy63P84rVz3BjCFE9e9Y9RXQZD3+h3YO1kgTNsNJy7bBc1YQp8DmSnwLIW5VPcw==", - "dev": true, - "requires": { - "css-color-names": "^1.0.1", - "postcss-value-parser": "^4.1.0", - "stylehacks": "^5.0.1" - } - }, - "postcss-merge-rules": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.0.1.tgz", - "integrity": "sha512-UR6R5Ph0c96QB9TMBH3ml8/kvPCThPHepdhRqAbvMRDRHQACPC8iM5NpfIC03+VRMZTGXy4L/BvFzcDFCgb+fA==", + "postcss-modules-values": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz", + "integrity": "sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==", "dev": true, "requires": { - "browserslist": "^4.16.0", - "caniuse-api": "^3.0.0", - "cssnano-utils": "^2.0.1", - "postcss-selector-parser": "^6.0.5", - "vendors": "^1.0.3" + "icss-utils": "^4.0.0", + "postcss": "^7.0.6" }, "dependencies": { - "browserslist": { - "version": "4.16.6", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", - "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "postcss": { + "version": "7.0.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", + "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001219", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.723", - "escalade": "^3.1.1", - "node-releases": "^1.1.71" + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" } }, - "caniuse-lite": { - "version": "1.0.30001230", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001230.tgz", - "integrity": "sha512-5yBd5nWCBS+jWKTcHOzXwo5xzcj4ePE/yjtkZyUV1BTUmrBaA9MRGC+e7mxnqXSA90CmCA8L3eKLaSUkt099IQ==", - "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 - }, - "electron-to-chromium": { - "version": "1.3.740", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.740.tgz", - "integrity": "sha512-Mi2m55JrX2BFbNZGKYR+2ItcGnR4O5HhrvgoRRyZQlaMGQULqDhoGkLWHzJoshSzi7k1PUofxcDbNhlFrDZNhg==", - "dev": true - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "node-releases": { - "version": "1.1.72", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", - "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", + "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 }, - "postcss-selector-parser": { - "version": "6.0.6", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz", - "integrity": "sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==", + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dev": true, "requires": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" + "has-flag": "^3.0.0" } } } }, - "postcss-minify-font-values": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.0.1.tgz", - "integrity": "sha512-7JS4qIsnqaxk+FXY1E8dHBDmraYFWmuL6cgt0T1SWGRO5bzJf8sUoelwa4P88LEWJZweHevAiDKxHlofuvtIoA==", + "postcss-selector-parser": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz", + "integrity": "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==", "dev": true, "requires": { - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-minify-gradients": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.0.1.tgz", - "integrity": "sha512-odOwBFAIn2wIv+XYRpoN2hUV3pPQlgbJ10XeXPq8UY2N+9ZG42xu45lTn/g9zZ+d70NKSQD6EOi6UiCMu3FN7g==", - "dev": true, - "requires": { - "cssnano-utils": "^2.0.1", - "is-color-stop": "^1.1.0", - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-minify-params": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.0.1.tgz", - "integrity": "sha512-4RUC4k2A/Q9mGco1Z8ODc7h+A0z7L7X2ypO1B6V8057eVK6mZ6xwz6QN64nHuHLbqbclkX1wyzRnIrdZehTEHw==", - "dev": true, - "requires": { - "alphanum-sort": "^1.0.2", - "browserslist": "^4.16.0", - "cssnano-utils": "^2.0.1", - "postcss-value-parser": "^4.1.0", - "uniqs": "^2.0.0" - }, - "dependencies": { - "browserslist": { - "version": "4.16.6", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", - "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001219", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.723", - "escalade": "^3.1.1", - "node-releases": "^1.1.71" - } - }, - "caniuse-lite": { - "version": "1.0.30001230", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001230.tgz", - "integrity": "sha512-5yBd5nWCBS+jWKTcHOzXwo5xzcj4ePE/yjtkZyUV1BTUmrBaA9MRGC+e7mxnqXSA90CmCA8L3eKLaSUkt099IQ==", - "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 - }, - "electron-to-chromium": { - "version": "1.3.740", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.740.tgz", - "integrity": "sha512-Mi2m55JrX2BFbNZGKYR+2ItcGnR4O5HhrvgoRRyZQlaMGQULqDhoGkLWHzJoshSzi7k1PUofxcDbNhlFrDZNhg==", - "dev": true - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "node-releases": { - "version": "1.1.72", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", - "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", - "dev": true - } - } - }, - "postcss-minify-selectors": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.1.0.tgz", - "integrity": "sha512-NzGBXDa7aPsAcijXZeagnJBKBPMYLaJJzB8CQh6ncvyl2sIndLVWfbcDi0SBjRWk5VqEjXvf8tYwzoKf4Z07og==", - "dev": true, - "requires": { - "alphanum-sort": "^1.0.2", - "postcss-selector-parser": "^6.0.5" - }, - "dependencies": { - "postcss-selector-parser": { - "version": "6.0.6", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz", - "integrity": "sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==", - "dev": true, - "requires": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - } - } - } - }, - "postcss-modules-extract-imports": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", - "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", - "dev": true, - "requires": { - "postcss": "^7.0.5" - }, - "dependencies": { - "postcss": { - "version": "7.0.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", - "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", - "dev": true, - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "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 - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "postcss-modules-local-by-default": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.2.tgz", - "integrity": "sha512-jM/V8eqM4oJ/22j0gx4jrp63GSvDH6v86OqyTHHUvk4/k1vceipZsaymiZ5PvocqZOl5SFHiFJqjs3la0wnfIQ==", - "dev": true, - "requires": { - "icss-utils": "^4.1.1", - "postcss": "^7.0.16", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.0.0" - }, - "dependencies": { - "postcss": { - "version": "7.0.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", - "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", - "dev": true, - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "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 - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "postcss-modules-scope": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", - "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", - "dev": true, - "requires": { - "postcss": "^7.0.6", - "postcss-selector-parser": "^6.0.0" - }, - "dependencies": { - "postcss": { - "version": "7.0.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", - "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", - "dev": true, - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "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 - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "postcss-modules-values": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz", - "integrity": "sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==", - "dev": true, - "requires": { - "icss-utils": "^4.0.0", - "postcss": "^7.0.6" - }, - "dependencies": { - "postcss": { - "version": "7.0.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", - "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", - "dev": true, - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "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 - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "postcss-normalize-charset": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.0.1.tgz", - "integrity": "sha512-6J40l6LNYnBdPSk+BHZ8SF+HAkS4q2twe5jnocgd+xWpz/mx/5Sa32m3W1AA8uE8XaXN+eg8trIlfu8V9x61eg==", - "dev": true - }, - "postcss-normalize-display-values": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.0.1.tgz", - "integrity": "sha512-uupdvWk88kLDXi5HEyI9IaAJTE3/Djbcrqq8YgjvAVuzgVuqIk3SuJWUisT2gaJbZm1H9g5k2w1xXilM3x8DjQ==", - "dev": true, - "requires": { - "cssnano-utils": "^2.0.1", - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-normalize-positions": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.0.1.tgz", - "integrity": "sha512-rvzWAJai5xej9yWqlCb1OWLd9JjW2Ex2BCPzUJrbaXmtKtgfL8dBMOOMTX6TnvQMtjk3ei1Lswcs78qKO1Skrg==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-normalize-repeat-style": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.0.1.tgz", - "integrity": "sha512-syZ2itq0HTQjj4QtXZOeefomckiV5TaUO6ReIEabCh3wgDs4Mr01pkif0MeVwKyU/LHEkPJnpwFKRxqWA/7O3w==", - "dev": true, - "requires": { - "cssnano-utils": "^2.0.1", - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-normalize-string": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.0.1.tgz", - "integrity": "sha512-Ic8GaQ3jPMVl1OEn2U//2pm93AXUcF3wz+OriskdZ1AOuYV25OdgS7w9Xu2LO5cGyhHCgn8dMXh9bO7vi3i9pA==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-normalize-timing-functions": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.0.1.tgz", - "integrity": "sha512-cPcBdVN5OsWCNEo5hiXfLUnXfTGtSFiBU9SK8k7ii8UD7OLuznzgNRYkLZow11BkQiiqMcgPyh4ZqXEEUrtQ1Q==", - "dev": true, - "requires": { - "cssnano-utils": "^2.0.1", - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-normalize-unicode": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.0.1.tgz", - "integrity": "sha512-kAtYD6V3pK0beqrU90gpCQB7g6AOfP/2KIPCVBKJM2EheVsBQmx/Iof+9zR9NFKLAx4Pr9mDhogB27pmn354nA==", - "dev": true, - "requires": { - "browserslist": "^4.16.0", - "postcss-value-parser": "^4.1.0" - }, - "dependencies": { - "browserslist": { - "version": "4.16.6", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", - "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001219", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.723", - "escalade": "^3.1.1", - "node-releases": "^1.1.71" - } - }, - "caniuse-lite": { - "version": "1.0.30001230", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001230.tgz", - "integrity": "sha512-5yBd5nWCBS+jWKTcHOzXwo5xzcj4ePE/yjtkZyUV1BTUmrBaA9MRGC+e7mxnqXSA90CmCA8L3eKLaSUkt099IQ==", - "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 - }, - "electron-to-chromium": { - "version": "1.3.740", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.740.tgz", - "integrity": "sha512-Mi2m55JrX2BFbNZGKYR+2ItcGnR4O5HhrvgoRRyZQlaMGQULqDhoGkLWHzJoshSzi7k1PUofxcDbNhlFrDZNhg==", - "dev": true - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "node-releases": { - "version": "1.1.72", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", - "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", - "dev": true - } - } - }, - "postcss-normalize-url": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.0.1.tgz", - "integrity": "sha512-hkbG0j58Z1M830/CJ73VsP7gvlG1yF+4y7Fd1w4tD2c7CaA2Psll+pQ6eQhth9y9EaqZSLzamff/D0MZBMbYSg==", - "dev": true, - "requires": { - "is-absolute-url": "^3.0.3", - "normalize-url": "^4.5.0", - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-normalize-whitespace": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.0.1.tgz", - "integrity": "sha512-iPklmI5SBnRvwceb/XH568yyzK0qRVuAG+a1HFUsFRf11lEJTiQQa03a4RSCQvLKdcpX7XsI1Gen9LuLoqwiqA==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-ordered-values": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.0.1.tgz", - "integrity": "sha512-6mkCF5BQ25HvEcDfrMHCLLFHlraBSlOXFnQMHYhSpDO/5jSR1k8LdEXOkv+7+uzW6o6tBYea1Km0wQSRkPJkwA==", - "dev": true, - "requires": { - "cssnano-utils": "^2.0.1", - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-reduce-initial": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.0.1.tgz", - "integrity": "sha512-zlCZPKLLTMAqA3ZWH57HlbCjkD55LX9dsRyxlls+wfuRfqCi5mSlZVan0heX5cHr154Dq9AfbH70LyhrSAezJw==", - "dev": true, - "requires": { - "browserslist": "^4.16.0", - "caniuse-api": "^3.0.0" - }, - "dependencies": { - "browserslist": { - "version": "4.16.6", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", - "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001219", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.723", - "escalade": "^3.1.1", - "node-releases": "^1.1.71" - } - }, - "caniuse-lite": { - "version": "1.0.30001230", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001230.tgz", - "integrity": "sha512-5yBd5nWCBS+jWKTcHOzXwo5xzcj4ePE/yjtkZyUV1BTUmrBaA9MRGC+e7mxnqXSA90CmCA8L3eKLaSUkt099IQ==", - "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 - }, - "electron-to-chromium": { - "version": "1.3.740", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.740.tgz", - "integrity": "sha512-Mi2m55JrX2BFbNZGKYR+2ItcGnR4O5HhrvgoRRyZQlaMGQULqDhoGkLWHzJoshSzi7k1PUofxcDbNhlFrDZNhg==", - "dev": true - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "node-releases": { - "version": "1.1.72", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", - "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", - "dev": true - } - } - }, - "postcss-reduce-transforms": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.0.1.tgz", - "integrity": "sha512-a//FjoPeFkRuAguPscTVmRQUODP+f3ke2HqFNgGPwdYnpeC29RZdCBvGRGTsKpMURb/I3p6jdKoBQ2zI+9Q7kA==", - "dev": true, - "requires": { - "cssnano-utils": "^2.0.1", - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-selector-parser": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz", - "integrity": "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==", - "dev": true, - "requires": { - "cssesc": "^3.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, - "postcss-svgo": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.0.1.tgz", - "integrity": "sha512-cD7DFo6tF9i5eWvwtI4irKOHCpmASFS0xvZ5EQIgEdA1AWfM/XiHHY/iss0gcKHhkqwgYmuo2M0KhJLd5Us6mg==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.1.0", - "svgo": "^2.3.0" - } - }, - "postcss-unique-selectors": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.0.1.tgz", - "integrity": "sha512-gwi1NhHV4FMmPn+qwBNuot1sG1t2OmacLQ/AX29lzyggnjd+MnVD5uqQmpXO3J17KGL2WAxQruj1qTd3H0gG/w==", - "dev": true, - "requires": { - "alphanum-sort": "^1.0.2", - "postcss-selector-parser": "^6.0.5", - "uniqs": "^2.0.0" - }, - "dependencies": { - "postcss-selector-parser": { - "version": "6.0.6", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz", - "integrity": "sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==", - "dev": true, - "requires": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - } - } + "cssesc": "^3.0.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" } }, "postcss-value-parser": { @@ -5997,13 +5060,13 @@ "dev": true }, "pretty-error": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz", - "integrity": "sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.2.tgz", + "integrity": "sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw==", "dev": true, "requires": { - "renderkid": "^2.0.1", - "utila": "~0.4" + "lodash": "^4.17.20", + "renderkid": "^2.0.4" } }, "private": { @@ -6242,61 +5305,75 @@ } }, "renderkid": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.3.tgz", - "integrity": "sha512-z8CLQp7EZBPCwCnncgf9C4XAi3WR0dv+uWu/PjIyhhAb5d6IJ/QZqlHFprHeKT+59//V6BNUsLbvN8+2LarxGA==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.6.tgz", + "integrity": "sha512-GIis2GBr/ho0pFNf57D4XM4+PgnQuTii0WCPjEZmZfKivzUfGuRdjN2aQYtYMiNggHmNyBve+thFnNR1iBRcKg==", "dev": true, "requires": { - "css-select": "^1.1.0", - "dom-converter": "^0.2", - "htmlparser2": "^3.3.0", - "strip-ansi": "^3.0.0", - "utila": "^0.4.0" + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^6.0.0" }, "dependencies": { - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", - "dev": true + "dom-serializer": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", + "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + } }, "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.0.tgz", + "integrity": "sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA==", "dev": true, "requires": { - "domelementtype": "1" + "domelementtype": "^2.2.0" + }, + "dependencies": { + "domelementtype": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", + "dev": true + } } }, "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.7.0.tgz", + "integrity": "sha512-8eaHa17IwJUPAiB+SoTYBo5mCdeMgdcAoXJ59m6DT1vw+5iLS3gNoqYaRowaBKtGVrOF1Jz4yDTgYKLK2kvfJg==", "dev": true, "requires": { - "dom-serializer": "0", - "domelementtype": "1" + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "dependencies": { + "domelementtype": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", + "dev": true + } } }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", - "dev": true - }, "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", "dev": true, "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" } } } @@ -6510,18 +5587,6 @@ "integrity": "sha1-mUWygD8hni96ygCtuLyfZA+ELJo=", "dev": true }, - "rgb-regex": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", - "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=", - "dev": true - }, - "rgba-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", - "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=", - "dev": true - }, "run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -6740,12 +5805,6 @@ "tweetnacl": "~0.14.0" } }, - "stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", - "dev": true - }, "stealthy-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", @@ -6783,27 +5842,7 @@ "requires": { "ansi-regex": "^5.0.0" } - } - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + } } }, "string_decoder": { @@ -6813,12 +5852,12 @@ "dev": true }, "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "^5.0.0" } }, "strip-eof": { @@ -6832,71 +5871,6 @@ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true }, - "stylehacks": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.0.1.tgz", - "integrity": "sha512-Es0rVnHIqbWzveU1b24kbw92HsebBepxfcqe5iix7t9j0PQqhs0IxXVXv0pY2Bxa08CgMkzD6OWql7kbGOuEdA==", - "dev": true, - "requires": { - "browserslist": "^4.16.0", - "postcss-selector-parser": "^6.0.4" - }, - "dependencies": { - "browserslist": { - "version": "4.16.6", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", - "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001219", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.723", - "escalade": "^3.1.1", - "node-releases": "^1.1.71" - } - }, - "caniuse-lite": { - "version": "1.0.30001230", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001230.tgz", - "integrity": "sha512-5yBd5nWCBS+jWKTcHOzXwo5xzcj4ePE/yjtkZyUV1BTUmrBaA9MRGC+e7mxnqXSA90CmCA8L3eKLaSUkt099IQ==", - "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 - }, - "electron-to-chromium": { - "version": "1.3.740", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.740.tgz", - "integrity": "sha512-Mi2m55JrX2BFbNZGKYR+2ItcGnR4O5HhrvgoRRyZQlaMGQULqDhoGkLWHzJoshSzi7k1PUofxcDbNhlFrDZNhg==", - "dev": true - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "node-releases": { - "version": "1.1.72", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", - "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", - "dev": true - }, - "postcss-selector-parser": { - "version": "6.0.6", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz", - "integrity": "sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==", - "dev": true, - "requires": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - } - } - } - }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -6906,143 +5880,6 @@ "has-flag": "^3.0.0" } }, - "svgo": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.3.0.tgz", - "integrity": "sha512-fz4IKjNO6HDPgIQxu4IxwtubtbSfGEAJUq/IXyTPIkGhWck/faiiwfkvsB8LnBkKLvSoyNNIY6d13lZprJMc9Q==", - "dev": true, - "requires": { - "@trysound/sax": "0.1.1", - "chalk": "^4.1.0", - "commander": "^7.1.0", - "css-select": "^3.1.2", - "css-tree": "^1.1.2", - "csso": "^4.2.0", - "stable": "^0.1.8" - }, - "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.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", - "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 - }, - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true - }, - "css-select": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-3.1.2.tgz", - "integrity": "sha512-qmss1EihSuBNWNNhHjxzxSfJoFBM/lERB/Q4EnsJQQC62R2evJDW481091oAdOr9uh46/0n4nrg0It5cAnj1RA==", - "dev": true, - "requires": { - "boolbase": "^1.0.0", - "css-what": "^4.0.0", - "domhandler": "^4.0.0", - "domutils": "^2.4.3", - "nth-check": "^2.0.0" - } - }, - "css-what": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-4.0.0.tgz", - "integrity": "sha512-teijzG7kwYfNVsUh2H/YN62xW3KK9YhXEgSlbxMlcyjPNvdKJqFx5lrwlJgoFP1ZHlB89iGDlo/JyshKeRhv5A==", - "dev": true - }, - "dom-serializer": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", - "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", - "dev": true, - "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - } - }, - "domelementtype": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", - "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", - "dev": true - }, - "domhandler": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.0.tgz", - "integrity": "sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA==", - "dev": true, - "requires": { - "domelementtype": "^2.2.0" - } - }, - "domutils": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.6.0.tgz", - "integrity": "sha512-y0BezHuy4MDYxh6OvolXYsH+1EMGmFbwv5FKW7ovwMG6zTPWqNPq3WF9ayZssFq+UlKdffGLbOEaghNdaOm1WA==", - "dev": true, - "requires": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.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 - }, - "nth-check": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.0.tgz", - "integrity": "sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q==", - "dev": true, - "requires": { - "boolbase": "^1.0.0" - } - }, - "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" - } - } - } - }, "symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -7062,9 +5899,9 @@ } }, "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", + "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", "dev": true }, "terser": { @@ -7093,23 +5930,23 @@ } }, "terser-webpack-plugin": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.0.3.tgz", - "integrity": "sha512-zFdGk8Lh9ZJGPxxPE6jwysOlATWB8GMW8HcfGULWA/nPal+3VdATflQvSBSLQJRCmYZnfFJl6vkRTiwJGNgPiQ==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.3.tgz", + "integrity": "sha512-cxGbMqr6+A2hrIB5ehFIF+F/iST5ZOxvOmy9zih9ySbP1C2oEWQSOUS+2SNBTjzx5xLKO4xnod9eywdfq1Nb9A==", "dev": true, "requires": { - "jest-worker": "^26.6.1", - "p-limit": "^3.0.2", + "jest-worker": "^27.0.2", + "p-limit": "^3.1.0", "schema-utils": "^3.0.0", "serialize-javascript": "^5.0.1", "source-map": "^0.6.1", - "terser": "^5.3.8" + "terser": "^5.7.0" }, "dependencies": { "@types/json-schema": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", - "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==", + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", "dev": true }, "ajv": { @@ -7137,12 +5974,12 @@ "dev": true }, "p-limit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz", - "integrity": "sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "requires": { - "p-try": "^2.0.0" + "yocto-queue": "^0.1.0" } }, "schema-utils": { @@ -7163,9 +6000,9 @@ "dev": true }, "terser": { - "version": "5.3.8", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.3.8.tgz", - "integrity": "sha512-zVotuHoIfnYjtlurOouTazciEfL7V38QMAOhGqpXDEg6yT13cF4+fEP9b0rrCEQTn+tT46uxgFsTZzhygk+CzQ==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.7.0.tgz", + "integrity": "sha512-HP5/9hp2UaZt5fYkuhNBR8YyRcT8juw8+uFbAme53iN9hblvKnLUTKkmwJG6ocWpIKf8UK4DoeWG4ty0J6S6/g==", "dev": true, "requires": { "commander": "^2.20.0", @@ -7183,12 +6020,6 @@ } } }, - "timsort": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", - "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", - "dev": true - }, "tiny-lr": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-1.1.1.tgz", @@ -7359,6 +6190,12 @@ "prelude-ls": "~1.1.2" } }, + "type-fest": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.2.0.tgz", + "integrity": "sha512-++0N6KyAj0t2webXst0PE0xuXb4Dv3z1Z+4SGzK+j/epeWBZCfkQbkW/ezscZwpinmBQ5wu/l4TqagKSVcAGCA==", + "dev": true + }, "typescript": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", @@ -7427,12 +6264,6 @@ "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", "dev": true }, - "uniqs": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", - "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", - "dev": true - }, "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -7483,16 +6314,6 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, - "util.promisify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", - "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "object.getownpropertydescriptors": "^2.0.3" - } - }, "utila": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", @@ -7524,12 +6345,6 @@ "homedir-polyfill": "^1.0.1" } }, - "vendors": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz", - "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==", - "dev": true - }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", @@ -7560,9 +6375,9 @@ } }, "watchpack": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.0.1.tgz", - "integrity": "sha512-vO8AKGX22ZRo6PiOFM9dC0re8IcKh8Kd/aH2zeqUc6w4/jBGlTy2P7fTC6ekT0NjVeGjgU2dGC5rNstKkeLEQg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.2.0.tgz", + "integrity": "sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA==", "dev": true, "requires": { "glob-to-regexp": "^0.4.1", @@ -7576,41 +6391,40 @@ "dev": true }, "webpack": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.4.0.tgz", - "integrity": "sha512-udpYTyqz8toTTdaOsL2QKPLeZLt2IEm9qY7yTXuFEQhKu5bk0yQD9BtAdVQksmz4jFbbWOiWmm3NHarO0zr/ng==", + "version": "5.38.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.38.1.tgz", + "integrity": "sha512-OqRmYD1OJbHZph6RUMD93GcCZy4Z4wC0ele4FXyYF0J6AxO1vOSuIlU1hkS/lDlR9CDYBz64MZRmdbdnFFoT2g==", "dev": true, "requires": { "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.45", - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-module-context": "1.9.0", - "@webassemblyjs/wasm-edit": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0", - "acorn": "^8.0.4", + "@types/estree": "^0.0.47", + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/wasm-edit": "1.11.0", + "@webassemblyjs/wasm-parser": "1.11.0", + "acorn": "^8.2.1", "browserslist": "^4.14.5", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.3.1", - "eslint-scope": "^5.1.1", + "enhanced-resolve": "^5.8.0", + "es-module-lexer": "^0.4.0", + "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.2.4", "json-parse-better-errors": "^1.0.2", - "loader-runner": "^4.1.0", + "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "pkg-dir": "^4.2.0", "schema-utils": "^3.0.0", - "tapable": "^2.0.0", - "terser-webpack-plugin": "^5.0.3", - "watchpack": "^2.0.0", - "webpack-sources": "^2.1.1" + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.1", + "watchpack": "^2.2.0", + "webpack-sources": "^2.3.0" }, "dependencies": { "@types/json-schema": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", - "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==", + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", "dev": true }, "ajv": { @@ -7632,22 +6446,34 @@ "dev": true }, "browserslist": { - "version": "4.14.7", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.14.7.tgz", - "integrity": "sha512-BSVRLCeG3Xt/j/1cCGj1019Wbty0H+Yvu2AOuZSuoaUWn3RatbL33Cxk+Q4jRMRAbOm0p7SLravLjpnT6s0vzQ==", + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001157", - "colorette": "^1.2.1", - "electron-to-chromium": "^1.3.591", + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", "escalade": "^3.1.1", - "node-releases": "^1.1.66" + "node-releases": "^1.1.71" } }, + "caniuse-lite": { + "version": "1.0.30001236", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001236.tgz", + "integrity": "sha512-o0PRQSrSCGJKCPZcgMzl5fUaj5xHe8qA2m4QRvnyY4e1lITqoNkr7q/Oh1NcpGSy0Th97UZ35yoKcINPoq7YOQ==", + "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 + }, "electron-to-chromium": { - "version": "1.3.592", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.592.tgz", - "integrity": "sha512-kGNowksvqQiPb1pUSQKpd8JFoGPLxYOwduNRCqCxGh/2Q1qE2JdmwouCW41lUzDxOb/2RIV4lR0tVIfboWlO9A==", + "version": "1.3.750", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.750.tgz", + "integrity": "sha512-Eqy9eHNepZxJXT+Pc5++zvEi5nQ6AGikwFYDCYwXUFBr+ynJ6pDG7MzZmwGYCIuXShLJM0n4bq+aoKDmvSGJ8A==", "dev": true }, "escalade": { @@ -7656,25 +6482,6 @@ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "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" - } - }, - "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" - } - }, "neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", @@ -7682,35 +6489,11 @@ "dev": true }, "node-releases": { - "version": "1.1.66", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.66.tgz", - "integrity": "sha512-JHEQ1iWPGK+38VLB2H9ef2otU4l8s3yAMt9Xf934r6+ojCYDMHPMqvCc9TnzfeFSP1QEOeU6YZEd3+De0LTCgg==", - "dev": true - }, - "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" - } - }, - "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==", + "version": "1.1.73", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz", + "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==", "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" - } - }, "schema-utils": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", @@ -7728,16 +6511,10 @@ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, - "tapable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.1.1.tgz", - "integrity": "sha512-Wib1S8m2wdpLbmQz0RBEVosIyvb/ykfKXf3ZIDqvWoMg/zTNm6G/tDSuUM61J1kNCDXWJrLHGSFeMhAG+gAGpQ==", - "dev": true - }, "webpack-sources": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.2.0.tgz", - "integrity": "sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.0.tgz", + "integrity": "sha512-WyOdtwSvOML1kbgtXbTDnEW0jkJ7hZr/bDByIwszhWd/4XX1A3XMkrbFMsuH4+/MfLlZCUzlAdg4r7jaGKEIgQ==", "dev": true, "requires": { "source-list-map": "^2.0.1", @@ -8064,12 +6841,6 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" }, - "yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true - }, "yargs": { "version": "17.0.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.0.1.tgz", @@ -8104,6 +6875,12 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz", "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==", "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true } } } diff --git a/static/package.json b/static/package.json index afc5549e0..fed30c669 100644 --- a/static/package.json +++ b/static/package.json @@ -21,7 +21,7 @@ "babel-loader": "^8.1.0", "comment-json": "^3.0.2", "css-loader": "^3.4.2", - "cssnano": "^5.0.2", + "esbuild-loader": "^2.13.1", "file-loader": "^5.1.0", "file-system": "^2.2.2", "fs-extra": "^9.0.1", @@ -33,8 +33,6 @@ "jambo": "^1.11.0", "jsdom": "^16.4.0", "mini-css-extract-plugin": "^1.6.0", - "postcss": "^8.2.10", - "postcss-loader": "^5.3.0", "resolve-url-loader": "^3.1.1", "sass": "^1.34.0", "sass-loader": "^8.0.2", diff --git a/static/webpack-config.js b/static/webpack-config.js index b82742d85..2b429483f 100644 --- a/static/webpack-config.js +++ b/static/webpack-config.js @@ -5,7 +5,6 @@ const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const HtmlPlugin = require('html-webpack-plugin'); const RemovePlugin = require('remove-files-webpack-plugin'); const { merge } = require('webpack-merge'); -const cssnano = require('cssnano'); module.exports = function () { const jamboConfig = require('./jambo.json'); @@ -92,16 +91,6 @@ module.exports = function () { use: [ MiniCssExtractPlugin.loader, 'css-loader', - { - loader: 'postcss-loader', - options: { - postcssOptions: { - plugins: [ - cssnano({ preset: 'default'}) - ], - }, - }, - }, 'resolve-url-loader', { loader: 'sass-loader', diff --git a/static/webpack/webpack.prod.js b/static/webpack/webpack.prod.js index ca1e1e779..5fff2d793 100644 --- a/static/webpack/webpack.prod.js +++ b/static/webpack/webpack.prod.js @@ -1,3 +1,5 @@ +const { ESBuildMinifyPlugin } = require('esbuild-loader') + module.exports = () => { const InlineAssetHtmlPlugin = require('./InlineAssetHtmlPlugin'); return { @@ -29,6 +31,14 @@ module.exports = () => { } } ] - } + }, + optimization: { + minimizer: [ + new ESBuildMinifyPlugin({ + target: 'es5', + css: true + }) + ] + }, }; } \ No newline at end of file From dee94c16a48755879dcd89405ee94939872d5ad9 Mon Sep 17 00:00:00 2001 From: Christopher Jiang Date: Thu, 10 Jun 2021 11:35:35 -0400 Subject: [PATCH 34/56] Created common partial for pagination --- templates/common-partials/markup/pagination.hbs | 1 + templates/common-partials/script/pagination.hbs | 15 +++++++++++++++ .../vertical-full-page-map/markup/pagination.hbs | 2 +- templates/vertical-grid/markup/pagination.hbs | 2 +- templates/vertical-grid/script/pagination.hbs | 16 +--------------- templates/vertical-map/markup/pagination.hbs | 2 +- .../vertical-standard/markup/pagination.hbs | 2 +- .../vertical-standard/script/pagination.hbs | 16 +--------------- 8 files changed, 22 insertions(+), 34 deletions(-) create mode 100644 templates/common-partials/markup/pagination.hbs create mode 100644 templates/common-partials/script/pagination.hbs diff --git a/templates/common-partials/markup/pagination.hbs b/templates/common-partials/markup/pagination.hbs new file mode 100644 index 000000000..2f1935c3a --- /dev/null +++ b/templates/common-partials/markup/pagination.hbs @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/templates/common-partials/script/pagination.hbs b/templates/common-partials/script/pagination.hbs new file mode 100644 index 000000000..4078f1c6d --- /dev/null +++ b/templates/common-partials/script/pagination.hbs @@ -0,0 +1,15 @@ +ANSWERS.addComponent("Pagination", Object.assign({}, { + container: "#js-answersPagination", + onPaginate: (newPageNumber, oldPageNumber, totalPages) => { + if (window.parentIFrame) { + const paginateMessage = { action: 'paginate' }; + window.parentIFrame.sendMessage(JSON.stringify(paginateMessage)); + } else { + document.documentElement.scrollTop = 0; + document.body.scrollTop = 0; // Safari + } + }, + {{#if verticalKey}} + verticalKey: "{{{verticalKey}}}", + {{/if}} +}, {{{ json componentSettings.Pagination }}})); diff --git a/templates/vertical-full-page-map/markup/pagination.hbs b/templates/vertical-full-page-map/markup/pagination.hbs index 2f1935c3a..7c5797dc3 100644 --- a/templates/vertical-full-page-map/markup/pagination.hbs +++ b/templates/vertical-full-page-map/markup/pagination.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/pagination }} \ No newline at end of file diff --git a/templates/vertical-grid/markup/pagination.hbs b/templates/vertical-grid/markup/pagination.hbs index 174bbb2b4..7c5797dc3 100644 --- a/templates/vertical-grid/markup/pagination.hbs +++ b/templates/vertical-grid/markup/pagination.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/pagination }} \ No newline at end of file diff --git a/templates/vertical-grid/script/pagination.hbs b/templates/vertical-grid/script/pagination.hbs index 4fc8841b1..f422e06db 100644 --- a/templates/vertical-grid/script/pagination.hbs +++ b/templates/vertical-grid/script/pagination.hbs @@ -1,15 +1 @@ -ANSWERS.addComponent("Pagination", Object.assign({}, { - container: ".js-answersPagination", - onPaginate: (newPageNumber, oldPageNumber, totalPages) => { - if (window.parentIFrame) { - const paginateMessage = { action: 'paginate' }; - window.parentIFrame.sendMessage(JSON.stringify(paginateMessage)); - } else { - document.documentElement.scrollTop = 0; - document.body.scrollTop = 0; // Safari - } - }, - {{#if verticalKey}} - verticalKey: "{{{verticalKey}}}", - {{/if}} -}, {{{ json componentSettings.Pagination }}})); +{{> templates/common-partials/script/pagination }} \ No newline at end of file diff --git a/templates/vertical-map/markup/pagination.hbs b/templates/vertical-map/markup/pagination.hbs index 2f1935c3a..7c5797dc3 100644 --- a/templates/vertical-map/markup/pagination.hbs +++ b/templates/vertical-map/markup/pagination.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/pagination }} \ No newline at end of file diff --git a/templates/vertical-standard/markup/pagination.hbs b/templates/vertical-standard/markup/pagination.hbs index 174bbb2b4..7c5797dc3 100644 --- a/templates/vertical-standard/markup/pagination.hbs +++ b/templates/vertical-standard/markup/pagination.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/pagination }} \ No newline at end of file diff --git a/templates/vertical-standard/script/pagination.hbs b/templates/vertical-standard/script/pagination.hbs index 4fc8841b1..f422e06db 100644 --- a/templates/vertical-standard/script/pagination.hbs +++ b/templates/vertical-standard/script/pagination.hbs @@ -1,15 +1 @@ -ANSWERS.addComponent("Pagination", Object.assign({}, { - container: ".js-answersPagination", - onPaginate: (newPageNumber, oldPageNumber, totalPages) => { - if (window.parentIFrame) { - const paginateMessage = { action: 'paginate' }; - window.parentIFrame.sendMessage(JSON.stringify(paginateMessage)); - } else { - document.documentElement.scrollTop = 0; - document.body.scrollTop = 0; // Safari - } - }, - {{#if verticalKey}} - verticalKey: "{{{verticalKey}}}", - {{/if}} -}, {{{ json componentSettings.Pagination }}})); +{{> templates/common-partials/script/pagination }} \ No newline at end of file From ec2caf761a033adc800581d44cae16de97e8ae20 Mon Sep 17 00:00:00 2001 From: Christopher Jiang Date: Wed, 9 Jun 2021 12:47:55 -0400 Subject: [PATCH 35/56] Created common partial for sortoptions --- templates/common-partials/markup/sortoptions.hbs | 1 + templates/common-partials/script/sortoptions.hbs | 6 ++++++ templates/vertical-full-page-map/markup/sortoptions.hbs | 2 +- templates/vertical-full-page-map/script/sortoptions.hbs | 7 +------ templates/vertical-grid/markup/sortoptions.hbs | 2 +- templates/vertical-grid/script/sortoptions.hbs | 7 +------ templates/vertical-map/markup/sortoptions.hbs | 2 +- templates/vertical-map/script/sortoptions.hbs | 7 +------ templates/vertical-standard/markup/sortoptions.hbs | 2 +- templates/vertical-standard/script/sortoptions.hbs | 7 +------ 10 files changed, 15 insertions(+), 28 deletions(-) create mode 100644 templates/common-partials/markup/sortoptions.hbs create mode 100644 templates/common-partials/script/sortoptions.hbs diff --git a/templates/common-partials/markup/sortoptions.hbs b/templates/common-partials/markup/sortoptions.hbs new file mode 100644 index 000000000..7bfeaa804 --- /dev/null +++ b/templates/common-partials/markup/sortoptions.hbs @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/templates/common-partials/script/sortoptions.hbs b/templates/common-partials/script/sortoptions.hbs new file mode 100644 index 000000000..0f3f07a88 --- /dev/null +++ b/templates/common-partials/script/sortoptions.hbs @@ -0,0 +1,6 @@ +ANSWERS.addComponent("SortOptions", Object.assign({}, { + container: "#js-answersSortOptions", + {{#if verticalKey}} + verticalKey: "{{{verticalKey}}}", + {{/if}} +}, {{{ json componentSettings.SortOptions }}})); \ No newline at end of file diff --git a/templates/vertical-full-page-map/markup/sortoptions.hbs b/templates/vertical-full-page-map/markup/sortoptions.hbs index 7bfeaa804..d0ed51b54 100644 --- a/templates/vertical-full-page-map/markup/sortoptions.hbs +++ b/templates/vertical-full-page-map/markup/sortoptions.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/sortoptions }} \ No newline at end of file diff --git a/templates/vertical-full-page-map/script/sortoptions.hbs b/templates/vertical-full-page-map/script/sortoptions.hbs index 0f3f07a88..c56d5b6ad 100644 --- a/templates/vertical-full-page-map/script/sortoptions.hbs +++ b/templates/vertical-full-page-map/script/sortoptions.hbs @@ -1,6 +1 @@ -ANSWERS.addComponent("SortOptions", Object.assign({}, { - container: "#js-answersSortOptions", - {{#if verticalKey}} - verticalKey: "{{{verticalKey}}}", - {{/if}} -}, {{{ json componentSettings.SortOptions }}})); \ No newline at end of file +{{> templates/common-partials/script/sortoptions }} \ No newline at end of file diff --git a/templates/vertical-grid/markup/sortoptions.hbs b/templates/vertical-grid/markup/sortoptions.hbs index 7bfeaa804..d0ed51b54 100644 --- a/templates/vertical-grid/markup/sortoptions.hbs +++ b/templates/vertical-grid/markup/sortoptions.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/sortoptions }} \ No newline at end of file diff --git a/templates/vertical-grid/script/sortoptions.hbs b/templates/vertical-grid/script/sortoptions.hbs index 0f3f07a88..c56d5b6ad 100644 --- a/templates/vertical-grid/script/sortoptions.hbs +++ b/templates/vertical-grid/script/sortoptions.hbs @@ -1,6 +1 @@ -ANSWERS.addComponent("SortOptions", Object.assign({}, { - container: "#js-answersSortOptions", - {{#if verticalKey}} - verticalKey: "{{{verticalKey}}}", - {{/if}} -}, {{{ json componentSettings.SortOptions }}})); \ No newline at end of file +{{> templates/common-partials/script/sortoptions }} \ No newline at end of file diff --git a/templates/vertical-map/markup/sortoptions.hbs b/templates/vertical-map/markup/sortoptions.hbs index 7bfeaa804..d0ed51b54 100644 --- a/templates/vertical-map/markup/sortoptions.hbs +++ b/templates/vertical-map/markup/sortoptions.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/sortoptions }} \ No newline at end of file diff --git a/templates/vertical-map/script/sortoptions.hbs b/templates/vertical-map/script/sortoptions.hbs index 0f3f07a88..c56d5b6ad 100644 --- a/templates/vertical-map/script/sortoptions.hbs +++ b/templates/vertical-map/script/sortoptions.hbs @@ -1,6 +1 @@ -ANSWERS.addComponent("SortOptions", Object.assign({}, { - container: "#js-answersSortOptions", - {{#if verticalKey}} - verticalKey: "{{{verticalKey}}}", - {{/if}} -}, {{{ json componentSettings.SortOptions }}})); \ No newline at end of file +{{> templates/common-partials/script/sortoptions }} \ No newline at end of file diff --git a/templates/vertical-standard/markup/sortoptions.hbs b/templates/vertical-standard/markup/sortoptions.hbs index 7bfeaa804..d0ed51b54 100644 --- a/templates/vertical-standard/markup/sortoptions.hbs +++ b/templates/vertical-standard/markup/sortoptions.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/sortoptions }} \ No newline at end of file diff --git a/templates/vertical-standard/script/sortoptions.hbs b/templates/vertical-standard/script/sortoptions.hbs index 0f3f07a88..c56d5b6ad 100644 --- a/templates/vertical-standard/script/sortoptions.hbs +++ b/templates/vertical-standard/script/sortoptions.hbs @@ -1,6 +1 @@ -ANSWERS.addComponent("SortOptions", Object.assign({}, { - container: "#js-answersSortOptions", - {{#if verticalKey}} - verticalKey: "{{{verticalKey}}}", - {{/if}} -}, {{{ json componentSettings.SortOptions }}})); \ No newline at end of file +{{> templates/common-partials/script/sortoptions }} \ No newline at end of file From 29dc3da42f1881a8968829e750e19adea500e071 Mon Sep 17 00:00:00 2001 From: Christopher Jiang Date: Wed, 9 Jun 2021 13:02:35 -0400 Subject: [PATCH 36/56] Created common partial for verticalresults --- .../markup/verticalresults.hbs | 1 + .../script/verticalresults.hbs | 72 ++++++++++++++++++ .../markup/verticalresults.hbs | 2 +- .../vertical-grid/markup/verticalresults.hbs | 2 +- .../vertical-grid/script/verticalresults.hbs | 73 +------------------ .../vertical-map/markup/verticalresults.hbs | 2 +- .../vertical-map/script/verticalresults.hbs | 73 +------------------ .../markup/verticalresults.hbs | 2 +- .../script/verticalresults.hbs | 73 +------------------ 9 files changed, 80 insertions(+), 220 deletions(-) create mode 100644 templates/common-partials/markup/verticalresults.hbs create mode 100644 templates/common-partials/script/verticalresults.hbs diff --git a/templates/common-partials/markup/verticalresults.hbs b/templates/common-partials/markup/verticalresults.hbs new file mode 100644 index 000000000..bbb1e3b6f --- /dev/null +++ b/templates/common-partials/markup/verticalresults.hbs @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/templates/common-partials/script/verticalresults.hbs b/templates/common-partials/script/verticalresults.hbs new file mode 100644 index 000000000..e2d0e1a8c --- /dev/null +++ b/templates/common-partials/script/verticalresults.hbs @@ -0,0 +1,72 @@ +ANSWERS.addComponent("VerticalResults", Object.assign({}, { + container: ".js-answersVerticalResults", + {{#if verticalKey}} + verticalKey: "{{{verticalKey}}}", + modifier: "{{{verticalKey}}}", + {{/if}} + verticalPages: [ + {{#each verticalConfigs}} + {{#if verticalKey}} + { + verticalKey: "{{{verticalKey}}}", + {{#each ../excludedVerticals}}{{#ifeq this ../verticalKey}}hideInNavigation: true,{{/ifeq}}{{/each}} + {{#ifeq ../verticalKey verticalKey}}isActive: true,{{/ifeq}} + {{#with (lookup verticalsToConfig verticalKey)}} + {{#if isFirst}}isFirst: {{isFirst}},{{/if}} + {{#if icon}}icon: "{{{icon}}}",{{/if}} + {{#if iconUrl}}iconUrl: "{{{relativePathHandler url=iconUrl relativePath=@root.relativePath}}}",{{/if}} + label: {{> verticalLabel overridedLabel=label verticalKey=../verticalKey fallback=@key}}, + url: + {{#if url}} + "{{{relativePathHandler url=url relativePath=@root.relativePath}}}", + {{else if ../url}} + "{{{relativePathHandler url=../url relativePath=@root.relativePath}}}", + {{else}} + "{{{@key}}}.html", + {{/if}} + {{/with}} + }{{#unless @last}},{{/unless}} + {{else}} + { + {{#with (lookup verticalsToConfig "Universal")}} + {{#if isFirst}}isFirst: {{isFirst}},{{/if}} + {{#if icon}}icon: "{{{icon}}}",{{/if}} + label: {{#if label}}"{{{label}}}"{{else}}"{{{@key}}}"{{/if}}, + url: + {{#if url}} + "{{{relativePathHandler url=url relativePath=@root.relativePath}}}", + {{else if ../url}} + "{{{relativePathHandler url=../url relativePath=@root.relativePath}}}", + {{else}} + "{{{@key}}}.html", + {{/if}} + {{/with}} + }{{#unless @last}},{{/unless}} + {{/if}} + {{/each}} + ], + {{#with (lookup verticalsToConfig verticalKey)}} + card: { + {{#if cardType}}cardType: "{{{cardType}}}",{{/if}} + }, + {{/with}} +}, {{{ json componentSettings.VerticalResults }}})); + +{{!-- + Prints the vertical label according to specific logic + Assumes @root has environment variables and global_config + @param overridedLabel The hardcoded label from configuration in repo, meant to supercede defaults + @param verticalKey The current vertical key, if it exists + @param fallback The fallback for the label if all else doesn't exist +--}} +{{#*inline 'verticalLabel'}} + {{~#if overridedLabel ~}} + "{{{overridedLabel}}}" + {{~ else ~}} + HitchhikerJS.getInjectedProp( + "{{{@root.global_config.experienceKey}}}", + ["verticals", "{{{verticalKey}}}", "displayName"]) + {{~#if verticalKey ~}} || "{{{verticalKey}}}" {{~/if ~}} + {{~#if fallback ~}} || "{{{fallback}}}" {{~/if ~}} + {{~/if ~}} +{{/inline}} \ No newline at end of file diff --git a/templates/vertical-full-page-map/markup/verticalresults.hbs b/templates/vertical-full-page-map/markup/verticalresults.hbs index bbb1e3b6f..cb9b89771 100644 --- a/templates/vertical-full-page-map/markup/verticalresults.hbs +++ b/templates/vertical-full-page-map/markup/verticalresults.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/verticalresults }} \ No newline at end of file diff --git a/templates/vertical-grid/markup/verticalresults.hbs b/templates/vertical-grid/markup/verticalresults.hbs index 8e0801e97..cb9b89771 100644 --- a/templates/vertical-grid/markup/verticalresults.hbs +++ b/templates/vertical-grid/markup/verticalresults.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/verticalresults }} \ No newline at end of file diff --git a/templates/vertical-grid/script/verticalresults.hbs b/templates/vertical-grid/script/verticalresults.hbs index 413f471b0..6eadf08c0 100644 --- a/templates/vertical-grid/script/verticalresults.hbs +++ b/templates/vertical-grid/script/verticalresults.hbs @@ -1,72 +1 @@ -ANSWERS.addComponent("VerticalResults", Object.assign({}, { - container: ".js-answersVerticalResults", - {{#if verticalKey}} - verticalKey: "{{{verticalKey}}}", - modifier: "{{{verticalKey}}}", - {{/if}} - verticalPages: [ - {{#each verticalConfigs}} - {{#if verticalKey}} - { - verticalKey: "{{{verticalKey}}}", - {{#each ../excludedVerticals}}{{#ifeq this ../verticalKey}}hideInNavigation: true,{{/ifeq}}{{/each}} - {{#ifeq ../verticalKey verticalKey}}isActive: true,{{/ifeq}} - {{#with (lookup verticalsToConfig verticalKey)}} - {{#if isFirst}}isFirst: {{isFirst}},{{/if}} - {{#if icon}}icon: "{{{icon}}}",{{/if}} - {{#if iconUrl}}iconUrl: "{{{relativePathHandler url=iconUrl relativePath=@root.relativePath}}}",{{/if}} - label: {{> verticalLabel overridedLabel=label verticalKey=../verticalKey fallback=@key}}, - url: - {{#if url}} - "{{{relativePathHandler url=url relativePath=@root.relativePath}}}", - {{else if ../url}} - "{{{relativePathHandler url=../url relativePath=@root.relativePath}}}", - {{else}} - "{{{@key}}}.html", - {{/if}} - {{/with}} - }{{#unless @last}},{{/unless}} - {{else}} - { - {{#with (lookup verticalsToConfig "Universal")}} - {{#if isFirst}}isFirst: {{isFirst}},{{/if}} - {{#if icon}}icon: "{{{icon}}}",{{/if}} - label: {{#if label}}"{{{label}}}"{{else}}"{{{@key}}}"{{/if}}, - url: - {{#if url}} - "{{{relativePathHandler url=url relativePath=@root.relativePath}}}", - {{else if ../url}} - "{{{relativePathHandler url=../url relativePath=@root.relativePath}}}", - {{else}} - "{{{@key}}}.html", - {{/if}} - {{/with}} - }{{#unless @last}},{{/unless}} - {{/if}} - {{/each}} - ], - {{#with (lookup verticalsToConfig verticalKey)}} - card: { - {{#if cardType}}cardType: "{{{cardType}}}",{{/if}} - }, - {{/with}} -}, {{{ json componentSettings.VerticalResults }}})); - -{{!-- - Prints the vertical label according to specific logic - Assumes @root has environment variables and global_config - @param overridedLabel The hardcoded label from configuration in repo, meant to supercede defaults - @param verticalKey The current vertical key, if it exists - @param fallback The fallback for the label if all else doesn't exist ---}} -{{#*inline 'verticalLabel'}} - {{~#if overridedLabel ~}} - "{{{overridedLabel}}}" - {{~ else ~}} - HitchhikerJS.getInjectedProp( - "{{{@root.global_config.experienceKey}}}", - ["verticals", "{{{verticalKey}}}", "displayName"]) - {{~#if verticalKey ~}} || "{{{verticalKey}}}" {{~/if ~}} - {{~#if fallback ~}} || "{{{fallback}}}" {{~/if ~}} - {{~/if ~}} -{{/inline}} +{{> templates/common-partials/script/verticalresults }} \ No newline at end of file diff --git a/templates/vertical-map/markup/verticalresults.hbs b/templates/vertical-map/markup/verticalresults.hbs index bbb1e3b6f..cb9b89771 100644 --- a/templates/vertical-map/markup/verticalresults.hbs +++ b/templates/vertical-map/markup/verticalresults.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/verticalresults }} \ No newline at end of file diff --git a/templates/vertical-map/script/verticalresults.hbs b/templates/vertical-map/script/verticalresults.hbs index 604b836c4..6eadf08c0 100644 --- a/templates/vertical-map/script/verticalresults.hbs +++ b/templates/vertical-map/script/verticalresults.hbs @@ -1,72 +1 @@ -ANSWERS.addComponent("VerticalResults", Object.assign({}, { - container: "#js-answersVerticalResults", - {{#if verticalKey}} - verticalKey: "{{{verticalKey}}}", - modifier: "{{{verticalKey}}}", - {{/if}} - verticalPages: [ - {{#each verticalConfigs}} - {{#if verticalKey}} - { - verticalKey: "{{{verticalKey}}}", - {{#each ../excludedVerticals}}{{#ifeq this ../verticalKey}}hideInNavigation: true,{{/ifeq}}{{/each}} - {{#ifeq ../verticalKey verticalKey}}isActive: true,{{/ifeq}} - {{#with (lookup verticalsToConfig verticalKey)}} - {{#if isFirst}}isFirst: {{isFirst}},{{/if}} - {{#if icon}}icon: "{{{icon}}}",{{/if}} - {{#if iconUrl}}iconUrl: "{{{relativePathHandler url=iconUrl relativePath=@root.relativePath}}}",{{/if}} - label: {{> verticalLabel overridedLabel=label verticalKey=../verticalKey fallback=@key}}, - url: - {{#if url}} - "{{{relativePathHandler url=url relativePath=@root.relativePath}}}", - {{else if ../url}} - "{{{relativePathHandler url=../url relativePath=@root.relativePath}}}", - {{else}} - "{{{@key}}}.html", - {{/if}} - {{/with}} - }{{#unless @last}},{{/unless}} - {{else}} - { - {{#with (lookup verticalsToConfig "Universal")}} - {{#if isFirst}}isFirst: {{isFirst}},{{/if}} - {{#if icon}}icon: "{{{icon}}}",{{/if}} - label: {{#if label}}"{{{label}}}"{{else}}"{{{@key}}}"{{/if}}, - url: - {{#if url}} - "{{{relativePathHandler url=url relativePath=@root.relativePath}}}", - {{else if ../url}} - "{{{relativePathHandler url=../url relativePath=@root.relativePath}}}", - {{else}} - "{{{@key}}}.html", - {{/if}} - {{/with}} - }{{#unless @last}},{{/unless}} - {{/if}} - {{/each}} - ], - {{#with (lookup verticalsToConfig verticalKey)}} - card: { - {{#if cardType}}cardType: "{{{cardType}}}",{{/if}} - }, - {{/with}} -}, {{{ json componentSettings.VerticalResults }}})); - -{{!-- - Prints the vertical label according to specific logic - Assumes @root has environment variables and global_config - @param overridedLabel The hardcoded label from configuration in repo, meant to supercede defaults - @param verticalKey The current vertical key, if it exists - @param fallback The fallback for the label if all else doesn't exist ---}} -{{#*inline 'verticalLabel'}} - {{~#if overridedLabel ~}} - "{{{overridedLabel}}}" - {{~ else ~}} - HitchhikerJS.getInjectedProp( - "{{{@root.global_config.experienceKey}}}", - ["verticals", "{{{verticalKey}}}", "displayName"]) - {{~#if verticalKey ~}} || "{{{verticalKey}}}" {{~/if ~}} - {{~#if fallback ~}} || "{{{fallback}}}" {{~/if ~}} - {{~/if ~}} -{{/inline}} +{{> templates/common-partials/script/verticalresults }} \ No newline at end of file diff --git a/templates/vertical-standard/markup/verticalresults.hbs b/templates/vertical-standard/markup/verticalresults.hbs index 8e0801e97..cb9b89771 100644 --- a/templates/vertical-standard/markup/verticalresults.hbs +++ b/templates/vertical-standard/markup/verticalresults.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/verticalresults }} \ No newline at end of file diff --git a/templates/vertical-standard/script/verticalresults.hbs b/templates/vertical-standard/script/verticalresults.hbs index 413f471b0..6eadf08c0 100644 --- a/templates/vertical-standard/script/verticalresults.hbs +++ b/templates/vertical-standard/script/verticalresults.hbs @@ -1,72 +1 @@ -ANSWERS.addComponent("VerticalResults", Object.assign({}, { - container: ".js-answersVerticalResults", - {{#if verticalKey}} - verticalKey: "{{{verticalKey}}}", - modifier: "{{{verticalKey}}}", - {{/if}} - verticalPages: [ - {{#each verticalConfigs}} - {{#if verticalKey}} - { - verticalKey: "{{{verticalKey}}}", - {{#each ../excludedVerticals}}{{#ifeq this ../verticalKey}}hideInNavigation: true,{{/ifeq}}{{/each}} - {{#ifeq ../verticalKey verticalKey}}isActive: true,{{/ifeq}} - {{#with (lookup verticalsToConfig verticalKey)}} - {{#if isFirst}}isFirst: {{isFirst}},{{/if}} - {{#if icon}}icon: "{{{icon}}}",{{/if}} - {{#if iconUrl}}iconUrl: "{{{relativePathHandler url=iconUrl relativePath=@root.relativePath}}}",{{/if}} - label: {{> verticalLabel overridedLabel=label verticalKey=../verticalKey fallback=@key}}, - url: - {{#if url}} - "{{{relativePathHandler url=url relativePath=@root.relativePath}}}", - {{else if ../url}} - "{{{relativePathHandler url=../url relativePath=@root.relativePath}}}", - {{else}} - "{{{@key}}}.html", - {{/if}} - {{/with}} - }{{#unless @last}},{{/unless}} - {{else}} - { - {{#with (lookup verticalsToConfig "Universal")}} - {{#if isFirst}}isFirst: {{isFirst}},{{/if}} - {{#if icon}}icon: "{{{icon}}}",{{/if}} - label: {{#if label}}"{{{label}}}"{{else}}"{{{@key}}}"{{/if}}, - url: - {{#if url}} - "{{{relativePathHandler url=url relativePath=@root.relativePath}}}", - {{else if ../url}} - "{{{relativePathHandler url=../url relativePath=@root.relativePath}}}", - {{else}} - "{{{@key}}}.html", - {{/if}} - {{/with}} - }{{#unless @last}},{{/unless}} - {{/if}} - {{/each}} - ], - {{#with (lookup verticalsToConfig verticalKey)}} - card: { - {{#if cardType}}cardType: "{{{cardType}}}",{{/if}} - }, - {{/with}} -}, {{{ json componentSettings.VerticalResults }}})); - -{{!-- - Prints the vertical label according to specific logic - Assumes @root has environment variables and global_config - @param overridedLabel The hardcoded label from configuration in repo, meant to supercede defaults - @param verticalKey The current vertical key, if it exists - @param fallback The fallback for the label if all else doesn't exist ---}} -{{#*inline 'verticalLabel'}} - {{~#if overridedLabel ~}} - "{{{overridedLabel}}}" - {{~ else ~}} - HitchhikerJS.getInjectedProp( - "{{{@root.global_config.experienceKey}}}", - ["verticals", "{{{verticalKey}}}", "displayName"]) - {{~#if verticalKey ~}} || "{{{verticalKey}}}" {{~/if ~}} - {{~#if fallback ~}} || "{{{fallback}}}" {{~/if ~}} - {{~/if ~}} -{{/inline}} +{{> templates/common-partials/script/verticalresults }} \ No newline at end of file From 38a280128fdb941bf0d50e4838705f9dc7366b12 Mon Sep 17 00:00:00 2001 From: Christopher Jiang Date: Tue, 8 Jun 2021 17:06:29 -0400 Subject: [PATCH 37/56] Created common partial for verticalresultscount --- templates/common-partials/markup/verticalresultscount.hbs | 1 + templates/common-partials/script/verticalresultscount.hbs | 4 ++++ .../vertical-full-page-map/markup/verticalresultscount.hbs | 2 +- .../vertical-full-page-map/script/verticalresultscount.hbs | 5 +---- templates/vertical-grid/markup/verticalresultscount.hbs | 2 +- templates/vertical-grid/script/verticalresultscount.hbs | 5 +---- templates/vertical-map/markup/verticalresultscount.hbs | 2 +- templates/vertical-map/script/verticalresultscount.hbs | 5 +---- templates/vertical-standard/markup/verticalresultscount.hbs | 2 +- templates/vertical-standard/script/verticalresultscount.hbs | 5 +---- 10 files changed, 13 insertions(+), 20 deletions(-) create mode 100644 templates/common-partials/markup/verticalresultscount.hbs create mode 100644 templates/common-partials/script/verticalresultscount.hbs diff --git a/templates/common-partials/markup/verticalresultscount.hbs b/templates/common-partials/markup/verticalresultscount.hbs new file mode 100644 index 000000000..004729536 --- /dev/null +++ b/templates/common-partials/markup/verticalresultscount.hbs @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/templates/common-partials/script/verticalresultscount.hbs b/templates/common-partials/script/verticalresultscount.hbs new file mode 100644 index 000000000..a79fda533 --- /dev/null +++ b/templates/common-partials/script/verticalresultscount.hbs @@ -0,0 +1,4 @@ +ANSWERS.addComponent('VerticalResultsCount', { + container: '#js-answersVerticalResultsCount', + ...{{{ json componentSettings.VerticalResultsCount }}} +}); \ No newline at end of file diff --git a/templates/vertical-full-page-map/markup/verticalresultscount.hbs b/templates/vertical-full-page-map/markup/verticalresultscount.hbs index 004729536..adfb83d71 100644 --- a/templates/vertical-full-page-map/markup/verticalresultscount.hbs +++ b/templates/vertical-full-page-map/markup/verticalresultscount.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/verticalresultscount }} \ No newline at end of file diff --git a/templates/vertical-full-page-map/script/verticalresultscount.hbs b/templates/vertical-full-page-map/script/verticalresultscount.hbs index a79fda533..530863b1f 100644 --- a/templates/vertical-full-page-map/script/verticalresultscount.hbs +++ b/templates/vertical-full-page-map/script/verticalresultscount.hbs @@ -1,4 +1 @@ -ANSWERS.addComponent('VerticalResultsCount', { - container: '#js-answersVerticalResultsCount', - ...{{{ json componentSettings.VerticalResultsCount }}} -}); \ No newline at end of file +{{> templates/common-partials/script/verticalresultscount }} \ No newline at end of file diff --git a/templates/vertical-grid/markup/verticalresultscount.hbs b/templates/vertical-grid/markup/verticalresultscount.hbs index 004729536..adfb83d71 100644 --- a/templates/vertical-grid/markup/verticalresultscount.hbs +++ b/templates/vertical-grid/markup/verticalresultscount.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/verticalresultscount }} \ No newline at end of file diff --git a/templates/vertical-grid/script/verticalresultscount.hbs b/templates/vertical-grid/script/verticalresultscount.hbs index a79fda533..530863b1f 100644 --- a/templates/vertical-grid/script/verticalresultscount.hbs +++ b/templates/vertical-grid/script/verticalresultscount.hbs @@ -1,4 +1 @@ -ANSWERS.addComponent('VerticalResultsCount', { - container: '#js-answersVerticalResultsCount', - ...{{{ json componentSettings.VerticalResultsCount }}} -}); \ No newline at end of file +{{> templates/common-partials/script/verticalresultscount }} \ No newline at end of file diff --git a/templates/vertical-map/markup/verticalresultscount.hbs b/templates/vertical-map/markup/verticalresultscount.hbs index 004729536..adfb83d71 100644 --- a/templates/vertical-map/markup/verticalresultscount.hbs +++ b/templates/vertical-map/markup/verticalresultscount.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/verticalresultscount }} \ No newline at end of file diff --git a/templates/vertical-map/script/verticalresultscount.hbs b/templates/vertical-map/script/verticalresultscount.hbs index a79fda533..530863b1f 100644 --- a/templates/vertical-map/script/verticalresultscount.hbs +++ b/templates/vertical-map/script/verticalresultscount.hbs @@ -1,4 +1 @@ -ANSWERS.addComponent('VerticalResultsCount', { - container: '#js-answersVerticalResultsCount', - ...{{{ json componentSettings.VerticalResultsCount }}} -}); \ No newline at end of file +{{> templates/common-partials/script/verticalresultscount }} \ No newline at end of file diff --git a/templates/vertical-standard/markup/verticalresultscount.hbs b/templates/vertical-standard/markup/verticalresultscount.hbs index 004729536..adfb83d71 100644 --- a/templates/vertical-standard/markup/verticalresultscount.hbs +++ b/templates/vertical-standard/markup/verticalresultscount.hbs @@ -1 +1 @@ -
\ No newline at end of file +{{> templates/common-partials/markup/verticalresultscount }} \ No newline at end of file diff --git a/templates/vertical-standard/script/verticalresultscount.hbs b/templates/vertical-standard/script/verticalresultscount.hbs index a79fda533..530863b1f 100644 --- a/templates/vertical-standard/script/verticalresultscount.hbs +++ b/templates/vertical-standard/script/verticalresultscount.hbs @@ -1,4 +1 @@ -ANSWERS.addComponent('VerticalResultsCount', { - container: '#js-answersVerticalResultsCount', - ...{{{ json componentSettings.VerticalResultsCount }}} -}); \ No newline at end of file +{{> templates/common-partials/script/verticalresultscount }} \ No newline at end of file From 72fc7e89249d5b0ba19716356a2a5ec9da60ab36 Mon Sep 17 00:00:00 2001 From: Christopher Jiang Date: Wed, 9 Jun 2021 11:40:02 -0400 Subject: [PATCH 38/56] Registered common partials in test files. --- tests/templates/script/navigation.js | 4 ++++ tests/templates/script/verticalresults.js | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/tests/templates/script/navigation.js b/tests/templates/script/navigation.js index 2978f731b..578d3e653 100644 --- a/tests/templates/script/navigation.js +++ b/tests/templates/script/navigation.js @@ -2,6 +2,10 @@ const fs = require('fs'); const path = require('path'); const hbs = require('../../test-utils/hbs'); +const tempToNavPath = 'templates/common-partials/script/navigation'; +const partialPath = path.resolve(__dirname, `../../../${tempToNavPath}.hbs`); +hbs.registerPartial(tempToNavPath, fs.readFileSync(partialPath, 'utf-8')); + const pageTemplates = [ 'universal-standard', 'vertical-grid', diff --git a/tests/templates/script/verticalresults.js b/tests/templates/script/verticalresults.js index 8548a1334..ba918d17b 100644 --- a/tests/templates/script/verticalresults.js +++ b/tests/templates/script/verticalresults.js @@ -9,6 +9,10 @@ const pageTemplates = [ 'vertical-full-page-map' ]; +const tempToVertPath = 'templates/common-partials/script/verticalresults'; +const partialPath = path.resolve(__dirname, `../../../${tempToVertPath}.hbs`); +hbs.registerPartial(tempToVertPath, fs.readFileSync(partialPath, 'utf-8')); + for (const pageTemplate of pageTemplates) { const compiledTemplate = getCompiledVerticalResultsTemplate(pageTemplate); From 37782645d0fb5aaad63f6dd0681121bdbae3ac97 Mon Sep 17 00:00:00 2001 From: Tom Meyer Date: Thu, 10 Jun 2021 11:56:48 -0400 Subject: [PATCH 39/56] Add `postcss` back to `static/package.json`. (#827) The `InlineAssetHTMLPlugin` still requires `postcss`, so we need to add it back to the `static/package.json`. TEST=manual Verified that I could now build a site after upgrading to `develop`. --- static/package-lock.json | 31 +++++++++++++++++++++++++++++++ static/package.json | 1 + 2 files changed, 32 insertions(+) diff --git a/static/package-lock.json b/static/package-lock.json index 541bef080..59d9c42d8 100644 --- a/static/package-lock.json +++ b/static/package-lock.json @@ -4532,6 +4532,12 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "nanoid": { + "version": "3.1.23", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz", + "integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==", + "dev": true + }, "neo-async": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", @@ -4883,6 +4889,25 @@ "integrity": "sha512-Vy9eH1dRD9wHjYt/QqXcTz+RnX/zg53xK+KljFSX30PvdDMb2z+c6uDUeblUGqqJgz3QFsdlA0IJvHziPmWtQg==", "dev": true }, + "postcss": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.1.tgz", + "integrity": "sha512-9qH0MGjsSm+fjxOi3GnwViL1otfi7qkj+l/WX5gcRGmZNGsIcqc+A5fBkE6PUobEQK4APqYVaES+B3Uti98TCw==", + "dev": true, + "requires": { + "colorette": "^1.2.2", + "nanoid": "^3.1.23", + "source-map-js": "^0.6.2" + }, + "dependencies": { + "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 + } + } + }, "postcss-modules-extract-imports": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", @@ -5746,6 +5771,12 @@ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, + "source-map-js": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz", + "integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==", + "dev": true + }, "source-map-resolve": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", diff --git a/static/package.json b/static/package.json index fed30c669..b37ef5cd2 100644 --- a/static/package.json +++ b/static/package.json @@ -33,6 +33,7 @@ "jambo": "^1.11.0", "jsdom": "^16.4.0", "mini-css-extract-plugin": "^1.6.0", + "postcss": "^8.3.1", "resolve-url-loader": "^3.1.1", "sass": "^1.34.0", "sass-loader": "^8.0.2", From 6368b08ce9719f3251d67392708be3c04de0dc81 Mon Sep 17 00:00:00 2001 From: Oliver Shi Date: Mon, 14 Jun 2021 11:34:47 -0400 Subject: [PATCH 40/56] change webpack devtool to 'eval' from 'source-map' (#829) See here for a comparison of webpack devtool options https://webpack.js.org/configuration/devtool/ 'source-map' is listed as one of the slowest options for build, and is recommended for production builds that want high quality source maps. Changing this to 'eval' shaves off 0.5s from the build time, while still providing a source map in dev mode. J=SLAP-1373 TEST=manual see ~0.5s shaved off the webpack build time see that I get source maps in dev mode, and can add a console log to a formatter and clicking on the console.log's line number will take me to the correct source line in dev tools --- static/webpack-config.js | 1 - static/webpack/webpack.dev.js | 1 + static/webpack/webpack.prod.js | 1 + 3 files changed, 2 insertions(+), 1 deletion(-) diff --git a/static/webpack-config.js b/static/webpack-config.js index 2b429483f..979466cae 100644 --- a/static/webpack-config.js +++ b/static/webpack-config.js @@ -48,7 +48,6 @@ module.exports = function () { ]; const commonConfig = { - devtool: 'source-map', stats: 'errors-warnings', performance: { maxAssetSize: 1536000, diff --git a/static/webpack/webpack.dev.js b/static/webpack/webpack.dev.js index cd1b9546e..15ff8ee3d 100644 --- a/static/webpack/webpack.dev.js +++ b/static/webpack/webpack.dev.js @@ -1,6 +1,7 @@ module.exports = () => { return { mode: 'development', + devtool: 'eval', optimization: { minimize: false } diff --git a/static/webpack/webpack.prod.js b/static/webpack/webpack.prod.js index 5fff2d793..26ae8ca06 100644 --- a/static/webpack/webpack.prod.js +++ b/static/webpack/webpack.prod.js @@ -4,6 +4,7 @@ module.exports = () => { const InlineAssetHtmlPlugin = require('./InlineAssetHtmlPlugin'); return { mode: 'production', + devtool: 'source-map', plugins: [ new InlineAssetHtmlPlugin() ], From 5e08a2a5684cfee51fad2745c503fb7df0ba1d00 Mon Sep 17 00:00:00 2001 From: Oliver Shi Date: Mon, 14 Jun 2021 13:19:33 -0400 Subject: [PATCH 41/56] separate bundle into legacy and modern bundle (#828) This commit separates bundle.js into the polyfill-free bundle.js and polyfilled bundle-legacy.js. Both still run through the babel loader, because the esbuild minifier is set to target es5, and does not let you minify some bundles to es5 and some bundles to newer javascript. The type="module" and nomodule script loading pattern is used to dynamically load the correct bundle. This is the pattern we use for determining whether to use answers-modern or answers assets. This shrinks bundle.js from 443KB to 313KB in prod mode (and from 1.3MB to 705KB in dev mode). In prod mode the page speed went from 50 -> 56, and in dev mode the page speed lighthouse scores went from 36 -> 48. J=SLAP-1373 TEST=manual see ~0.7s build speed improvements on yanswers and answers-atlanticsearch when I remove the core-js import from entry.js this build speedup doesn't show up for the test-site for some reason, though investigated for a while but could not figure out why I figured that yanswers and another random repo would be better benchmarks, though the test-site's build speed was also not hurt at all by this change see that the production modern bundle shrinks from 443KB to 313KB after removing polyfills smoke test that full page map on ie11 (browserstack), firefox, safari, chrome, and galaxy s6 chrome (browserstack) see that bundle.js is inlined properly, and only the modern one is inlined --- layouts/html.hbs | 2 +- script/partials/bundle-script-tags.hbs | 2 ++ static/entry-legacy.js | 8 ++++++ static/entry.js | 36 +++----------------------- static/js/HitchhikerJS.js | 29 +++++++++++++++++++++ static/webpack-config.js | 9 +++---- static/webpack/webpack.prod.js | 7 +++-- 7 files changed, 52 insertions(+), 41 deletions(-) create mode 100644 script/partials/bundle-script-tags.hbs create mode 100644 static/entry-legacy.js create mode 100644 static/js/HitchhikerJS.js diff --git a/layouts/html.hbs b/layouts/html.hbs index 3b6619164..3563474eb 100644 --- a/layouts/html.hbs +++ b/layouts/html.hbs @@ -85,7 +85,7 @@ }); {{/babel}} - + {{> script/partials/bundle-script-tags }} {{#if global_config.googleAnalyticsId}} diff --git a/script/partials/bundle-script-tags.hbs b/script/partials/bundle-script-tags.hbs new file mode 100644 index 000000000..67292671a --- /dev/null +++ b/script/partials/bundle-script-tags.hbs @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/static/entry-legacy.js b/static/entry-legacy.js new file mode 100644 index 000000000..06365daff --- /dev/null +++ b/static/entry-legacy.js @@ -0,0 +1,8 @@ +// Import global polyfills +import 'core-js/stable'; + +import * as HitchhikerJS from './js/HitchhikerJS'; +window.HitchhikerJS = HitchhikerJS; + +// Import all SCSS +import Scss from './scss/answers/_default.scss'; diff --git a/static/entry.js b/static/entry.js index f571d728e..92f7f43e7 100644 --- a/static/entry.js +++ b/static/entry.js @@ -1,35 +1,5 @@ -// Import global polyfills -import 'core-js/stable'; +import * as HitchhikerJS from './js/HitchhikerJS'; +window.HitchhikerJS = HitchhikerJS; // Import all SCSS -import Scss from './scss/answers/_default.scss'; - -// Import all JS assets -import Formatters from './js/formatters'; -window.Formatter = Formatters; - -export { Formatters }; -export { getDefaultMapApiKey } from './js/default-map-api-key'; -export { isStaging } from './js/is-staging'; -export { isMobile } from 'is-mobile'; -export { getInjectedProp } from './js/get-injected-prop'; -export { isHighlighted } from './js/is-highlighted'; - -// Used to transfigure the page for the Overlay -import Overlay from './js/overlay/answers-frame/overlay'; -window.Overlay = new Overlay(); - -// Import code used in Collapsible Filters, and give it the alias of window.CollapsibleFilters. -import CollapsibleFilters from './js/collapsible-filters'; -export { CollapsibleFilters }; -global.CollapsibleFilters = CollapsibleFilters; - -// Import custom modules which can be accessed from HitchhikerJS.CustomModules -import * as CustomModules from './js/custom-modules'; -export { CustomModules }; - -import StorageKeys from './js/constants/storage-keys'; -export { StorageKeys }; - -import transformFacets from './js/transform-facets'; -export { transformFacets } \ No newline at end of file +import Scss from './scss/answers/_default.scss'; \ No newline at end of file diff --git a/static/js/HitchhikerJS.js b/static/js/HitchhikerJS.js new file mode 100644 index 000000000..afd7ae021 --- /dev/null +++ b/static/js/HitchhikerJS.js @@ -0,0 +1,29 @@ +// Import all JS assets +import Formatters from './formatters'; +window.Formatter = Formatters; + +export { Formatters }; +export { getDefaultMapApiKey } from './default-map-api-key'; +export { isStaging } from './is-staging'; +export { isMobile } from 'is-mobile'; +export { getInjectedProp } from './get-injected-prop'; +export { isHighlighted } from './is-highlighted'; + +// Used to transfigure the page for the Overlay +import Overlay from './overlay/answers-frame/overlay'; +window.Overlay = new Overlay(); + +// Import code used in Collapsible Filters, and give it the alias of window.CollapsibleFilters. +import CollapsibleFilters from './collapsible-filters'; +export { CollapsibleFilters }; +global.CollapsibleFilters = CollapsibleFilters; + +// Import custom modules which can be accessed from HitchhikerJS.CustomModules +import * as CustomModules from './custom-modules'; +export { CustomModules }; + +import StorageKeys from './constants/storage-keys'; +export { StorageKeys }; + +import transformFacets from './transform-facets'; +export { transformFacets } \ No newline at end of file diff --git a/static/webpack-config.js b/static/webpack-config.js index 979466cae..256d79793 100644 --- a/static/webpack-config.js +++ b/static/webpack-config.js @@ -55,7 +55,7 @@ module.exports = function () { }, target: ['web', 'es5'], entry: { - 'HitchhikerJS': `./${jamboConfig.dirs.output}/static/entry.js`, + 'bundle': `./${jamboConfig.dirs.output}/static/entry.js`, 'iframe': `./${jamboConfig.dirs.output}/static/js/iframe.js`, 'answers': `./${jamboConfig.dirs.output}/static/js/iframe.js`, 'overlay-button': `./${jamboConfig.dirs.output}/static/js/overlay/button-frame/entry.js`, @@ -73,8 +73,7 @@ module.exports = function () { filename: pathData => { const chunkName = pathData.chunk.name; return { - VerticalFullPageMap: 'locator-bundle.js', - HitchhikerJS: 'bundle.js', + VerticalFullPageMap: 'locator-bundle.js' }[chunkName] || '[name].js' }, library: '[name]', @@ -140,12 +139,12 @@ module.exports = function () { if (isDevelopment) { const devConfig = require( `./${jamboConfig.dirs.output}/static/webpack/webpack.dev.js` - )(); + )(jamboConfig); return merge(commonConfig, devConfig); } else { const prodConfig = require( `./${jamboConfig.dirs.output}/static/webpack/webpack.prod.js` - )(); + )(jamboConfig); return merge(commonConfig, prodConfig); } }; diff --git a/static/webpack/webpack.prod.js b/static/webpack/webpack.prod.js index 26ae8ca06..f78a981c6 100644 --- a/static/webpack/webpack.prod.js +++ b/static/webpack/webpack.prod.js @@ -1,10 +1,13 @@ const { ESBuildMinifyPlugin } = require('esbuild-loader') -module.exports = () => { +module.exports = (jamboConfig) => { const InlineAssetHtmlPlugin = require('./InlineAssetHtmlPlugin'); return { mode: 'production', devtool: 'source-map', + entry: { + 'bundle-legacy': `./${jamboConfig.dirs.output}/static/entry-legacy.js`, + }, plugins: [ new InlineAssetHtmlPlugin() ], @@ -42,4 +45,4 @@ module.exports = () => { ] }, }; -} \ No newline at end of file +} From dccef58eeb7b9f5c2792b4db9889a9f2ce8f7c77 Mon Sep 17 00:00:00 2001 From: Oliver Shi Date: Mon, 14 Jun 2021 15:51:36 -0400 Subject: [PATCH 42/56] add static/assets loader test to snapshots (#832) This commit adds a usage of the html-asset-loader to our Percy snapshots. The universal page's KM vertical now uses a custom static icon. J=NONE T=manual test that I can load up the test site and the icon appears --- test-site/config/index.json | 3 ++- test-site/static/assets/slapshot.png | Bin 0 -> 69970 bytes 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 test-site/static/assets/slapshot.png diff --git a/test-site/config/index.json b/test-site/config/index.json index b88c26b3d..b0d8b9a16 100644 --- a/test-site/config/index.json +++ b/test-site/config/index.json @@ -39,7 +39,8 @@ "cardType": "financial-professional-location", "mapConfig": { "mapProvider": "Google" - } + }, + "icon": "static/assets/slapshot.png" }, "products": { "universalSectionTemplate": "grid-three-columns", diff --git a/test-site/static/assets/slapshot.png b/test-site/static/assets/slapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..e1adbd65f02fdd63fcb10d97f3173595c28c95a1 GIT binary patch literal 69970 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 literal 0 HcmV?d00001 From f8d8bd4707e9482821107049de7d4b1d90bfae01 Mon Sep 17 00:00:00 2001 From: Tom Meyer Date: Tue, 15 Jun 2021 07:29:48 -0400 Subject: [PATCH 43/56] Wrap 'Opens At' text in a call to `_localizer.getTranslation`. (#834) In the `open-status/message-factory` we forgot to wrap one of the static strings in a `_localizer.getTranslation` call. This caused the 'Opens At' string to always appear in English. J=SLAP-1380 TEST=manual, auto This fix was already verified manually by a HH. I am just adding it to the Theme. I did add a unit test suite for the `message-factory`. The test suite and test I added would have caught this issue and so will ensure there aren't future regressions on this front. --- static/js/hours/open-status/messagefactory.js | 2 +- .../js/hours/open-status/messagefactory.js | 50 +++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 tests/static/js/hours/open-status/messagefactory.js diff --git a/static/js/hours/open-status/messagefactory.js b/static/js/hours/open-status/messagefactory.js index 750b30e2f..267767306 100644 --- a/static/js/hours/open-status/messagefactory.js +++ b/static/js/hours/open-status/messagefactory.js @@ -33,7 +33,7 @@ export default class OpenStatusMessageFactory { ${this._localizer.getTranslation(OpenStatusStrings.CLOSED)} - · ${OpenStatusStrings.OPENS_AT} + · ${this._localizer.getTranslation(OpenStatusStrings.OPENS_AT)} ${time} `; diff --git a/tests/static/js/hours/open-status/messagefactory.js b/tests/static/js/hours/open-status/messagefactory.js new file mode 100644 index 000000000..c0ac337b9 --- /dev/null +++ b/tests/static/js/hours/open-status/messagefactory.js @@ -0,0 +1,50 @@ +import { OpenStatusStrings, OpenStatusTypes } from '../../../../../static/js/hours/open-status/constants'; +import OpenStatusMessageFactory from '../../../../../static/js/hours/open-status/messagefactory'; + +const localizer = { + getLocalizedTime: jest.fn(yextTime => { + let time = new Date(); + time.setHours(Math.floor(yextTime / 100)); + time.setMinutes(yextTime % 100); + + return time.toLocaleString('en', { + hour: 'numeric', + minute: 'numeric' + }); + }), + getTranslation: jest.fn(str => { + const translations = { + [OpenStatusStrings.CLOSED]: 'Closed', + [OpenStatusStrings.OPEN_24_HOURS]: 'Open 24 Hours', + [OpenStatusStrings.OPENS_AT]: 'Opens at', + [OpenStatusStrings.OPEN_NOW]: 'Open Now', + [OpenStatusStrings.CLOSES_AT]: 'Closes at', + } + return translations[str]; + }) +}; +const messageFactory = new OpenStatusMessageFactory(localizer); +const sanitizeMessage = msg => msg.replace(/\s/g, ''); + +describe('Open Status messages are generated correctly', () => { + it(`generates ${OpenStatusTypes.OPENS_TODAY} message correctly`, () => { + const hoursToday = { + status: OpenStatusTypes.OPENS_TODAY, + nextTime: 1700 + }; + + const expectedMessage = ` + + Closed + · Opens at + 5:00 PM + + `; + + expect(sanitizeMessage(messageFactory.create(hoursToday))) + .toEqual(sanitizeMessage(expectedMessage)); + expect(localizer.getLocalizedTime.mock.calls[0][0]).toBe(1700); + expect(localizer.getTranslation.mock.calls[0][0]).toBe(OpenStatusStrings.CLOSED); + expect(localizer.getTranslation.mock.calls[1][0]).toBe(OpenStatusStrings.OPENS_AT); + }); +}); \ No newline at end of file From 53561242454f114e7ed76edac6435f3051676344 Mon Sep 17 00:00:00 2001 From: cea2aj <42848445+cea2aj@users.noreply.github.com> Date: Tue, 15 Jun 2021 10:58:37 -0400 Subject: [PATCH 44/56] Additional locator acceptance tests (#830) Add additional locator acceptance tests These tests cover: - Pagination - Default initial search - Interacting with the results list This PR also includes some additional updates - Set `yxt-Pin` and `yxt-PinCluster` CSS classes so that I can safely target them from the tests. This should only affect Mapbox since google does not use HTML pins - Updated the functions on the blocks to all be async. I think this consistency makes it easier to write acceptance tests. It also separates concerns by keeping the lower-level `Selector` object within the blocks. J=SLAP-1362 TEST=acceptance --- static/js/theme-map/ThemeMap.js | 7 +- tests/acceptance/blocks/page.js | 16 +++++ tests/acceptance/blocks/pagination.js | 23 +++++++ tests/acceptance/blocks/thememap.js | 68 +++++++++++++++++-- tests/acceptance/blocks/verticalresults.js | 55 +++++++++++---- tests/acceptance/index.js | 8 ++- .../suites/vertical-full-page-map.js | 35 ++++++++-- 7 files changed, 185 insertions(+), 27 deletions(-) create mode 100644 tests/acceptance/blocks/page.js create mode 100644 tests/acceptance/blocks/pagination.js diff --git a/static/js/theme-map/ThemeMap.js b/static/js/theme-map/ThemeMap.js index 37347ce99..368ba04a0 100644 --- a/static/js/theme-map/ThemeMap.js +++ b/static/js/theme-map/ThemeMap.js @@ -309,7 +309,9 @@ class ThemeMap extends ANSWERS.Component { .setWidth(defaultPin.width) .setHeight(defaultPin.height) .setAnchorX(this.config.pinClusterAnchors.anchorX) - .setAnchorY(this.config.pinClusterAnchors.anchorY); + .setAnchorY(this.config.pinClusterAnchors.anchorY) + .setClass('yxt-PinCluster') + .setSRText(`Cluster of ${pinCount} results`); return properties; }) @@ -347,7 +349,8 @@ class ThemeMap extends ANSWERS.Component { .withPropertiesForStatus(status => { const properties = new PinProperties() .setIcon(status.selected ? 'selected' : ((status.hovered || status.focused) ? 'hovered' : 'default')) - .setSRText(index) + .setClass('yxt-Pin') + .setSRText(`Result number ${index}`) .setZIndex(status.selected ? 1 : ((status.hovered || status.focused) ? 2 : 0)) .setAnchorX(this.config.pinAnchors.anchorX) .setAnchorY(this.config.pinAnchors.anchorY); diff --git a/tests/acceptance/blocks/page.js b/tests/acceptance/blocks/page.js new file mode 100644 index 000000000..df755c230 --- /dev/null +++ b/tests/acceptance/blocks/page.js @@ -0,0 +1,16 @@ +import { Selector, t } from 'testcafe'; + +/** + * Models the user interaction with the page as a whole + */ +class Page { + constructor () { + this._document = Selector('.YxtPage-doc'); + } + + async scrollToBottom () { + await t.scroll(this._document, 'bottom'); + } +} + +export default new Page(); \ No newline at end of file diff --git a/tests/acceptance/blocks/pagination.js b/tests/acceptance/blocks/pagination.js new file mode 100644 index 000000000..d110d3dae --- /dev/null +++ b/tests/acceptance/blocks/pagination.js @@ -0,0 +1,23 @@ +import { Selector, t } from 'testcafe'; +import Page from './page'; +import VerticalResults from './verticalresults'; + +/** + * Models the user interaction with a {import('@yext/answers-search-ui').PaginationComponent}. + */ +class Pagination { + constructor () { + this._nextResultsButton = Selector('.js-yxt-Pagination-next'); + } + + /** + * Clicks the next results page button + */ + async nextResults () { + await Page.scrollToBottom(); // We must scroll to the bottom of the page to be able to click the next results page button + await VerticalResults.scrollToBottom(); + await t.click(this._nextResultsButton); + } +} + +export default new Pagination(); \ No newline at end of file diff --git a/tests/acceptance/blocks/thememap.js b/tests/acceptance/blocks/thememap.js index 22917d405..4b20f80a1 100644 --- a/tests/acceptance/blocks/thememap.js +++ b/tests/acceptance/blocks/thememap.js @@ -1,23 +1,32 @@ -import { Selector, t } from 'testcafe'; +import { Selector, t, ClientFunction } from 'testcafe'; /** * This class models user interactions with the {@link ThemeMap}. */ class ThemeMap { constructor () { - this._pin = Selector('.js-answersMap button'); - this._canvas = Selector('.mapboxgl-canvas'); + this._pin = Selector('.yxt-Pin button'); + this._pinCluster = Selector('.yxt-PinCluster button'); + this._canvas = Selector('.Answers-map'); this._searchThisAreaToggle = Selector('.Answers-searchThisAreaToggleLabel'); this._searchThisAreaButton = Selector('.js-searchThisAreaButton'); } /** - * Selects a pin from the Mapbox map. + * Selects a pin from the map. */ - async selectMapboxPin () { + async selectPin () { await t.click(this._pin); } + /** + * Selects a pin cluster from the map. + */ + async selectPinCluster () { + await t.click(this._pinCluster); + await this.waitForZoomStabilization(); + } + async dragLeft () { await t.drag(this._canvas, 750, 0); } @@ -29,6 +38,55 @@ class ThemeMap { async clickSearchThisAreaButton () { await t.click(this._searchThisAreaButton); } + + async clickMap () { + await t.click(this._canvas); + } + + /** + * Gets the current zoom of the map + * @returns {Promise} + */ + async getZoom () { + const zoom = await ClientFunction(() => { + return ANSWERS + .components + .getActiveComponent('VerticalFullPageMapOrchestrator') + .currentZoom + })(); + return zoom; + } + + /** + * Waits for the map zoom to stabilize + */ + async waitForZoomStabilization () { + const pollingIntervalMsecs = 500; + const minNumStableIntervals = 3; + const maxNumIntervals= 10; + let previousZoom = await this.getZoom(); + let numStableIntervals = 0; + let numIntervals = 0; + let isZoomStabilized = false; + let isMaxIntervalsReached = false; + + while (!isZoomStabilized && !isMaxIntervalsReached) { + await t.wait(pollingIntervalMsecs); + const currentZoom = await this.getZoom(); + + if (currentZoom === previousZoom) { + numStableIntervals++; + } else { + numStableIntervals = 0; + } + + numIntervals++; + + isZoomStabilized = (numStableIntervals >= minNumStableIntervals); + isMaxIntervalsReached = (numIntervals >= maxNumIntervals); + previousZoom = currentZoom; + } + } } export default new ThemeMap(); \ No newline at end of file diff --git a/tests/acceptance/blocks/verticalresults.js b/tests/acceptance/blocks/verticalresults.js index 8bfa70c98..2b45aebc1 100644 --- a/tests/acceptance/blocks/verticalresults.js +++ b/tests/acceptance/blocks/verticalresults.js @@ -1,4 +1,4 @@ -import { Selector } from 'testcafe'; +import { Selector, t } from 'testcafe'; /** * Models the user interaction with a {import('@yext/answers-search-ui').VerticalResultsComponent}. @@ -6,9 +6,12 @@ import { Selector } from 'testcafe'; class VerticalResults { constructor () { this._selector = Selector('.yxt-Results') + this._resultsWrapper = Selector('.Answers-resultsWrapper'); this._focusedCard = Selector('.yxt-Card--pinFocused'); + this._getNthCard = index => Selector(`.yxt-Card[data-opts*="${index}"]`); this._noResults = Selector('.yxt-AlternativeVerticals-noResultsInfo'); this._resultsCount = Selector('.yxt-VerticalResultsCount-total'); + this._resultsCountStart = Selector('.yxt-VerticalResultsCount-start'); } /** @@ -19,32 +22,60 @@ class VerticalResults { if (await this._noResults.exists) { return 0; } - return await this.getResultsCountTotal(); + return await this.getResultsCount(); } /** - * Returns the number of results from the VerticalResultsCount. + * Returns the number of results from the VerticalResultsCount-total. * @returns {Promise} */ - async getResultsCountTotal () { + async getResultsCount () { const countText = await this._resultsCount.innerText; return Number.parseInt(countText); } /** - * Gets a selector for the card associated with the currently focused map pin. - * @returns {Selector} + * Returns the offset between the first result and the first result displayed + * @returns {Promise} + */ + async getResultsOffset () { + const countText = await this._resultsCountStart.innerText; + return Number.parseInt(countText) - 1; + } + + /** + * Returns true if a card from the vertical results is focused + * @returns {Promise} + */ + async isCardFocused () { + return this._focusedCard.exists; + } + + /** + * Clicks the card specified by the card index + */ + async clickCard (cardIndex) { + await t.click(this._getNthCard(cardIndex)); + } + + /** + * Returns true if results are present + * @returns {Promise} */ - getFocusedCard () { - return this._focusedCard; + async isResultsPresent () { + return this._selector.exists; } /** - * Gets a selector for the results div. - * @returns {Selector} + * Gets the number of pixels that the element's content is scrolled upward + * @returns {Promise} */ - getResults () { - return this._selector; + async getScrollTop () { + return this._resultsWrapper.scrollTop + } + + async scrollToBottom () { + await t.scroll(this._resultsWrapper, 'bottom'); } } diff --git a/tests/acceptance/index.js b/tests/acceptance/index.js index 114c2cf63..d15051d57 100644 --- a/tests/acceptance/index.js +++ b/tests/acceptance/index.js @@ -29,10 +29,14 @@ async function runTests (browsers) { .startApp(`npx serve -p ${PORT} test-site/public`, 4000) .run({ quarantineMode: true }); if (numberTestsFailed > 0) { + await testcafe.close(); process.exit(1); } - } - finally { + } catch (e) { + console.error(e); + await testcafe.close(); + process.exit(1); + } finally { await testcafe.close(); } } \ No newline at end of file diff --git a/tests/acceptance/suites/vertical-full-page-map.js b/tests/acceptance/suites/vertical-full-page-map.js index fb6a317fc..c289accad 100644 --- a/tests/acceptance/suites/vertical-full-page-map.js +++ b/tests/acceptance/suites/vertical-full-page-map.js @@ -2,22 +2,24 @@ import { PORT } from '../constants'; import SearchBar from '../blocks/searchbar'; import VerticalResults from '../blocks/verticalresults'; import ThemeMap from '../blocks/thememap'; +import Pagination from '../blocks/pagination'; fixture`Vertical Full Page Map` .page(`http://localhost:${PORT}/locations_full_page_map`) test('Can search and get results', async t => { await SearchBar.submitQuery('virginia'); - const results = VerticalResults.getResults(); - await t.expect(results.exists).ok(); + const isResultsPresent = await VerticalResults.isResultsPresent(); + await t.expect(isResultsPresent).ok(); }); test('Clicking on a pin focuses on a results card', async t => { await SearchBar.submitQuery('virginia'); - const focusedCard = VerticalResults.getFocusedCard(); - await t.expect(focusedCard.exists).notOk(); - await ThemeMap.selectMapboxPin(); - await t.expect(focusedCard.exists).ok(); + let isCardFocused = await VerticalResults.isCardFocused(); + await t.expect(isCardFocused).notOk(); + await ThemeMap.selectPin(); + isCardFocused = await VerticalResults.isCardFocused(); + await t.expect(isCardFocused).ok(); }); test('Search when map moves works', async t => { @@ -38,3 +40,24 @@ test('Search this area button works', async t => { const resultsCountAfterDrag = await VerticalResults.getNumResults(); await t.expect(resultsCountBeforeDrag !== resultsCountAfterDrag).ok(); }); + +test('Default initial search works and is enabled by default', async t => { + const resultsCount = await VerticalResults.getNumResults(); + await t.expect(resultsCount).ok(); +}); + +test('Pagination works', async t => { + const initialResultsOffset = await VerticalResults.getResultsOffset(); + await Pagination.nextResults(); + const updatedResultsOffset = await VerticalResults.getResultsOffset(); + await t.expect(initialResultsOffset).notEql(updatedResultsOffset); +}); + +test('Pagination scrolls the results to the top', async t => { + await VerticalResults.scrollToBottom(); + const scrollTop = await VerticalResults.getScrollTop(); + await t.expect(scrollTop).notEql(0); + await Pagination.nextResults(); + const scrollTopAfterPagination = await VerticalResults.getScrollTop(); + await t.expect(scrollTopAfterPagination).eql(0); +}); \ No newline at end of file From 18377da5fe6077dd167d59e86d905a3c45cf1f36 Mon Sep 17 00:00:00 2001 From: cea2aj <42848445+cea2aj@users.noreply.github.com> Date: Tue, 15 Jun 2021 11:20:40 -0400 Subject: [PATCH 45/56] Filter and Cluster acceptance tests for the locator (#831) Add additional filter and cluster tests Enable clustering on the filter page and add some test coverage for filters and clusters. J=SLAP-1362 TEST=acceptance --- .../locations_full_page_map_with_filters.json | 7 ++++ tests/acceptance/blocks/collapsiblefilters.js | 36 +++++++++++++++++++ .../vertical-full-page-map-with-filters.js | 32 +++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 tests/acceptance/blocks/collapsiblefilters.js create mode 100644 tests/acceptance/suites/vertical-full-page-map-with-filters.js diff --git a/test-site/config-overrides/locations_full_page_map_with_filters.json b/test-site/config-overrides/locations_full_page_map_with_filters.json index 4a97b36ce..433147ac1 100644 --- a/test-site/config-overrides/locations_full_page_map_with_filters.json +++ b/test-site/config-overrides/locations_full_page_map_with_filters.json @@ -5,5 +5,12 @@ "showMore": false, "searchOnChange": true } + }, + "verticalsToConfig": { + "KM": { + "mapConfig": { + "enablePinClustering": true + } + } } } \ No newline at end of file diff --git a/tests/acceptance/blocks/collapsiblefilters.js b/tests/acceptance/blocks/collapsiblefilters.js new file mode 100644 index 000000000..5c78dbb56 --- /dev/null +++ b/tests/acceptance/blocks/collapsiblefilters.js @@ -0,0 +1,36 @@ +import { Selector, t } from 'testcafe'; + +/** + * Models the user interaction with collapsible filters + */ +class CollapsibleFilters { + constructor () { + this._viewFiltersButton = Selector('.js-changeFilters'); + this._viewResultsButton = Selector('.Hitchhiker-ViewResultsButton'); + this._collapsibleFiltersExpanded = Selector('.CollapsibleFilters--expanded'); + } + + /** + * Opens the filter view + */ + async viewFilters () { + await t.click(this._viewFiltersButton); + } + + /** + * Closes the filter view and opens the list view + */ + async viewResults () { + await t.click(this._viewResultsButton); + } + + /** + * Returns true if the filter view is open + * @returns {Promise} + */ + async isFilterViewOpen () { + return this._collapsibleFiltersExpanded.exists; + } +} + +export default new CollapsibleFilters(); \ No newline at end of file diff --git a/tests/acceptance/suites/vertical-full-page-map-with-filters.js b/tests/acceptance/suites/vertical-full-page-map-with-filters.js new file mode 100644 index 000000000..be506efd9 --- /dev/null +++ b/tests/acceptance/suites/vertical-full-page-map-with-filters.js @@ -0,0 +1,32 @@ +import { PORT } from '../constants'; +import SearchBar from '../blocks/searchbar'; +import VerticalResults from '../blocks/verticalresults'; +import ThemeMap from '../blocks/thememap'; +import CollapsibleFilters from '../blocks/collapsiblefilters'; + +fixture`Vertical Full Page Map with Filters and Clusters` + .page(`http://localhost:${PORT}/locations_full_page_map_with_filters`) + +test('Clicking on a pin closes the filter view', async t => { + await SearchBar.submitQuery('virginia'); + await CollapsibleFilters.viewFilters(); + await ThemeMap.selectPin(); + const isFilterViewOpen = await CollapsibleFilters.isFilterViewOpen(); + await t.expect(isFilterViewOpen).notOk(); +}); + +test('Clicking on a cluster causes the map to zoom in', async t => { + await SearchBar.submitQuery('virginia'); + const zoom = await ThemeMap.getZoom(); + await ThemeMap.selectPinCluster(); + const zoomAfterSelectingCluster = await ThemeMap.getZoom(); + await t.expect(zoom).lt(zoomAfterSelectingCluster); +}); + +test('Clicking on a cluster causes a new search to be ran', async t => { + await SearchBar.submitQuery('virginia'); + const numResults = await VerticalResults.getNumResults(); + await ThemeMap.selectPinCluster(); + const numResultsAfterSelectingCluster = await VerticalResults.getNumResults(); + await t.expect(numResults).notEql(numResultsAfterSelectingCluster); +}); \ No newline at end of file From 9f925004f3b34caefe926db4d183bf13818873f1 Mon Sep 17 00:00:00 2001 From: Yen Truong <36055303+yen-tt@users.noreply.github.com> Date: Wed, 16 Jun 2021 16:57:44 -0400 Subject: [PATCH 46/56] add multilang testing to theme (#826) Set up test site to support multilanguage and generate Percy snapshots Updated locale config to support spanish (es) Added index.es.json and config-override *.es.json for pages to have spanish label and multilang cards, if exists Updated standardpagenavigator and iframenavigator to support navigating to non-default locale urls Added multilangphotographer to capture snapshots in alternate languages J=1363 TEST=manual and percy Launched test site and search/navigate through Spanish and English pages to see that messages are translated accordingly. New snapshots are generated on percy for alternate language (es). --- package.json | 3 +- test-site/config-overrides/events.es.json | 13 ++ test-site/config-overrides/faqs.es.json | 10 ++ .../financial_professionals.es.json | 12 ++ .../healthcare_professionals.es.json | 10 ++ .../config-overrides/help_articles.es.json | 12 ++ test-site/config-overrides/jobs.es.json | 12 ++ test-site/config-overrides/locations.es.json | 22 +++ .../locations_full_page_map.es.json | 33 +++++ ...cations_full_page_map_with_filters.es.json | 36 +++++ .../config-overrides/locations_google.es.json | 22 +++ test-site/config-overrides/menu_items.es.json | 10 ++ test-site/config-overrides/people.es.json | 11 ++ test-site/config-overrides/products.es.json | 10 ++ .../products_clickable_image.es.json | 10 ++ test-site/config/index.es.json | 47 +++++++ test-site/config/locale_config.json | 6 + test-site/scripts/build.sh | 2 +- test-site/scripts/create-verticals.js | 4 +- tests/percy/camera.js | 20 ++- tests/percy/iframepagenavigator.js | 32 ++++- tests/percy/index.js | 10 +- tests/percy/multilangphotographer.js | 129 ++++++++++++++++++ tests/percy/photographer.js | 4 +- tests/percy/queries.json | 14 ++ tests/percy/standardpagenavigator.js | 24 +++- 26 files changed, 501 insertions(+), 17 deletions(-) create mode 100644 test-site/config-overrides/events.es.json create mode 100644 test-site/config-overrides/faqs.es.json create mode 100644 test-site/config-overrides/financial_professionals.es.json create mode 100644 test-site/config-overrides/healthcare_professionals.es.json create mode 100644 test-site/config-overrides/help_articles.es.json create mode 100644 test-site/config-overrides/jobs.es.json create mode 100644 test-site/config-overrides/locations.es.json create mode 100644 test-site/config-overrides/locations_full_page_map.es.json create mode 100644 test-site/config-overrides/locations_full_page_map_with_filters.es.json create mode 100644 test-site/config-overrides/locations_google.es.json create mode 100644 test-site/config-overrides/menu_items.es.json create mode 100644 test-site/config-overrides/people.es.json create mode 100644 test-site/config-overrides/products.es.json create mode 100644 test-site/config-overrides/products_clickable_image.es.json create mode 100644 test-site/config/index.es.json create mode 100644 tests/percy/multilangphotographer.js create mode 100644 tests/percy/queries.json diff --git a/package.json b/package.json index 4b28b5714..abba97284 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "setup-test-site": "./test-site/scripts/setup.sh", "build-test-site": "./test-site/scripts/build.sh", "serve-test-site": "serve -p 5042 test-site/public", - "acceptance": "node ./tests/acceptance/index.js" + "acceptance": "node ./tests/acceptance/index.js", + "percy": "npx percy exec -- node tests/percy/index.js" }, "repository": { "type": "git", diff --git a/test-site/config-overrides/events.es.json b/test-site/config-overrides/events.es.json new file mode 100644 index 000000000..c5c339e2a --- /dev/null +++ b/test-site/config-overrides/events.es.json @@ -0,0 +1,13 @@ +{ + "verticalsToConfig": { + "events": { // The vertical key from your search configuration + // "label": "", // The name of the vertical in the section header and the navigation bar + // "verticalLimit": 15, // The result count limit for vertical search + // "universalLimit": 5, // The result count limit for universal search + "cardType": "multilang-event-standard", // The name of the card to use - e.g. accordion, location, customcard + "icon": "star", // The icon to use on the card for this vertical + "universalSectionTemplate": "standard", + "label": "Eventos" + } + } +} diff --git a/test-site/config-overrides/faqs.es.json b/test-site/config-overrides/faqs.es.json new file mode 100644 index 000000000..0124be2a2 --- /dev/null +++ b/test-site/config-overrides/faqs.es.json @@ -0,0 +1,10 @@ +{ + "verticalsToConfig": { + "faq": { + "cardType": "multilang-faq-accordion", // The name of the card to use - e.g. accordion, location, customcard + "icon": "star", // The icon to use on the card for this vertical + "universalSectionTemplate": "standard", + "label": "FAQs" + } + } +} \ No newline at end of file diff --git a/test-site/config-overrides/financial_professionals.es.json b/test-site/config-overrides/financial_professionals.es.json new file mode 100644 index 000000000..9a7f86520 --- /dev/null +++ b/test-site/config-overrides/financial_professionals.es.json @@ -0,0 +1,12 @@ +{ + "verticalsToConfig": { + "financial_professionals": { // The vertical key from your search configuration + "label": "Profesionales financieros", // The name of the vertical in the section header and the navigation bar + // "verticalLimit": 15, // The result count limit for vertical search + // "universalLimit": 5, // The result count limit for universal search + "cardType": "multilang-financial-professional-location", // The name of the card to use - e.g. accordion, location, customcard + "icon": "star", // The icon to use on the card for this vertical + "universalSectionTemplate": "standard" + } + } +} diff --git a/test-site/config-overrides/healthcare_professionals.es.json b/test-site/config-overrides/healthcare_professionals.es.json new file mode 100644 index 000000000..c53b2bcf7 --- /dev/null +++ b/test-site/config-overrides/healthcare_professionals.es.json @@ -0,0 +1,10 @@ +{ + "verticalsToConfig": { + "healthcare_professionals": { // The vertical key from your search configuration + "label": "Profesionales de la salud", // The name of the vertical in the section header and the navigation bar + "cardType": "multilang-professional-standard", // The name of the card to use - e.g. accordion, location, customcard + "icon": "star", // The icon to use on the card for this vertical + "universalSectionTemplate": "standard" + } + } +} diff --git a/test-site/config-overrides/help_articles.es.json b/test-site/config-overrides/help_articles.es.json new file mode 100644 index 000000000..5668bbfc0 --- /dev/null +++ b/test-site/config-overrides/help_articles.es.json @@ -0,0 +1,12 @@ +{ + "verticalsToConfig": { + "help_articles": { // The vertical key from your search configuration + "label": "Artículos de ayuda", // The name of the vertical in the section header and the navigation bar + // "verticalLimit": 15, // The result count limit for vertical search + // "universalLimit": 5, // The result count limit for universal search + "cardType": "document-standard", // The name of the card to use - e.g. accordion, location, customcard + "icon": "star", // The icon to use on the card for this vertical + "universalSectionTemplate": "standard" + } + } +} diff --git a/test-site/config-overrides/jobs.es.json b/test-site/config-overrides/jobs.es.json new file mode 100644 index 000000000..f239982c4 --- /dev/null +++ b/test-site/config-overrides/jobs.es.json @@ -0,0 +1,12 @@ +{ + "verticalsToConfig": { + "jobs": { // The vertical key from your search configuration + "label": "Trabajos", // The name of the vertical in the section header and the navigation bar + // "verticalLimit": 15, // The result count limit for vertical search + // "universalLimit": 5, // The result count limit for universal search + "cardType": "multilang-job-standard", // The name of the card to use - e.g. accordion, location, customcard + "icon": "star", // The icon to use on the card for this vertical + "universalSectionTemplate": "standard" + } + } +} diff --git a/test-site/config-overrides/locations.es.json b/test-site/config-overrides/locations.es.json new file mode 100644 index 000000000..a12100a08 --- /dev/null +++ b/test-site/config-overrides/locations.es.json @@ -0,0 +1,22 @@ +{ + "verticalsToConfig": { + "KM": { // The vertical key from your search configuration + "cardType": "multilang-location-standard", // The name of the card to use - e.g. accordion, location, customcard + "icon": "pin", // The icon to use on the card for this vertical + "mapConfig": { + "mapProvider": "MapBox", // The name of the provider (e.g. Mapbox, Google) + "pin": { + "backgroundColor": "", // Enter a hex value or color for the pin background + "labelColor": "", // Enter a hex value or color for the label color + "strokeColor": "" // Enter a hex value or color for the stroke color + }, + "noResults": { + "displayAllResults": true, // Set to FALSE to hide results on the map when a search returns no results + "visible": true // Set to FALSE to hide the map when a search returns no results + } + }, + "universalSectionTemplate": "standard", + "label": "Ubicaciones" + } + } +} \ No newline at end of file diff --git a/test-site/config-overrides/locations_full_page_map.es.json b/test-site/config-overrides/locations_full_page_map.es.json new file mode 100644 index 000000000..67beba06a --- /dev/null +++ b/test-site/config-overrides/locations_full_page_map.es.json @@ -0,0 +1,33 @@ +{ + "verticalsToConfig": { + "KM": { + "cardType": "multilang-location-standard", // The name of the card to use - e.g. accordion, location, customcard + "icon": "pin", // The icon to use on the card for this vertical + "mapConfig": { + //"enablePinClustering": true, // Cluster pins on the map that are close together. Defaults false + "mapProvider": "MapBox", // The name of the provider (e.g. Mapbox, Google) + "noResults": { + "displayAllResults": false // Set to FALSE to hide results on the map when a search returns no results + }, + "pin": { + "default": { // The pin in its normal state + "backgroundColor": "#5387d7", // Enter a hex value or color for the pin background + "strokeColor": "#2a446b", + "labelColor": "white" + }, + "hovered": { // The pin when it is hovered + "backgroundColor": "#2f4d71", + "strokeColor": "#172638", + "labelColor": "white" + }, + "selected": { // The pin when it is selected by mouse click or through a card click + "backgroundColor": "#2f4d71", + "strokeColor": "#172638", + "labelColor": "white" + } + } + }, + "universalSectionTemplate": "standard" + } + } +} \ No newline at end of file diff --git a/test-site/config-overrides/locations_full_page_map_with_filters.es.json b/test-site/config-overrides/locations_full_page_map_with_filters.es.json new file mode 100644 index 000000000..88e60a0a8 --- /dev/null +++ b/test-site/config-overrides/locations_full_page_map_with_filters.es.json @@ -0,0 +1,36 @@ +{ + "verticalsToConfig": { + "KM": { // The vertical key from your search configuration + // "label": "", // The name of the vertical in the section header and the navigation bar + // "verticalLimit": 15, // The result count limit for vertical search + // "universalLimit": 5, // The result count limit for universal search + "cardType": "multilang-location-standard", // The name of the card to use - e.g. accordion, location, customcard + "icon": "pin", // The icon to use on the card for this vertical + "mapConfig": { + //"enablePinClustering": true, // Cluster pins on the map that are close together. Defaults false + "mapProvider": "MapBox", // The name of the provider (e.g. Mapbox, Google) + "noResults": { + "displayAllResults": false // Set to FALSE to hide results on the map when a search returns no results + }, + "pin": { + "default": { // The pin in its normal state + "backgroundColor": "#5387d7", // Enter a hex value or color for the pin background + "strokeColor": "#2a446b", + "labelColor": "white" + }, + "hovered": { // The pin when it is hovered + "backgroundColor": "#2f4d71", + "strokeColor": "#172638", + "labelColor": "white" + }, + "selected": { // The pin when it is selected by mouse click or through a card click + "backgroundColor": "#2f4d71", + "strokeColor": "#172638", + "labelColor": "white" + } + } + }, + "universalSectionTemplate": "standard" + } + } +} \ No newline at end of file diff --git a/test-site/config-overrides/locations_google.es.json b/test-site/config-overrides/locations_google.es.json new file mode 100644 index 000000000..db2a6d91a --- /dev/null +++ b/test-site/config-overrides/locations_google.es.json @@ -0,0 +1,22 @@ +{ + "verticalsToConfig": { + "KM": { // The vertical key from your search configuration + // "label": "", // The name of the vertical in the section header and the navigation bar + "cardType": "multilang-location-standard", // The name of the card to use - e.g. accordion, location, customcard + "icon": "pin", // The icon to use on the card for this vertical + "mapConfig": { + "mapProvider": "Google", // The name of the provider (e.g. Mapbox, Google) + "pin": { + "backgroundColor": "", // Enter a hex value or color for the pin background + "labelColor": "", // Enter a hex value or color for the label color + "strokeColor": "" // Enter a hex value or color for the stroke color + }, + "noResults": { + "displayAllResults": true, // Set to FALSE to hide results on the map when a search returns no results + "visible": true // Set to FALSE to hide the map when a search returns no results + } + }, + "universalSectionTemplate": "standard" + } + } +} \ No newline at end of file diff --git a/test-site/config-overrides/menu_items.es.json b/test-site/config-overrides/menu_items.es.json new file mode 100644 index 000000000..0bb370950 --- /dev/null +++ b/test-site/config-overrides/menu_items.es.json @@ -0,0 +1,10 @@ +{ + "verticalsToConfig": { + "menu_items": { // The vertical key from your search configuration + "label": "Elementos de menú", // The name of the vertical in the section header and the navigation bar + "cardType": "multilang-menuitem-standard", // The name of the card to use - e.g. accordion, location, customcard + "icon": "star", // The icon to use on the card for this vertical + "universalSectionTemplate": "standard" + } + } +} diff --git a/test-site/config-overrides/people.es.json b/test-site/config-overrides/people.es.json new file mode 100644 index 000000000..fb81050d2 --- /dev/null +++ b/test-site/config-overrides/people.es.json @@ -0,0 +1,11 @@ +{ + "verticalsToConfig": { + "people": { // The vertical key from your search configuration + // "label": "", // The name of the vertical in the section header and the navigation bar + "cardType": "multilang-standard", // The name of the card to use - e.g. accordion, location, customcard + "icon": "star", // The icon to use on the card for this vertical + "universalSectionTemplate": "standard", + "label": "Personas" + } + } +} diff --git a/test-site/config-overrides/products.es.json b/test-site/config-overrides/products.es.json new file mode 100644 index 000000000..782f1bd0d --- /dev/null +++ b/test-site/config-overrides/products.es.json @@ -0,0 +1,10 @@ +{ + "verticalsToConfig": { + "products": { // The vertical key from your search configuration + "label": "Productos", // The name of the vertical in the section header and the navigation bar + "cardType": "multilang-product-prominentvideo", // The name of the card to use - e.g. accordion, location, customcard + "icon": "star", // The icon to use on the card for this vertical + "universalSectionTemplate": "standard" + } + } +} diff --git a/test-site/config-overrides/products_clickable_image.es.json b/test-site/config-overrides/products_clickable_image.es.json new file mode 100644 index 000000000..de30e7f0f --- /dev/null +++ b/test-site/config-overrides/products_clickable_image.es.json @@ -0,0 +1,10 @@ +{ + "verticalsToConfig": { + "products": { // The vertical key from your search configuration + "label": "Productos", // The name of the vertical in the section header and the navigation bar + "cardType": "multilang-product-prominentimage-clickable", // The name of the card to use - e.g. accordion, location, customcard + "icon": "star", // The icon to use on the card for this vertical + "universalSectionTemplate": "standard" + } + } +} diff --git a/test-site/config/index.es.json b/test-site/config/index.es.json new file mode 100644 index 000000000..66287ff4e --- /dev/null +++ b/test-site/config/index.es.json @@ -0,0 +1,47 @@ +{ + "componentSettings": { + /** + "QASubmission": { + "entityId": "", // Set the ID of the entity to use for Q&A submissions, must be of entity type "Organization" + "privacyPolicyUrl": "" // The fully qualified URL to the privacy policy + }, + **/ + "DirectAnswer": { + "types": { + "FEATURED_SNIPPET": { + "cardType": "documentsearch-standard" + }, + "FIELD_VALUE": { + "cardType": "multilang-allfields-standard" + } + } + }, + "SearchBar": { + "placeholderText": "Buscar" // The placeholder text in the answers search bar + } + }, + "verticalsToConfig": { + "Universal": { + "isFirst": "true", // Indicates that this should always appear first in the navigation bar + "label": "Todas" // The name of the universal tab in the navigation bar + }, + "KM": { + "universalSectionTemplate": "grid-two-columns", + "cardType": "multilang-financial-professional-location", + "mapConfig": { + "mapProvider": "Google" + } + }, + "products": { + "universalSectionTemplate": "grid-three-columns", + "cardType": "multilang-product-prominentimage" + }, + "links": { + "cardType": "multilang-link-standard" + }, + "healthcare_professionals": { + "cardType": "multilang-professional-location" + } + } +} + \ No newline at end of file diff --git a/test-site/config/locale_config.json b/test-site/config/locale_config.json index 5897cf38d..5f328802f 100644 --- a/test-site/config/locale_config.json +++ b/test-site/config/locale_config.json @@ -6,6 +6,12 @@ // "translationFile": ".po", // the filepath for the translation file // "urlOverride": "", // provide an override for the url path for this locale if you want it to be different than specified in the urlFormat object "experienceKey": "slanswers" // the unique key of your search configuration for this locale + }, + "es": { + // "fallback": [""], // allows you to specify locale fallbacks for this locale + // "translationFile": "../../translation/es.po", // the filepath for the translation file + // "urlOverride": "", // provide an override for the url path for this locale if you want it to be different than specified in the urlFormat object + "experienceKey": "slanswers-es" // the unique key of your search configuration for this locale } }, "urlFormat": { diff --git a/test-site/scripts/build.sh b/test-site/scripts/build.sh index dc3245e84..38c8b3abc 100755 --- a/test-site/scripts/build.sh +++ b/test-site/scripts/build.sh @@ -17,4 +17,4 @@ npx jambo directanswercard --name allfields-custom --templateCardFolder directan node scripts/create-verticals.js -npx jambo build && grunt webpack +npx jambo build && npx grunt webpack diff --git a/test-site/scripts/create-verticals.js b/test-site/scripts/create-verticals.js index 4dcdd4172..c89935ad7 100644 --- a/test-site/scripts/create-verticals.js +++ b/test-site/scripts/create-verticals.js @@ -90,7 +90,9 @@ const testSiteDir = path.resolve(__dirname, '..'); process.chdir(testSiteDir); Object.entries(verticalConfiguration).forEach(([pageName, config]) => { - execSync(`npx jambo vertical --name ${pageName} --verticalKey ${config.verticalKey} --template ${config.template} --cardName ${config.cardName}`); + execSync(`npx jambo vertical --name ${pageName} --verticalKey ${config.verticalKey} --template ${config.template} --cardName ${config.cardName} --locales es`); configMerger.mergeConfigForPage(pageName); pagePatcher.applyPatchToPage(pageName); + configMerger.mergeConfigForPage(pageName + '.es'); + pagePatcher.applyPatchToPage(pageName + '.es'); }); diff --git a/tests/percy/camera.js b/tests/percy/camera.js index c8e7afed5..cf2a127fc 100644 --- a/tests/percy/camera.js +++ b/tests/percy/camera.js @@ -7,10 +7,21 @@ class Camera { /** * @param {function} percySnapshot The percy snapshot function * @param {boolean} iframeMode Enables capturing iframe snapshots + * @param {string} locale Enables capturing locale specific snapshots */ - constructor(percySnapshot, iframeMode ) { + constructor(percySnapshot, iframeMode, locale='en') { this._percySnapshot = percySnapshot; this._iframeMode = iframeMode; + this._locale = locale; + } + + /** + * Set locale for snapshot of the site + * + * @param {string} locale + */ + setLocale(locale) { + this._locale = locale; } /** @@ -44,15 +55,14 @@ class Camera { } /** - * Returns the correct snapshot name based on the iframe mode + * Returns the correct snapshot name based on the iframe mode and locale * * @param {string} snapshotName * @returns {string} */ _getSnapshotName(snapshotName) { - return this._iframeMode - ? snapshotName + '_iframe' - : snapshotName; + let updatedSnapshotName = this._iframeMode ? snapshotName + '_iframe' : snapshotName; + return this._locale === 'en' ? updatedSnapshotName : this._locale + '--' + updatedSnapshotName; } } diff --git a/tests/percy/iframepagenavigator.js b/tests/percy/iframepagenavigator.js index 6c4f0bdec..660aaf75e 100644 --- a/tests/percy/iframepagenavigator.js +++ b/tests/percy/iframepagenavigator.js @@ -9,24 +9,50 @@ class IframePageNavigator extends PageNavigator { * @param {import('puppeteer').Page} page A Pupeteer Page * @param {string} siteUrl A url to the index of the site * @param {string} iframePage The name of the iframe page + * @param {string} defaultLocale default locale config of the site */ - constructor(page, siteUrl, iframePage) { + constructor(page, siteUrl, iframePage, defaultLocale='en') { super(); this._page = page; this._siteUrl = siteUrl; this._iframePage = iframePage; + this._defaultLocale = defaultLocale; + + /** + * Locale param for the site's url on universal page + * + * @type {string} + */ + this._localeUniversalUrlPath = ''; + + /** + * Locale param for the site's url on vertical page + * + * @type {string} + */ + this._localePrefix = ''; + } + + /** + * Sets locale param for the site's url based on given locale + * + * @param {string} locale + */ + setCurrentLocale(locale) { + this._localeUniversalUrlPath = locale === this._defaultLocale ? '' : '&verticalUrl=' + locale; + this._localePrefix = locale === this._defaultLocale ? '' : locale + '/'; } async gotoUniversalPage(queryParams = {}) { const queryParamsString = getQueryParamsString(queryParams); - const url = `${this._siteUrl}/${this._iframePage}.html?${queryParamsString}`; + const url = `${this._siteUrl}/${this._iframePage}.html?${queryParamsString}${this._localeUniversalUrlPath}`; await this._page.goto(url); await waitTillHTMLRendered(this._page); } async gotoVerticalPage(vertical, queryParams = {}) { const queryParamsString = getQueryParamsString(queryParams); - const url = `${this._siteUrl}/${this._iframePage}.html?verticalUrl=${vertical}.html&${queryParamsString}`; + const url = `${this._siteUrl}/${this._iframePage}.html?verticalUrl=${this._localePrefix}${vertical}.html&${queryParamsString}`; await this._page.goto(url); await waitTillHTMLRendered(this._page); } diff --git a/tests/percy/index.js b/tests/percy/index.js index 213426a03..c6b1728b3 100644 --- a/tests/percy/index.js +++ b/tests/percy/index.js @@ -1,9 +1,11 @@ const PercyScript = require('@percy/script'); const HttpServer = require('../test-utils/server'); const Photographer = require('./photographer'); +const MultilangPhotographer = require('./multilangphotographer'); const StandardPageNavigator = require('./standardpagenavigator'); const IframePageNavigator = require('./iframepagenavigator'); const Camera = require('./camera'); +const queryConfig = require('./queries.json'); const PORT = 5042; @@ -17,11 +19,17 @@ PercyScript.run(async (page, percySnapshot) => { const standardPageNavigator = new StandardPageNavigator(page, `http://localhost:${PORT}`); const iframePageNavigator = new IframePageNavigator(page, `http://localhost:${PORT}`, 'iframe_test'); + const standardCamera = new Camera(percySnapshot); const iframeCamera = new Camera(percySnapshot, true); await (new Photographer(standardPageNavigator, standardCamera).captureSnapshots()); await (new Photographer(iframePageNavigator, iframeCamera).captureSnapshots()); + standardPageNavigator.setCurrentLocale('es'); + standardCamera.setLocale('es'); + + await (new MultilangPhotographer(standardPageNavigator, standardCamera, queryConfig.es).captureSnapshots()); + server.shutdown(); -}); \ No newline at end of file +}); diff --git a/tests/percy/multilangphotographer.js b/tests/percy/multilangphotographer.js new file mode 100644 index 000000000..65bf8829e --- /dev/null +++ b/tests/percy/multilangphotographer.js @@ -0,0 +1,129 @@ +/** + * @typedef {import('./pagenavigator.js')} PageNavigator + * @typedef {import('./Camera.js')} Camera + */ + +/** + * Responsible for determining which snapshots to take for specific locale + */ +class MultilangPhotographer { + /** + * @param {PageNavigator} pageNavigator + * @param {Camera} camera + * @param {Object} queries custom queries for specific locale + */ + constructor(pageNavigator, camera, queries) { + this._pageNavigator = pageNavigator; + this._camera = camera; + this._queries = queries; + } + + /** + * Sets custom queries based on locale + * + * @param {Object} queries + */ + setLocaleQueries(queries) { + this._queries = queries; + } + + async captureSnapshots() { + await this._captureUniversalSearch(); + await this._captureVerticalSearch(); + await this._captureVerticalGridSearch(); + await this._captureVerticalMapSearch(); + await this._captureVerticalFullPageMapSearch(); + await this._captureDirectAnswers(); + } + + async _captureUniversalSearch () { + await this._pageNavigator.gotoUniversalPage(); + await this._camera.snapshot('universal-search'); + + await this._pageNavigator.gotoUniversalPage({ query: 'a' }); + await this._camera.snapshot('universal-search--no-results'); + + await this._pageNavigator.gotoUniversalPage({ query: this._queries.faq }); + await this._pageNavigator.click('.HitchhikerFaqAccordion-toggle') + await this._camera.snapshot('universal-search--faq-accordion'); + + await this._pageNavigator.gotoUniversalPage({ query: 'yext answers'}); + await this._camera.snapshot('universal-search--product-prominentimage'); + } + + async _captureVerticalSearch () { + await this._pageNavigator.gotoVerticalPage('events'); + await this._camera.snapshot('vertical-search'); + + await this._pageNavigator.gotoVerticalPage('events', { query: 'a' }); + await this._camera.snapshot('vertical-search--no-results'); + + await this._pageNavigator.gotoVerticalPage('financial_professionals', { query: 'connor' }); + await this._camera.snapshot('vertical-search--financial-professional-location'); + + await this._pageNavigator.gotoVerticalPage('jobs', { query: this._queries.job }); + await this._camera.snapshot('vertical-search--job-standard'); + + await this._pageNavigator.gotoVerticalPage('help_articles', { query: 'slap chop' }); + await this._camera.snapshot('vertical-search--document-standard'); + + await this._pageNavigator.gotoVerticalPage('menu_items', { query: this._queries.menu_item }); + await this._camera.snapshot('vertical-search--menuitem-standard'); + } + + async _captureVerticalGridSearch () { + await this._pageNavigator.gotoVerticalPage('people', { query: 'a' }); + await this._camera.snapshot('vertical-grid-search'); + + await this._pageNavigator.gotoVerticalPage('people', { query: 'vrginia' }); + await this._camera.snapshot('vertical-grid-search--spellcheck'); + + await this._pageNavigator.gotoVerticalPage('products', { query: 'yext answers' }); + await this._camera.snapshot('vertical-grid-search--product-prominentvideo'); + + await this._pageNavigator.gotoVerticalPage('products_clickable_image', { query: 'yext answers' }); + await this._camera.snapshot('vertical-grid-search--product-prominentimage-clickable'); + } + + async _captureVerticalMapSearch () { + await this._pageNavigator.gotoVerticalPage('locations', { query: 'a' }); + await this._camera.snapshot('vertical-map-search'); + + await this._pageNavigator.gotoVerticalPage('locations_google', { query: 'virginia' }); + await this._camera.snapshot('vertical-map-search--google'); + } + + async _captureVerticalFullPageMapSearch () { + await this._pageNavigator + .gotoVerticalPage('locations_full_page_map', { query: '' }); + await this._camera.snapshotDesktopOnly('vertical-full-page-map__desktop-view'); + await this._camera.snapshotMobileOnly('vertical-full-page-map__mobile-list-view'); + + await this._pageNavigator.click('.Answers-mobileToggle'); + await this._camera.snapshotMobileOnly('vertical-full-page-map__mobile-map-view'); + + const mapboxPinSelector = '.js-answersMap button'; + await this._pageNavigator.click(mapboxPinSelector); + await this._camera.snapshotMobileOnly('vertical-full-page-map__mobile-detail-view'); + + await this._pageNavigator + .gotoVerticalPage('locations_full_page_map', { query: 'office sparce'}); + await this._camera.snapshotDesktopOnly('vertical-full-page-map--spellcheck__desktop-view'); + await this._camera.snapshotMobileOnly('vertical-full-page-map--spellcheck__mobile-list-view'); + + await this._pageNavigator + .gotoVerticalPage('locations_full_page_map', { query: 'virginia' }); + await this._camera.snapshotDesktopOnly('vertical-full-page-map--nlp-filters__desktop-view'); + + await this._pageNavigator + .gotoVerticalPage('locations_full_page_map_with_filters', { query: 'virginia' }); + await this._camera.snapshotDesktopOnly('vertical-full-page-map-with-filters--nlp-filters__desktop-view'); + } + + async _captureDirectAnswers () { + await this._pageNavigator.gotoUniversalPage({ query: this._queries.field_direct_answers }); + await this._camera.snapshot('field-direct-answer'); + } +} + +module.exports = MultilangPhotographer; diff --git a/tests/percy/photographer.js b/tests/percy/photographer.js index c8a14cae5..8120f6752 100644 --- a/tests/percy/photographer.js +++ b/tests/percy/photographer.js @@ -38,7 +38,7 @@ class Photographer { await this._pageNavigator.gotoUniversalPage({ query: 'what if i forget my password?'}); await this._pageNavigator.click('.HitchhikerFaqAccordion-toggle') await this._camera.snapshot('universal-search--faq-accordion'); - + await this._pageNavigator.gotoUniversalPage({ query: 'yext answers'}); await this._camera.snapshot('universal-search--product-prominentimage'); } @@ -124,4 +124,4 @@ class Photographer { } } -module.exports = Photographer; \ No newline at end of file +module.exports = Photographer; diff --git a/tests/percy/queries.json b/tests/percy/queries.json new file mode 100644 index 000000000..89d895386 --- /dev/null +++ b/tests/percy/queries.json @@ -0,0 +1,14 @@ +{ + "en": { + "faq": "what if i forgot my password?", + "job": "job", + "menu_item": "roll", + "field_direct_answers": "bryan reed description" + }, + "es": { + "faq": "¿Qué pasa si olvidé mi contraseña?", + "job": "trabajo", + "menu_item": "rollo", + "field_direct_answers": "descripción de bryan reed" + } +} diff --git a/tests/percy/standardpagenavigator.js b/tests/percy/standardpagenavigator.js index 37e18ab54..b938aa8c8 100644 --- a/tests/percy/standardpagenavigator.js +++ b/tests/percy/standardpagenavigator.js @@ -8,23 +8,41 @@ class StandardPageNavigator extends PageNavigator { /** * @param {import('puppeteer').Page} page A Pupeteer Page * @param {string} siteUrl A url to the index of the site + * @param {string} defaultLocale default locale config of the site */ - constructor(page, siteUrl) { + constructor(page, siteUrl, defaultLocale='en') { super(); this._page = page; this._siteUrl = siteUrl; + this._defaultLocale = defaultLocale; + + /** + * Locale param for the site's url during page navigation + * + * @type {string} + */ + this._localeUrlPath = ''; + } + + /** + * Sets locale param for the site's url based on given locale + * + * @param {string} locale + */ + setCurrentLocale(locale) { + this._localeUrlPath = locale === this._defaultLocale? '' : '/' + locale; } async gotoUniversalPage(queryParams = {}) { const queryParamsString = getQueryParamsString(queryParams); - const url = `${this._siteUrl}?${queryParamsString}`; + const url = `${this._siteUrl}${this._localeUrlPath}?${queryParamsString}`; await this._page.goto(url); await waitTillHTMLRendered(this._page); } async gotoVerticalPage(vertical, queryParams = {}) { const queryParamsString = getQueryParamsString(queryParams); - const url = `${this._siteUrl}/${vertical}.html?${queryParamsString}`; + const url = `${this._siteUrl}${this._localeUrlPath}/${vertical}.html?${queryParamsString}`; await this._page.goto(url); await waitTillHTMLRendered(this._page); } From 72ba4c75e4a63fc2806e7ec6036e3e4bd5c6257f Mon Sep 17 00:00:00 2001 From: Yen Truong <36055303+yen-tt@users.noreply.github.com> Date: Thu, 17 Jun 2021 12:00:46 -0400 Subject: [PATCH 47/56] Refresh error due to double encoding in verticalUrl (#836) * Fix error after refresh due to double encoding in verticalUrl - URLSearchParams set() encoded verticalUrl even though it's already encoded since it's extracted from window's URL pathname. updated to append to the param string - replace() only update the first instance unless a global modifier is used (e.g. this would cause refresh issue on mulilang site for verticalUrl as 'es/help_articles'. updated to replaceAll J=SLAP-1376 TEST=manual Launched multilang site with iframe data-path directed to a page with spaces in its names. Confirmed refresh and back/forward nav works accordingly. Co-authored-by: Yen Truong --- layouts/html.hbs | 11 +++++------ static/js/iframe-common.js | 3 --- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/layouts/html.hbs b/layouts/html.hbs index 3563474eb..9de2a85b0 100644 --- a/layouts/html.hbs +++ b/layouts/html.hbs @@ -115,12 +115,11 @@ \ No newline at end of file +}; \ No newline at end of file diff --git a/tests/percy/photographer.js b/tests/percy/photographer.js index 8120f6752..d49b3797a 100644 --- a/tests/percy/photographer.js +++ b/tests/percy/photographer.js @@ -121,6 +121,12 @@ class Photographer { await this._pageNavigator.gotoUniversalPage({ query: 'where was joe exotic born?' }); await this._camera.snapshot('documentsearch-direct-answer') + + await this._pageNavigator.gotoUniversalPage({ query: 'how to get rich text' }); + await this._camera.snapshot('documentsearch-rich-text-direct-answer') + + await this._pageNavigator.gotoUniversalPage({ query: 'who is howard?' }); + await this._camera.snapshot('documentsearch-rich-text-picture-direct-answer') } } From 4910fe5bd87f6a6795acaff10a165cfb3155bc60 Mon Sep 17 00:00:00 2001 From: cea2aj <42848445+cea2aj@users.noreply.github.com> Date: Sun, 20 Jun 2021 23:08:45 -0400 Subject: [PATCH 50/56] Runtime config and JWT support (#843) Add runtime config and JWT support --- cards/event-standard/component.js | 8 ++- cards/faq-accordion/component.js | 8 ++- .../component.js | 8 ++- .../template.hbs | 2 +- cards/job-standard/component.js | 6 +- cards/link-standard/component.js | 4 +- cards/location-standard/component.js | 8 ++- cards/location-standard/template.hbs | 2 +- cards/menuitem-standard/component.js | 8 ++- cards/multilang-event-standard/component.js | 8 ++- cards/multilang-faq-accordion/component.js | 8 ++- .../component.js | 8 ++- .../template.hbs | 2 +- cards/multilang-job-standard/component.js | 6 +- cards/multilang-link-standard/component.js | 4 +- .../multilang-location-standard/component.js | 8 ++- .../multilang-location-standard/template.hbs | 2 +- .../multilang-menuitem-standard/component.js | 8 ++- .../component.js | 6 +- .../component.js | 9 +-- .../component.js | 10 ++-- cards/multilang-product-standard/component.js | 9 +-- .../component.js | 8 ++- .../template.hbs | 2 +- .../component.js | 8 ++- .../template.hbs | 2 +- cards/multilang-standard/component.js | 8 ++- .../component.js | 6 +- cards/product-prominentimage/component.js | 9 +-- cards/product-standard/component.js | 9 +-- cards/professional-location/component.js | 8 ++- cards/professional-location/template.hbs | 2 +- cards/professional-standard/component.js | 8 ++- cards/professional-standard/template.hbs | 2 +- cards/standard/component.js | 8 ++- .../allfields-standard/component.js | 10 ++-- .../documentsearch-standard/component.js | 7 ++- .../multilang-allfields-standard/component.js | 10 ++-- global_config.json | 2 + hooks/templatedataformatter.js | 26 +++++++++ layouts/html.hbs | 27 ++++++--- script/core.hbs | 6 +- static/entry.js | 2 +- static/js/HitchhikerJS.js | 11 ++++ static/js/answers-experience-frame.js | 41 +++++++++++++ static/js/iframe-common.js | 42 +++++++++++++- static/js/iframe-prod.js | 10 +++- static/js/iframe-staging.js | 8 ++- static/js/iframe.js | 8 ++- static/js/manual-initializer.js | 49 ++++++++++++++++ static/js/runtime-config-receiver.js | 15 +++++ static/js/runtime-config.js | 58 +++++++++++++++++++ static/webpack-config.js | 23 +++++++- static/webpack/getCleanedJamboInjectedData.js | 31 ++++++++++ test-site/config/global_config.json | 2 + test-site/jambo.json | 4 +- .../webpack/getCleanedJamboInjectedData.js | 34 +++++++++++ 57 files changed, 529 insertions(+), 119 deletions(-) create mode 100644 static/js/answers-experience-frame.js create mode 100644 static/js/manual-initializer.js create mode 100644 static/js/runtime-config-receiver.js create mode 100644 static/js/runtime-config.js create mode 100644 static/webpack/getCleanedJamboInjectedData.js create mode 100644 tests/static/webpack/getCleanedJamboInjectedData.js diff --git a/cards/event-standard/component.js b/cards/event-standard/component.js index f11d6f8d4..a9cb2278f 100644 --- a/cards/event-standard/component.js +++ b/cards/event-standard/component.js @@ -12,10 +12,12 @@ class event_standardCardComponent extends BaseCard['event-standard'] { * @param profile profile of the entity in the card */ dataForRender(profile) { + const linkTarget = AnswersExperience.runtimeConfig.get('linkTarget') || '_top'; + return { title: profile.name, // The header text of the card url: profile.website, // If the card title is a clickable link, set URL here - target: '_top', // If the title's URL should open in a new tab, etc. + target: linkTarget, // If the title's URL should open in a new tab, etc. titleEventOptions: this.addDefaultEventOptions(), date: Formatter.bigDate(profile), subtitle: Formatter.dateRange(profile), @@ -32,7 +34,7 @@ class event_standardCardComponent extends BaseCard['event-standard'] { label: 'RSVP', // The CTA's label iconName: 'calendar', // The icon to use for the CTA url: profile.ticketUrl || profile.website, // The URL a user will be directed to when clicking - target: '_top', // Where the new URL will be opened + target: linkTarget, // Where the new URL will be opened eventType: 'RSVP', // Type of Analytics event fired when clicking the CTA eventOptions: this.addDefaultEventOptions(), // ariaLabel: '', // Accessible text providing a descriptive label for the CTA @@ -42,7 +44,7 @@ class event_standardCardComponent extends BaseCard['event-standard'] { label: 'Directions', iconName: 'directions', url: Formatter.getDirectionsUrl(profile), - target: '_top', + target: linkTarget, eventType: 'DRIVING_DIRECTIONS', eventOptions: this.addDefaultEventOptions(), // ariaLabel: '', diff --git a/cards/faq-accordion/component.js b/cards/faq-accordion/component.js index d17b0a632..f05c1e8ca 100644 --- a/cards/faq-accordion/component.js +++ b/cards/faq-accordion/component.js @@ -12,10 +12,12 @@ class faq_accordionCardComponent extends BaseCard['faq-accordion'] { * @param {Object} profile of the entity in the card */ dataForRender(profile) { + const linkTarget = AnswersExperience.runtimeConfig.get('linkTarget') || '_top'; + return { title: profile.question || profile.name, // The header text of the card // subtitle: '', // The sub-header text of the card - details: profile.answer ? ANSWERS.formatRichText(profile.answer, "answer", "_top") : null, // The text in the body of the card + details: profile.answer ? ANSWERS.formatRichText(profile.answer, "answer", linkTarget) : null, // The text in the body of the card // If the card's details are longer than a certain character count, you can truncate the // text. A toggle will be supplied that can show or hide the truncated text. // showMoreDetails: { @@ -29,7 +31,7 @@ class faq_accordionCardComponent extends BaseCard['faq-accordion'] { label: profile.c_primaryCTA ? profile.c_primaryCTA.label : null, // The CTA's label // iconName: '', // The icon to use for the CTA url: Formatter.generateCTAFieldTypeLink(profile.c_primaryCTA), // The URL a user will be directed to when clicking - target: '_top', // Where the new URL will be opened. To open in a new tab use '_blank' + target: linkTarget, // Where the new URL will be opened. To open in a new tab use '_blank' eventType: 'CTA_CLICK', // Type of Analytics event fired when clicking the CTA // Event options for the analytics event fired when this CTA is clicked. eventOptions: this.addDefaultEventOptions({ /* Add additional options here */ }), @@ -40,7 +42,7 @@ class faq_accordionCardComponent extends BaseCard['faq-accordion'] { label: profile.c_secondaryCTA ? profile.c_secondaryCTA.label : null, // iconName: '', url: Formatter.generateCTAFieldTypeLink(profile.c_secondaryCTA), - target: '_top', + target: linkTarget, eventType: 'CTA_CLICK', eventOptions: this.addDefaultEventOptions({ /* Add additional options here */ }), // ariaLabel: '', diff --git a/cards/financial-professional-location/component.js b/cards/financial-professional-location/component.js index 615bbd625..033539bba 100644 --- a/cards/financial-professional-location/component.js +++ b/cards/financial-professional-location/component.js @@ -18,12 +18,14 @@ class financial_professional_locationCardComponent extends BaseCard['financial-p * @param profile profile of the entity in the card */ dataForRender(profile) { + const linkTarget = AnswersExperience.runtimeConfig.get('linkTarget') || '_top'; + return { showOrdinal: true, // Show the map pin number on the card. Only supported for universal search title: profile.name, // The header text of the card // subtitle: '', // The sub-header text of the card url: profile.website || profile.landingPageUrl, // If the card title is a clickable link, set URL here - target: '_top', // If the title's URL should open in a new tab, etc. + target: linkTarget, // If the title's URL should open in a new tab, etc. titleEventOptions: this.addDefaultEventOptions(), address: Formatter.address(profile), // The address for the card details: profile.description, // The text in the body of the card @@ -48,7 +50,7 @@ class financial_professional_locationCardComponent extends BaseCard['financial-p label: profile.c_primaryCTA ? profile.c_primaryCTA.label : null, // The CTA's label iconName: 'chevron', // The icon to use for the CTA url: Formatter.generateCTAFieldTypeLink(profile.c_primaryCTA), // The URL a user will be directed to when clicking - target: '_top', // Where the new URL will be opened + target: linkTarget, // Where the new URL will be opened eventType: 'CTA_CLICK', // Type of Analytics event fired when clicking the CTA eventOptions: this.addDefaultEventOptions(), // ariaLabel: '', // Accessible text providing a descriptive label for the CTA @@ -58,7 +60,7 @@ class financial_professional_locationCardComponent extends BaseCard['financial-p label: profile.c_secondaryCTA ? profile.c_secondaryCTA.label : null, iconName: 'chevron', url: Formatter.generateCTAFieldTypeLink(profile.c_secondaryCTA), - target: '_top', + target: linkTarget, eventType: 'CTA_CLICK', eventOptions: this.addDefaultEventOptions(), // ariaLabel: '' diff --git a/cards/financial-professional-location/template.hbs b/cards/financial-professional-location/template.hbs index 32aa56dfd..27698dedc 100644 --- a/cards/financial-professional-location/template.hbs +++ b/cards/financial-professional-location/template.hbs @@ -145,7 +145,7 @@ href="tel:{{card.phone}}" data-eventtype="TAP_TO_CALL" data-eventoptions='{{json card.phoneEventOptions}}' - target="_top"> + target={{#if card.target}}"{{card.target}}"{{else}}"_top"{{/if}}> {{card.phone}} diff --git a/cards/job-standard/component.js b/cards/job-standard/component.js index e622f9396..17893ce3a 100644 --- a/cards/job-standard/component.js +++ b/cards/job-standard/component.js @@ -12,10 +12,12 @@ class job_standardCardComponent extends BaseCard['job-standard'] { * @param profile profile of the entity in the card */ dataForRender(profile) { + const linkTarget = AnswersExperience.runtimeConfig.get('linkTarget') || '_top'; + return { title: profile.name, // The header text of the card url: profile.landingPageUrl, // If the card title is a clickable link, set URL here - target: '_top', // If the title's URL should open in a new tab, etc. + target: linkTarget, // If the title's URL should open in a new tab, etc. // image: '', // The URL of the image to display on the card // tagLabel: '', // The label of the displayed image titleEventOptions: this.addDefaultEventOptions(), @@ -33,7 +35,7 @@ class job_standardCardComponent extends BaseCard['job-standard'] { label: 'Apply Now', // The CTA's label iconName: 'briefcase', // The icon to use for the CTA url: profile.applicationUrl || profile.landingPageUrl, // The URL a user will be directed to when clicking - target: '_top', // Where the new URL will be opened + target: linkTarget, // Where the new URL will be opened eventType: 'CTA_CLICK', // Type of Analytics event fired when clicking the CTA eventOptions: this.addDefaultEventOptions(), // ariaLabel: '', // Accessible text providing a descriptive label for the CTA diff --git a/cards/link-standard/component.js b/cards/link-standard/component.js index 6f593f224..5061223ae 100644 --- a/cards/link-standard/component.js +++ b/cards/link-standard/component.js @@ -12,10 +12,12 @@ class link_standardCardComponent extends BaseCard['link-standard'] { * @param profile profile of the entity in the card */ dataForRender(profile) { + const linkTarget = AnswersExperience.runtimeConfig.get('linkTarget') || '_top'; + return { title: profile.htmlTitle, // The header text of the card url: profile.link, // If the card title is a clickable link, set URL here - target: '_top', // If the title's URL should open in a new tab, etc. + target: linkTarget, // If the title's URL should open in a new tab, etc. titleEventOptions: this.addDefaultEventOptions(), // subtitle: '', // The sub-header text of the card // If the card's details are longer than a certain character count, you can truncate the diff --git a/cards/location-standard/component.js b/cards/location-standard/component.js index 78a2e1be9..8e997c306 100644 --- a/cards/location-standard/component.js +++ b/cards/location-standard/component.js @@ -18,10 +18,12 @@ class location_standardCardComponent extends BaseCard['location-standard'] { * @param {Object} profile of the entity in the card */ dataForRender(profile) { + const linkTarget = AnswersExperience.runtimeConfig.get('linkTarget') || '_top'; + return { title: profile.name, // The header text of the card url: profile.website || profile.landingPageUrl, // If the card title is a clickable link, set URL here - target: '_top', // If the title's URL should open in a new tab, etc. + target: linkTarget, // If the title's URL should open in a new tab, etc. titleEventOptions: this.addDefaultEventOptions(), // The event options for title click analytics // subtitle: '', // The sub-header text of the card hours: Formatter.openStatus(profile), @@ -38,7 +40,7 @@ class location_standardCardComponent extends BaseCard['location-standard'] { label: 'Call', // The label of the CTA iconName: 'phone', // The icon to use for the CTA url: Formatter.phoneLink(profile), // The URL a user will be directed to when clicking - target: '_top', // If the URL will be opened in a new tab, etc. + target: linkTarget, // If the URL will be opened in a new tab, etc. eventType: 'TAP_TO_CALL', // Type of Analytics event fired when clicking the CTA eventOptions: this.addDefaultEventOptions(), // The analytics event options for CTA clicks // ariaLabel: '', // Accessible text providing a descriptive label for the CTA @@ -47,7 +49,7 @@ class location_standardCardComponent extends BaseCard['location-standard'] { label: 'Get Directions', iconName: 'directions', url: Formatter.getDirectionsUrl(profile), - target: '_top', + target: linkTarget, eventType: 'DRIVING_DIRECTIONS', eventOptions: this.addDefaultEventOptions(), // ariaLabel: '', diff --git a/cards/location-standard/template.hbs b/cards/location-standard/template.hbs index ccd68ce60..d0d127c13 100644 --- a/cards/location-standard/template.hbs +++ b/cards/location-standard/template.hbs @@ -47,7 +47,7 @@ + target={{#if card.target}}"{{card.target}}"{{else}}"_top"{{/if}}> {{card.phone}} diff --git a/cards/menuitem-standard/component.js b/cards/menuitem-standard/component.js index 98734bef4..c0c6ef15e 100644 --- a/cards/menuitem-standard/component.js +++ b/cards/menuitem-standard/component.js @@ -12,10 +12,12 @@ class menuitem_standardCardComponent extends BaseCard['menuitem-standard'] { * @param profile profile of the entity in the card */ dataForRender(profile) { + const linkTarget = AnswersExperience.runtimeConfig.get('linkTarget') || '_top'; + return { title: profile.name, // The header text of the card url: profile.landingPageUrl, // If the card title is a clickable link, set URL here - target: '_top', // If the title's URL should open in a new tab, etc. + target: linkTarget, // If the title's URL should open in a new tab, etc. image: Formatter.image(profile.c_photo).url, // The URL of the image to display on the card altText: Formatter.image(profile.c_photo).alternateText, // The alternate text for the image // tagLabel: '', // The label of the displayed image @@ -38,7 +40,7 @@ class menuitem_standardCardComponent extends BaseCard['menuitem-standard'] { label: 'Order Now', // The CTA's label iconName: 'chevron', // The icon to use for the CTA url: profile.orderUrl && profile.orderUrl.url, // The URL a user will be directed to when clicking - target: '_top', // Where the new URL will be opened + target: linkTarget, // Where the new URL will be opened eventType: 'CTA_CLICK', // Type of Analytics event fired when clicking the CTA eventOptions: this.addDefaultEventOptions(), // ariaLabel: '', // Accessible text providing a descriptive label for the CTA @@ -48,7 +50,7 @@ class menuitem_standardCardComponent extends BaseCard['menuitem-standard'] { label: 'View Menu', iconName: 'magnifying_glass', url: profile.landingPageUrl, - target: '_top', + target: linkTarget, eventType: 'CTA_CLICK', eventOptions: this.addDefaultEventOptions(), // ariaLabel: '', diff --git a/cards/multilang-event-standard/component.js b/cards/multilang-event-standard/component.js index 4a47ea640..af223357c 100644 --- a/cards/multilang-event-standard/component.js +++ b/cards/multilang-event-standard/component.js @@ -12,10 +12,12 @@ class multilang_event_standardCardComponent extends BaseCard['multilang-event-st * @param profile profile of the entity in the card */ dataForRender(profile) { + const linkTarget = AnswersExperience.runtimeConfig.get('linkTarget') || '_top'; + return { title: profile.name, // The header text of the card url: profile.website, // If the card title is a clickable link, set URL here - target: '_top', // If the title's URL should open in a new tab, etc. + target: linkTarget, // If the title's URL should open in a new tab, etc. titleEventOptions: this.addDefaultEventOptions(), date: Formatter.bigDate(profile), subtitle: Formatter.dateRange(profile), @@ -32,7 +34,7 @@ class multilang_event_standardCardComponent extends BaseCard['multilang-event-st label: {{ translateJS phrase='RSVP' context='RSVP is a verb' }}, // The CTA's label iconName: 'calendar', // The icon to use for the CTA url: profile.ticketUrl || profile.website, // The URL a user will be directed to when clicking - target: '_top', // Where the new URL will be opened + target: linkTarget, // Where the new URL will be opened eventType: 'RSVP', // Type of Analytics event fired when clicking the CTA eventOptions: this.addDefaultEventOptions(), // ariaLabel: '', // Accessible text providing a descriptive label for the CTA @@ -42,7 +44,7 @@ class multilang_event_standardCardComponent extends BaseCard['multilang-event-st label: {{ translateJS phrase='Directions' }}, iconName: 'directions', url: Formatter.getDirectionsUrl(profile), - target: '_top', + target: linkTarget, eventType: 'DRIVING_DIRECTIONS', eventOptions: this.addDefaultEventOptions(), // ariaLabel: '', diff --git a/cards/multilang-faq-accordion/component.js b/cards/multilang-faq-accordion/component.js index f4c15c65d..529fbb14a 100644 --- a/cards/multilang-faq-accordion/component.js +++ b/cards/multilang-faq-accordion/component.js @@ -12,10 +12,12 @@ class multilang_faq_accordionCardComponent extends BaseCard['multilang-faq-accor * @param {Object} profile of the entity in the card */ dataForRender(profile) { + const linkTarget = AnswersExperience.runtimeConfig.get('linkTarget') || '_top'; + return { title: profile.question || profile.name, // The header text of the card // subtitle: '', // The sub-header text of the card - details: profile.answer ? ANSWERS.formatRichText(profile.answer, "answer", "_top") : null, // The text in the body of the card + details: profile.answer ? ANSWERS.formatRichText(profile.answer, "answer", linkTarget) : null, // The text in the body of the card // If the card's details are longer than a certain character count, you can truncate the // text. A toggle will be supplied that can show or hide the truncated text. // showMoreDetails: { @@ -29,7 +31,7 @@ class multilang_faq_accordionCardComponent extends BaseCard['multilang-faq-accor label: profile.c_primaryCTA ? profile.c_primaryCTA.label : null, // The CTA's label // iconName: '', // The icon to use for the CTA url: Formatter.generateCTAFieldTypeLink(profile.c_primaryCTA), // The URL a user will be directed to when clicking - target: '_top', // Where the new URL will be opened. To open in a new tab use '_blank' + target: linkTarget, // Where the new URL will be opened. To open in a new tab use '_blank' eventType: 'CTA_CLICK', // Type of Analytics event fired when clicking the CTA // Event options for the analytics event fired when this CTA is clicked. eventOptions: this.addDefaultEventOptions({ /* Add additional options here */ }), @@ -40,7 +42,7 @@ class multilang_faq_accordionCardComponent extends BaseCard['multilang-faq-accor label: profile.c_secondaryCTA ? profile.c_secondaryCTA.label : null, // iconName: '', url: Formatter.generateCTAFieldTypeLink(profile.c_secondaryCTA), - target: '_top', + target: linkTarget, eventType: 'CTA_CLICK', eventOptions: this.addDefaultEventOptions({ /* Add additional options here */ }), // ariaLabel: '', diff --git a/cards/multilang-financial-professional-location/component.js b/cards/multilang-financial-professional-location/component.js index 3d74dd043..07595f9b3 100644 --- a/cards/multilang-financial-professional-location/component.js +++ b/cards/multilang-financial-professional-location/component.js @@ -18,12 +18,14 @@ class multilang_financial_professional_locationCardComponent extends BaseCard['m * @param profile profile of the entity in the card */ dataForRender(profile) { + const linkTarget = AnswersExperience.runtimeConfig.get('linkTarget') || '_top'; + return { showOrdinal: true, // Show the map pin number on the card. Only supported for universal search title: profile.name, // The header text of the card // subtitle: '', // The sub-header text of the card url: profile.website || profile.landingPageUrl, // If the card title is a clickable link, set URL here - target: '_top', // If the title's URL should open in a new tab, etc. + target: linkTarget, // If the title's URL should open in a new tab, etc. titleEventOptions: this.addDefaultEventOptions(), address: Formatter.address(profile), // The address for the card details: profile.description, // The text in the body of the card @@ -48,7 +50,7 @@ class multilang_financial_professional_locationCardComponent extends BaseCard['m label: profile.c_primaryCTA ? profile.c_primaryCTA.label : null, // The CTA's label iconName: 'chevron', // The icon to use for the CTA url: Formatter.generateCTAFieldTypeLink(profile.c_primaryCTA), // The URL a user will be directed to when clicking - target: '_top', // Where the new URL will be opened + target: linkTarget, // Where the new URL will be opened eventType: 'CTA_CLICK', // Type of Analytics event fired when clicking the CTA eventOptions: this.addDefaultEventOptions(), // ariaLabel: '', // Accessible text providing a descriptive label for the CTA @@ -58,7 +60,7 @@ class multilang_financial_professional_locationCardComponent extends BaseCard['m label: profile.c_secondaryCTA ? profile.c_secondaryCTA.label : null, iconName: 'chevron', url: Formatter.generateCTAFieldTypeLink(profile.c_secondaryCTA), - target: '_top', + target: linkTarget, eventType: 'CTA_CLICK', eventOptions: this.addDefaultEventOptions(), // ariaLabel: '' diff --git a/cards/multilang-financial-professional-location/template.hbs b/cards/multilang-financial-professional-location/template.hbs index f39bfa45d..6ed5d576b 100644 --- a/cards/multilang-financial-professional-location/template.hbs +++ b/cards/multilang-financial-professional-location/template.hbs @@ -145,7 +145,7 @@ href="tel:{{card.phone}}" data-eventtype="TAP_TO_CALL" data-eventoptions='{{json card.phoneEventOptions}}' - target="_top"> + target={{#if card.target}}"{{card.target}}"{{else}}"_top"{{/if}}> {{card.phone}} diff --git a/cards/multilang-job-standard/component.js b/cards/multilang-job-standard/component.js index 61deb2862..db073bd0c 100644 --- a/cards/multilang-job-standard/component.js +++ b/cards/multilang-job-standard/component.js @@ -12,10 +12,12 @@ class multilang_job_standardCardComponent extends BaseCard['multilang-job-standa * @param profile profile of the entity in the card */ dataForRender(profile) { + const linkTarget = AnswersExperience.runtimeConfig.get('linkTarget') || '_top'; + return { title: profile.name, // The header text of the card url: profile.landingPageUrl, // If the card title is a clickable link, set URL here - target: '_top', // If the title's URL should open in a new tab, etc. + target: linkTarget, // If the title's URL should open in a new tab, etc. // image: '', // The URL of the image to display on the card // tagLabel: '', // The label of the displayed image titleEventOptions: this.addDefaultEventOptions(), @@ -33,7 +35,7 @@ class multilang_job_standardCardComponent extends BaseCard['multilang-job-standa label: {{ translateJS phrase='Apply Now' }}, // The CTA's label iconName: 'briefcase', // The icon to use for the CTA url: profile.applicationUrl || profile.landingPageUrl, // The URL a user will be directed to when clicking - target: '_top', // Where the new URL will be opened + target: linkTarget, // Where the new URL will be opened eventType: 'CTA_CLICK', // Type of Analytics event fired when clicking the CTA eventOptions: this.addDefaultEventOptions(), // ariaLabel: '', // Accessible text providing a descriptive label for the CTA diff --git a/cards/multilang-link-standard/component.js b/cards/multilang-link-standard/component.js index c1b450833..2e1b5e74d 100644 --- a/cards/multilang-link-standard/component.js +++ b/cards/multilang-link-standard/component.js @@ -12,10 +12,12 @@ class multilang_link_standardCardComponent extends BaseCard['multilang-link-stan * @param profile profile of the entity in the card */ dataForRender(profile) { + const linkTarget = AnswersExperience.runtimeConfig.get('linkTarget') || '_top'; + return { title: profile.htmlTitle, // The header text of the card url: profile.link, // If the card title is a clickable link, set URL here - target: '_top', // If the title's URL should open in a new tab, etc. + target: linkTarget, // If the title's URL should open in a new tab, etc. titleEventOptions: this.addDefaultEventOptions(), // subtitle: '', // The sub-header text of the card // If the card's details are longer than a certain character count, you can truncate the diff --git a/cards/multilang-location-standard/component.js b/cards/multilang-location-standard/component.js index e9bc609bd..bc5d5d0c4 100644 --- a/cards/multilang-location-standard/component.js +++ b/cards/multilang-location-standard/component.js @@ -18,10 +18,12 @@ class multilang_location_standardCardComponent extends BaseCard['multilang-locat * @param {Object} profile of the entity in the card */ dataForRender(profile) { + const linkTarget = AnswersExperience.runtimeConfig.get('linkTarget') || '_top'; + return { title: profile.name, // The header text of the card url: profile.website || profile.landingPageUrl, // If the card title is a clickable link, set URL here - target: '_top', // If the title's URL should open in a new tab, etc. + target: linkTarget, // If the title's URL should open in a new tab, etc. titleEventOptions: this.addDefaultEventOptions(), // The event options for title click analytics // subtitle: '', // The sub-header text of the card hours: Formatter.openStatus(profile), @@ -38,7 +40,7 @@ class multilang_location_standardCardComponent extends BaseCard['multilang-locat label: {{ translateJS phrase='Call' context='Call is a verb' }}, // The label of the CTA iconName: 'phone', // The icon to use for the CTA url: Formatter.phoneLink(profile), // The URL a user will be directed to when clicking - target: '_top', // If the URL will be opened in a new tab, etc. + target: linkTarget, // If the URL will be opened in a new tab, etc. eventType: 'TAP_TO_CALL', // Type of Analytics event fired when clicking the CTA eventOptions: this.addDefaultEventOptions(), // The analytics event options for CTA clicks // ariaLabel: '', // Accessible text providing a descriptive label for the CTA @@ -47,7 +49,7 @@ class multilang_location_standardCardComponent extends BaseCard['multilang-locat label: {{ translateJS phrase='Get Directions' }}, iconName: 'directions', url: Formatter.getDirectionsUrl(profile), - target: '_top', + target: linkTarget, eventType: 'DRIVING_DIRECTIONS', eventOptions: this.addDefaultEventOptions(), // ariaLabel: '', diff --git a/cards/multilang-location-standard/template.hbs b/cards/multilang-location-standard/template.hbs index 9a101f80d..a718100ac 100644 --- a/cards/multilang-location-standard/template.hbs +++ b/cards/multilang-location-standard/template.hbs @@ -47,7 +47,7 @@ + target={{#if card.target}}"{{card.target}}"{{else}}"_top"{{/if}}> {{card.phone}} diff --git a/cards/multilang-menuitem-standard/component.js b/cards/multilang-menuitem-standard/component.js index a11366f11..269728ca4 100644 --- a/cards/multilang-menuitem-standard/component.js +++ b/cards/multilang-menuitem-standard/component.js @@ -12,10 +12,12 @@ class multilang_menuitem_standardCardComponent extends BaseCard['multilang-menui * @param profile profile of the entity in the card */ dataForRender(profile) { + const linkTarget = AnswersExperience.runtimeConfig.get('linkTarget') || '_top'; + return { title: profile.name, // The header text of the card url: profile.landingPageUrl, // If the card title is a clickable link, set URL here - target: '_top', // If the title's URL should open in a new tab, etc. + target: linkTarget, // If the title's URL should open in a new tab, etc. image: Formatter.image(profile.c_photo).url, // The URL of the image to display on the card altText: Formatter.image(profile.c_photo).alternateText, // The alternate text for the image // tagLabel: '', // The label of the displayed image @@ -38,7 +40,7 @@ class multilang_menuitem_standardCardComponent extends BaseCard['multilang-menui label: {{ translateJS phrase='Order Now' }}, // The CTA's label iconName: 'chevron', // The icon to use for the CTA url: profile.orderUrl && profile.orderUrl.url, // The URL a user will be directed to when clicking - target: '_top', // Where the new URL will be opened + target: linkTarget, // Where the new URL will be opened eventType: 'CTA_CLICK', // Type of Analytics event fired when clicking the CTA eventOptions: this.addDefaultEventOptions(), // ariaLabel: '', // Accessible text providing a descriptive label for the CTA @@ -48,7 +50,7 @@ class multilang_menuitem_standardCardComponent extends BaseCard['multilang-menui label: {{ translateJS phrase='View Menu' }}, iconName: 'magnifying_glass', url: profile.landingPageUrl, - target: '_top', + target: linkTarget, eventType: 'CTA_CLICK', eventOptions: this.addDefaultEventOptions(), // ariaLabel: '', diff --git a/cards/multilang-product-prominentimage-clickable/component.js b/cards/multilang-product-prominentimage-clickable/component.js index d07d9433b..c3b66bc29 100644 --- a/cards/multilang-product-prominentimage-clickable/component.js +++ b/cards/multilang-product-prominentimage-clickable/component.js @@ -27,16 +27,18 @@ class multilang_product_prominentimage_clickableCardComponent imageUrl = Formatter.image(profile.photoGallery[0]).url; alternateText = Formatter.image(profile.photoGallery[0]).alternateText; } + + const linkTarget = AnswersExperience.runtimeConfig.get('linkTarget') || '_top'; return { title: profile.name, // The header text of the card url: cardUrl, // If the card is a clickable link, set URL here - target: '_top', // If the card URL should open in a new tab, etc. + target: linkTarget, // If the card URL should open in a new tab, etc. titleEventOptions: this.addDefaultEventOptions(), subtitle: Formatter.price(profile.price), // The sub-header text of the card image: imageUrl, // The URL of the image to display on the card altText: alternateText, // The alternate text for the image - details: profile.richTextDescription ? ANSWERS.formatRichText(profile.richTextDescription, 'richTextDescription', '_top') : null, // The text in the body of the card, Warning: cannot contain links + details: profile.richTextDescription ? ANSWERS.formatRichText(profile.richTextDescription, 'richTextDescription', linkTarget) : null, // The text in the body of the card, Warning: cannot contain links // tag: profile.stockStatus ? profile.stockStatus : '', // The tag text for the card }; } diff --git a/cards/multilang-product-prominentimage/component.js b/cards/multilang-product-prominentimage/component.js index 724538744..f1d8e21e0 100644 --- a/cards/multilang-product-prominentimage/component.js +++ b/cards/multilang-product-prominentimage/component.js @@ -18,16 +18,17 @@ class multilang_product_prominentimageCardComponent extends BaseCard['multilang- imageUrl = Formatter.image(profile.photoGallery[0]).url; alternateText = Formatter.image(profile.photoGallery[0]).alternateText; } + const linkTarget = AnswersExperience.runtimeConfig.get('linkTarget') || '_top'; return { title: profile.name, // The header text of the card url: profile.landingPageUrl, // If the card title is a clickable link, set URL here - target: '_top', // If the title's URL should open in a new tab, etc. + target: linkTarget, // If the title's URL should open in a new tab, etc. titleEventOptions: this.addDefaultEventOptions(), subtitle: Formatter.price(profile.price), // The sub-header text of the card image: imageUrl, // The URL of the image to display on the card altText: alternateText, // The alternate text for the image - details: profile.richTextDescription ? ANSWERS.formatRichText(profile.richTextDescription, 'richTextDescription', '_top') : null, // The text in the body of the card + details: profile.richTextDescription ? ANSWERS.formatRichText(profile.richTextDescription, 'richTextDescription', linkTarget) : null, // The text in the body of the card // tag: profile.stockStatus ? profile.stockStatus : '', // The tag text for the card // If the card's details are longer than a certain character count, you can truncate the // text. A toggle will be supplied that can show or hide the truncated text. @@ -42,7 +43,7 @@ class multilang_product_prominentimageCardComponent extends BaseCard['multilang- label: profile.c_primaryCTA ? profile.c_primaryCTA.label : null, // The CTA's label iconName: 'chevron', // The icon to use for the CTA url: Formatter.generateCTAFieldTypeLink(profile.c_primaryCTA), // The URL a user will be directed to when clicking - target: '_top', // Where the new URL will be opened + target: linkTarget, // Where the new URL will be opened eventType: 'CTA_CLICK', // Type of Analytics event fired when clicking the CTA eventOptions: this.addDefaultEventOptions(), // ariaLabel: '', // Accessible text providing a descriptive label for the CTA @@ -52,7 +53,7 @@ class multilang_product_prominentimageCardComponent extends BaseCard['multilang- label: profile.c_secondaryCTA ? profile.c_secondaryCTA.label : null, iconName: 'chevron', url: Formatter.generateCTAFieldTypeLink(profile.c_secondaryCTA), - target: '_top', + target: linkTarget, eventType: 'CTA_CLICK', eventOptions: this.addDefaultEventOptions(), // ariaLabel: '', diff --git a/cards/multilang-product-prominentvideo/component.js b/cards/multilang-product-prominentvideo/component.js index feb2e9b5e..779da89eb 100644 --- a/cards/multilang-product-prominentvideo/component.js +++ b/cards/multilang-product-prominentvideo/component.js @@ -15,14 +15,16 @@ class multilang_product_prominentvideoCardComponent extends BaseCard['multilang- this.youtubeUrl = Formatter.getYoutubeUrl(profile.videos || []); this.vimeoUrl = profile.c_vimeo; + const linkTarget = AnswersExperience.runtimeConfig.get('linkTarget') || '_top'; + return { title: profile.name, // The header text of the card url: profile.landingPageUrl, // If the card title is a clickable link, set URL here - target: '_top', // If the title's URL should open in a new tab, etc. + target: linkTarget, // If the title's URL should open in a new tab, etc. titleEventOptions: this.addDefaultEventOptions(), subtitle: profile.featuredMessage?.description, // The sub-header text of the card videoUrl: this.youtubeUrl || this.vimeoUrl, - details: profile.richTextDescription ? ANSWERS.formatRichText(profile.richTextDescription, 'richTextDescription', '_top') : null, // The text in the body of the card + details: profile.richTextDescription ? ANSWERS.formatRichText(profile.richTextDescription, 'richTextDescription', linkTarget) : null, // The text in the body of the card // If the card's details are longer than a certain character count, you can truncate the // text. A toggle will be supplied that can show or hide the truncated text. // Note: If you are using rich text for the details, you should not enable this feature. @@ -36,7 +38,7 @@ class multilang_product_prominentvideoCardComponent extends BaseCard['multilang- label: profile.c_primaryCTA ? profile.c_primaryCTA.label : null, // The CTA's label iconName: 'chevron', // The icon to use for the CTA url: Formatter.generateCTAFieldTypeLink(profile.c_primaryCTA), // The URL a user will be directed to when clicking - target: '_top', // Where the new URL will be opened + target: linkTarget, // Where the new URL will be opened eventType: 'CTA_CLICK', // Type of Analytics event fired when clicking the CTA eventOptions: this.addDefaultEventOptions(), // ariaLabel: '', // Accessible text providing a descriptive label for the CTA @@ -46,7 +48,7 @@ class multilang_product_prominentvideoCardComponent extends BaseCard['multilang- label: profile.c_secondaryCTA ? profile.c_secondaryCTA.label : null, iconName: 'chevron', url: Formatter.generateCTAFieldTypeLink(profile.c_secondaryCTA), - target: '_top', + target: linkTarget, eventType: 'CTA_CLICK', eventOptions: this.addDefaultEventOptions(), // ariaLabel: '', diff --git a/cards/multilang-product-standard/component.js b/cards/multilang-product-standard/component.js index a182d77f8..947c66e7f 100644 --- a/cards/multilang-product-standard/component.js +++ b/cards/multilang-product-standard/component.js @@ -18,16 +18,17 @@ class multilang_product_standardCardComponent extends BaseCard['multilang-produc imageUrl = Formatter.image(profile.photoGallery[0]).url; alternateText = Formatter.image(profile.photoGallery[0]).alternateText; } + const linkTarget = AnswersExperience.runtimeConfig.get('linkTarget') || '_top'; return { title: profile.name, // The header text of the card url: profile.landingPageUrl, // If the card title is a clickable link, set URL here - target: '_top', // If the title's URL should open in a new tab, etc. + target: linkTarget, // If the title's URL should open in a new tab, etc. image: imageUrl, // The URL of the image to display on the card altText: alternateText, // The alternate text for the image titleEventOptions: this.addDefaultEventOptions(), subtitle: Formatter.price(profile.price), // The sub-header text of the card - details: profile.richTextDescription ? ANSWERS.formatRichText(profile.richTextDescription, 'richTextDescription', '_top') : null, // The text in the body of the card + details: profile.richTextDescription ? ANSWERS.formatRichText(profile.richTextDescription, 'richTextDescription', linkTarget) : null, // The text in the body of the card // If the card's details are longer than a certain character count, you can truncate the // text. A toggle will be supplied that can show or hide the truncated text. // Note: If you are using rich text for the details, you should not enable this feature. @@ -41,7 +42,7 @@ class multilang_product_standardCardComponent extends BaseCard['multilang-produc label: profile.c_primaryCTA ? profile.c_primaryCTA.label : null, // The CTA's label iconName: 'chevron', // The icon to use for the CTA url: Formatter.generateCTAFieldTypeLink(profile.c_primaryCTA), // The URL a user will be directed to when clicking - target: '_top', // Where the new URL will be opened + target: linkTarget, // Where the new URL will be opened eventType: 'CTA_CLICK', // Type of Analytics event fired when clicking the CTA eventOptions: this.addDefaultEventOptions(), // ariaLabel: '', // Accessible text providing a descriptive label for the CTA @@ -51,7 +52,7 @@ class multilang_product_standardCardComponent extends BaseCard['multilang-produc label: profile.c_secondaryCTA ? profile.c_secondaryCTA.label : null, iconName: 'chevron', // The icon to use for the CTA url: Formatter.generateCTAFieldTypeLink(profile.c_secondaryCTA), - target: '_top', // Where the new URL will be opened + target: linkTarget, // Where the new URL will be opened eventType: 'CTA_CLICK', // Type of Analytics event fired when clicking the CTA eventOptions: this.addDefaultEventOptions(), // ariaLabel: '', diff --git a/cards/multilang-professional-location/component.js b/cards/multilang-professional-location/component.js index d908db1cb..55006a511 100644 --- a/cards/multilang-professional-location/component.js +++ b/cards/multilang-professional-location/component.js @@ -18,12 +18,14 @@ class multilang_professional_locationCardComponent extends BaseCard['multilang-p * @param profile profile of the entity in the card */ dataForRender(profile) { + const linkTarget = AnswersExperience.runtimeConfig.get('linkTarget') || '_top'; + return { showOrdinal: true, // Show the map pin number on the card. Only supported for universal search title: `${profile.firstName} ${profile.lastName}`, // The header text of the card // subtitle: '', // The sub-header text of the card url: profile.website || profile.landingPageUrl, // If the card title is a clickable link, set URL here - target: '_top', // If the title's URL should open in a new tab, etc. + target: linkTarget, // If the title's URL should open in a new tab, etc. titleEventOptions: this.addDefaultEventOptions(), address: Formatter.address(profile), // The address for the card details: profile.description, // The text in the body of the card @@ -48,7 +50,7 @@ class multilang_professional_locationCardComponent extends BaseCard['multilang-p label: profile.c_primaryCTA ? profile.c_primaryCTA.label : null, // The CTA's label iconName: 'chevron', // The icon to use for the CTA url: Formatter.generateCTAFieldTypeLink(profile.c_primaryCTA), // The URL a user will be directed to when clicking - target: '_top', // Where the new URL will be opened + target: linkTarget, // Where the new URL will be opened eventType: 'CTA_CLICK', // Type of Analytics event fired when clicking the CTA eventOptions: this.addDefaultEventOptions(), // ariaLabel: '', // Accessible text providing a descriptive label for the CTA @@ -58,7 +60,7 @@ class multilang_professional_locationCardComponent extends BaseCard['multilang-p label: profile.c_secondaryCTA ? profile.c_secondaryCTA.label : null, iconName: 'chevron', url: Formatter.generateCTAFieldTypeLink(profile.c_secondaryCTA), - target: '_top', + target: linkTarget, eventType: 'CTA_CLICK', eventOptions: this.addDefaultEventOptions(), // ariaLabel: '' diff --git a/cards/multilang-professional-location/template.hbs b/cards/multilang-professional-location/template.hbs index c8b65e6a2..27bffed6d 100644 --- a/cards/multilang-professional-location/template.hbs +++ b/cards/multilang-professional-location/template.hbs @@ -142,7 +142,7 @@ href="tel:{{card.phone}}" data-eventtype="TAP_TO_CALL" data-eventoptions='{{json card.phoneEventOptions}}' - target="_top"> + target={{#if card.target}}"{{card.target}}"{{else}}"_top"{{/if}}> {{card.phone}} diff --git a/cards/multilang-professional-standard/component.js b/cards/multilang-professional-standard/component.js index 85e219f7e..0d969a180 100644 --- a/cards/multilang-professional-standard/component.js +++ b/cards/multilang-professional-standard/component.js @@ -12,11 +12,13 @@ class multilang_professional_standardCardComponent extends BaseCard['multilang-p * @param profile profile of the entity in the card */ dataForRender(profile) { + const linkTarget = AnswersExperience.runtimeConfig.get('linkTarget') || '_top'; + return { title: `${profile.firstName} ${profile.lastName}`, // The header text of the card // subtitle: '', // The sub-header text of the card url: profile.website || profile.landingPageUrl, // If the card title is a clickable link, set URL here - target: '_top', // If the title's URL should open in a new tab, etc. + target: linkTarget, // If the title's URL should open in a new tab, etc. titleEventOptions: this.addDefaultEventOptions(), details: profile.description, // The text in the body of the card // listTitle: '', // Heading of the bulleted list @@ -38,7 +40,7 @@ class multilang_professional_standardCardComponent extends BaseCard['multilang-p label: profile.c_primaryCTA ? profile.c_primaryCTA.label : null, // The CTA's label iconName: 'chevron', // The icon to use for the CTA url: Formatter.generateCTAFieldTypeLink(profile.c_primaryCTA), // The URL a user will be directed to when clicking - target: '_top', // Where the new URL will be opened + target: linkTarget, // Where the new URL will be opened eventType: 'CTA_CLICK', // Type of Analytics event fired when clicking the CTA eventOptions: this.addDefaultEventOptions(), // ariaLabel: '', // Accessible text providing a descriptive label for the CTA @@ -48,7 +50,7 @@ class multilang_professional_standardCardComponent extends BaseCard['multilang-p label: profile.c_secondaryCTA ? profile.c_secondaryCTA.label : null, iconName: 'chevron', url: Formatter.generateCTAFieldTypeLink(profile.c_secondaryCTA), - target: '_top', + target: linkTarget, eventType: 'CTA_CLICK', eventOptions: this.addDefaultEventOptions(), // ariaLabel: '' diff --git a/cards/multilang-professional-standard/template.hbs b/cards/multilang-professional-standard/template.hbs index 40adff2fd..08d6234a1 100644 --- a/cards/multilang-professional-standard/template.hbs +++ b/cards/multilang-professional-standard/template.hbs @@ -106,7 +106,7 @@ + target={{#if card.target}}"{{card.target}}"{{else}}"_top"{{/if}}> {{card.phone}} diff --git a/cards/multilang-standard/component.js b/cards/multilang-standard/component.js index 92787e5fb..1d12e678d 100644 --- a/cards/multilang-standard/component.js +++ b/cards/multilang-standard/component.js @@ -12,10 +12,12 @@ class multilang_standardCardComponent extends BaseCard['multilang-standard'] { * @param profile profile of the entity in the card */ dataForRender(profile) { + const linkTarget = AnswersExperience.runtimeConfig.get('linkTarget') || '_top'; + return { title: profile.name, // The header text of the card url: profile.website || profile.landingPageUrl, // If the card title is a clickable link, set URL here - target: '_top', // If the title's URL should open in a new tab, etc. + target: linkTarget, // If the title's URL should open in a new tab, etc. // image: '', // The URL of the image to display on the card // altText: '', // The alternate text for the image titleEventOptions: this.addDefaultEventOptions(), @@ -33,7 +35,7 @@ class multilang_standardCardComponent extends BaseCard['multilang-standard'] { label: profile.c_primaryCTA ? profile.c_primaryCTA.label : null, // The CTA's label iconName: 'chevron', // The icon to use for the CTA url: Formatter.generateCTAFieldTypeLink(profile.c_primaryCTA), // The URL a user will be directed to when clicking - target: '_top', // Where the new URL will be opened + target: linkTarget, // Where the new URL will be opened eventType: 'CTA_CLICK', // Type of Analytics event fired when clicking the CTA eventOptions: this.addDefaultEventOptions(), // ariaLabel: '', // Accessible text providing a descriptive label for the CTA @@ -43,7 +45,7 @@ class multilang_standardCardComponent extends BaseCard['multilang-standard'] { label: profile.c_secondaryCTA ? profile.c_secondaryCTA.label : null, iconName: 'chevron', url: Formatter.generateCTAFieldTypeLink(profile.c_secondaryCTA), - target: '_top', + target: linkTarget, eventType: 'CTA_CLICK', eventOptions: this.addDefaultEventOptions(), // ariaLabel: '', diff --git a/cards/product-prominentimage-clickable/component.js b/cards/product-prominentimage-clickable/component.js index 5d110044a..f70bd39d0 100644 --- a/cards/product-prominentimage-clickable/component.js +++ b/cards/product-prominentimage-clickable/component.js @@ -27,15 +27,17 @@ class product_prominentimage_clickableCardComponent extends BaseCard['product-pr alternateText = Formatter.image(profile.photoGallery[0]).alternateText; } + const linkTarget = AnswersExperience.runtimeConfig.get('linkTarget') || '_top'; + return { title: profile.name, // The header text of the card url: cardUrl, // If the card is a clickable link, set URL here - target: '_top', // If the card URL should open in a new tab, etc. + target: linkTarget, // If the card URL should open in a new tab, etc. titleEventOptions: this.addDefaultEventOptions(), subtitle: Formatter.price(profile.price), // The sub-header text of the card image: imageUrl, // The URL of the image to display on the card altText: alternateText, // The alternate text for the image - details: profile.richTextDescription ? ANSWERS.formatRichText(profile.richTextDescription, 'richTextDescription', '_top') : null, // The text in the body of the card, Warning: cannot contain links + details: profile.richTextDescription ? ANSWERS.formatRichText(profile.richTextDescription, 'richTextDescription', linkTarget) : null, // The text in the body of the card, Warning: cannot contain links // tag: profile.stockStatus ? profile.stockStatus : '', // The tag text for the card }; } diff --git a/cards/product-prominentimage/component.js b/cards/product-prominentimage/component.js index a1d796ba9..163eea636 100644 --- a/cards/product-prominentimage/component.js +++ b/cards/product-prominentimage/component.js @@ -18,16 +18,17 @@ class product_prominentimageCardComponent extends BaseCard['product-prominentima imageUrl = Formatter.image(profile.photoGallery[0]).url; alternateText = Formatter.image(profile.photoGallery[0]).alternateText; } + const linkTarget = AnswersExperience.runtimeConfig.get('linkTarget') || '_top'; return { title: profile.name, // The header text of the card url: profile.landingPageUrl, // If the card title is a clickable link, set URL here - target: '_top', // If the title's URL should open in a new tab, etc. + target: linkTarget, // If the title's URL should open in a new tab, etc. titleEventOptions: this.addDefaultEventOptions(), subtitle: Formatter.price(profile.price), // The sub-header text of the card image: imageUrl, // The URL of the image to display on the card altText: alternateText, // The alternate text for the image - details: profile.richTextDescription ? ANSWERS.formatRichText(profile.richTextDescription, 'richTextDescription', '_top') : null, // The text in the body of the card + details: profile.richTextDescription ? ANSWERS.formatRichText(profile.richTextDescription, 'richTextDescription', linkTarget) : null, // The text in the body of the card // tag: profile.stockStatus ? profile.stockStatus : '', // The tag text for the card // If the card's details are longer than a certain character count, you can truncate the // text. A toggle will be supplied that can show or hide the truncated text. @@ -42,7 +43,7 @@ class product_prominentimageCardComponent extends BaseCard['product-prominentima label: profile.c_primaryCTA ? profile.c_primaryCTA.label : null, // The CTA's label iconName: 'chevron', // The icon to use for the CTA url: Formatter.generateCTAFieldTypeLink(profile.c_primaryCTA), // The URL a user will be directed to when clicking - target: '_top', // Where the new URL will be opened + target: linkTarget, // Where the new URL will be opened eventType: 'CTA_CLICK', // Type of Analytics event fired when clicking the CTA eventOptions: this.addDefaultEventOptions(), // ariaLabel: '', // Accessible text providing a descriptive label for the CTA @@ -52,7 +53,7 @@ class product_prominentimageCardComponent extends BaseCard['product-prominentima label: profile.c_secondaryCTA ? profile.c_secondaryCTA.label : null, iconName: 'chevron', url: Formatter.generateCTAFieldTypeLink(profile.c_secondaryCTA), - target: '_top', + target: linkTarget, eventType: 'CTA_CLICK', eventOptions: this.addDefaultEventOptions(), // ariaLabel: '', diff --git a/cards/product-standard/component.js b/cards/product-standard/component.js index a2ffaa121..08d911d0e 100644 --- a/cards/product-standard/component.js +++ b/cards/product-standard/component.js @@ -18,16 +18,17 @@ class product_standardCardComponent extends BaseCard['product-standard'] { imageUrl = Formatter.image(profile.photoGallery[0]).url; alternateText = Formatter.image(profile.photoGallery[0]).alternateText; } + const linkTarget = AnswersExperience.runtimeConfig.get('linkTarget') || '_top'; return { title: profile.name, // The header text of the card url: profile.landingPageUrl, // If the card title is a clickable link, set URL here - target: '_top', // If the title's URL should open in a new tab, etc. + target: linkTarget, // If the title's URL should open in a new tab, etc. image: imageUrl, // The URL of the image to display on the card altText: alternateText, // The alternate text for the image titleEventOptions: this.addDefaultEventOptions(), subtitle: Formatter.price(profile.price), // The sub-header text of the card - details: profile.richTextDescription ? ANSWERS.formatRichText(profile.richTextDescription, 'richTextDescription', '_top') : null, // The text in the body of the card + details: profile.richTextDescription ? ANSWERS.formatRichText(profile.richTextDescription, 'richTextDescription', linkTarget) : null, // The text in the body of the card // If the card's details are longer than a certain character count, you can truncate the // text. A toggle will be supplied that can show or hide the truncated text. // Note: If you are using rich text for the details, you should not enable this feature. @@ -41,7 +42,7 @@ class product_standardCardComponent extends BaseCard['product-standard'] { label: profile.c_primaryCTA ? profile.c_primaryCTA.label : null, // The CTA's label iconName: 'chevron', // The icon to use for the CTA url: Formatter.generateCTAFieldTypeLink(profile.c_primaryCTA), // The URL a user will be directed to when clicking - target: '_top', // Where the new URL will be opened + target: linkTarget, // Where the new URL will be opened eventType: 'CTA_CLICK', // Type of Analytics event fired when clicking the CTA eventOptions: this.addDefaultEventOptions(), // ariaLabel: '', // Accessible text providing a descriptive label for the CTA @@ -51,7 +52,7 @@ class product_standardCardComponent extends BaseCard['product-standard'] { label: profile.c_secondaryCTA ? profile.c_secondaryCTA.label : null, iconName: 'chevron', // The icon to use for the CTA url: Formatter.generateCTAFieldTypeLink(profile.c_secondaryCTA), - target: '_top', // Where the new URL will be opened + target: linkTarget, // Where the new URL will be opened eventType: 'CTA_CLICK', // Type of Analytics event fired when clicking the CTA eventOptions: this.addDefaultEventOptions(), // ariaLabel: '', diff --git a/cards/professional-location/component.js b/cards/professional-location/component.js index e3eeac732..38f0e0531 100644 --- a/cards/professional-location/component.js +++ b/cards/professional-location/component.js @@ -18,12 +18,14 @@ class professional_locationCardComponent extends BaseCard['professional-location * @param profile profile of the entity in the card */ dataForRender(profile) { + const linkTarget = AnswersExperience.runtimeConfig.get('linkTarget') || '_top'; + return { showOrdinal: true, // Show the map pin number on the card. Only supported for universal search title: `${profile.firstName} ${profile.lastName}`, // The header text of the card // subtitle: '', // The sub-header text of the card url: profile.website || profile.landingPageUrl, // If the card title is a clickable link, set URL here - target: '_top', // If the title's URL should open in a new tab, etc. + target: linkTarget, // If the title's URL should open in a new tab, etc. titleEventOptions: this.addDefaultEventOptions(), address: Formatter.address(profile), // The address for the card details: profile.description, // The text in the body of the card @@ -48,7 +50,7 @@ class professional_locationCardComponent extends BaseCard['professional-location label: profile.c_primaryCTA ? profile.c_primaryCTA.label : null, // The CTA's label iconName: 'chevron', // The icon to use for the CTA url: Formatter.generateCTAFieldTypeLink(profile.c_primaryCTA), // The URL a user will be directed to when clicking - target: '_top', // Where the new URL will be opened + target: linkTarget, // Where the new URL will be opened eventType: 'CTA_CLICK', // Type of Analytics event fired when clicking the CTA eventOptions: this.addDefaultEventOptions(), // ariaLabel: '', // Accessible text providing a descriptive label for the CTA @@ -58,7 +60,7 @@ class professional_locationCardComponent extends BaseCard['professional-location label: profile.c_secondaryCTA ? profile.c_secondaryCTA.label : null, iconName: 'chevron', url: Formatter.generateCTAFieldTypeLink(profile.c_secondaryCTA), - target: '_top', + target: linkTarget, eventType: 'CTA_CLICK', eventOptions: this.addDefaultEventOptions(), // ariaLabel: '' diff --git a/cards/professional-location/template.hbs b/cards/professional-location/template.hbs index 462172609..4adc7ff19 100644 --- a/cards/professional-location/template.hbs +++ b/cards/professional-location/template.hbs @@ -142,7 +142,7 @@ href="tel:{{card.phone}}" data-eventtype="TAP_TO_CALL" data-eventoptions='{{json card.phoneEventOptions}}' - target="_top"> + target={{#if card.target}}"{{card.target}}"{{else}}"_top"{{/if}}> {{card.phone}} diff --git a/cards/professional-standard/component.js b/cards/professional-standard/component.js index 70ad16583..2dc4949a1 100644 --- a/cards/professional-standard/component.js +++ b/cards/professional-standard/component.js @@ -12,11 +12,13 @@ class professional_standardCardComponent extends BaseCard['professional-standard * @param profile profile of the entity in the card */ dataForRender(profile) { + const linkTarget = AnswersExperience.runtimeConfig.get('linkTarget') || '_top'; + return { title: `${profile.firstName} ${profile.lastName}`, // The header text of the card // subtitle: '', // The sub-header text of the card url: profile.website || profile.landingPageUrl, // If the card title is a clickable link, set URL here - target: '_top', // If the title's URL should open in a new tab, etc. + target: linkTarget, // If the title's URL should open in a new tab, etc. titleEventOptions: this.addDefaultEventOptions(), details: profile.description, // The text in the body of the card // listTitle: '', // Heading of the bulleted list @@ -38,7 +40,7 @@ class professional_standardCardComponent extends BaseCard['professional-standard label: profile.c_primaryCTA ? profile.c_primaryCTA.label : null, // The CTA's label iconName: 'chevron', // The icon to use for the CTA url: Formatter.generateCTAFieldTypeLink(profile.c_primaryCTA), // The URL a user will be directed to when clicking - target: '_top', // Where the new URL will be opened + target: linkTarget, // Where the new URL will be opened eventType: 'CTA_CLICK', // Type of Analytics event fired when clicking the CTA eventOptions: this.addDefaultEventOptions(), // ariaLabel: '', // Accessible text providing a descriptive label for the CTA @@ -48,7 +50,7 @@ class professional_standardCardComponent extends BaseCard['professional-standard label: profile.c_secondaryCTA ? profile.c_secondaryCTA.label : null, iconName: 'chevron', url: Formatter.generateCTAFieldTypeLink(profile.c_secondaryCTA), - target: '_top', + target: linkTarget, eventType: 'CTA_CLICK', eventOptions: this.addDefaultEventOptions(), // ariaLabel: '' diff --git a/cards/professional-standard/template.hbs b/cards/professional-standard/template.hbs index 40adff2fd..08d6234a1 100644 --- a/cards/professional-standard/template.hbs +++ b/cards/professional-standard/template.hbs @@ -106,7 +106,7 @@ + target={{#if card.target}}"{{card.target}}"{{else}}"_top"{{/if}}> {{card.phone}} diff --git a/cards/standard/component.js b/cards/standard/component.js index 31ab7ff90..17ab9c0d5 100644 --- a/cards/standard/component.js +++ b/cards/standard/component.js @@ -12,10 +12,12 @@ class standardCardComponent extends BaseCard['standard'] { * @param profile profile of the entity in the card */ dataForRender(profile) { + const linkTarget = AnswersExperience.runtimeConfig.get('linkTarget') || '_top'; + return { title: profile.name, // The header text of the card url: profile.website || profile.landingPageUrl, // If the card title is a clickable link, set URL here - target: '_top', // If the title's URL should open in a new tab, etc. + target: linkTarget, // If the title's URL should open in a new tab, etc. // image: '', // The URL of the image to display on the card // altText: '', // The alternate text for the image titleEventOptions: this.addDefaultEventOptions(), @@ -33,7 +35,7 @@ class standardCardComponent extends BaseCard['standard'] { label: profile.c_primaryCTA ? profile.c_primaryCTA.label : null, // The CTA's label iconName: 'chevron', // The icon to use for the CTA url: Formatter.generateCTAFieldTypeLink(profile.c_primaryCTA), // The URL a user will be directed to when clicking - target: '_top', // Where the new URL will be opened + target: linkTarget, // Where the new URL will be opened eventType: 'CTA_CLICK', // Type of Analytics event fired when clicking the CTA eventOptions: this.addDefaultEventOptions(), // ariaLabel: '', // Accessible text providing a descriptive label for the CTA @@ -43,7 +45,7 @@ class standardCardComponent extends BaseCard['standard'] { label: profile.c_secondaryCTA ? profile.c_secondaryCTA.label : null, iconName: 'chevron', url: Formatter.generateCTAFieldTypeLink(profile.c_secondaryCTA), - target: '_top', + target: linkTarget, eventType: 'CTA_CLICK', eventOptions: this.addDefaultEventOptions(), // ariaLabel: '', diff --git a/directanswercards/allfields-standard/component.js b/directanswercards/allfields-standard/component.js index 2ee3dc0fe..531ca79df 100644 --- a/directanswercards/allfields-standard/component.js +++ b/directanswercards/allfields-standard/component.js @@ -13,6 +13,7 @@ class allfields_standardComponent extends BaseDirectAnswerCard['allfields-standa dataForRender(type, answer, relatedItem) { let isArray = Array.isArray(answer.value); let value, arrayValue, regularValue, isRichText; + const linkTarget = AnswersExperience.runtimeConfig.get('linkTarget') || '_top'; switch (answer.fieldType) { case 'url': @@ -132,9 +133,9 @@ class allfields_standardComponent extends BaseDirectAnswerCard['allfields-standa case 'rich_text': isRichText = true; if (isArray) { - arrayValue = answer.value.map((value) => ANSWERS.formatRichText(value)); + arrayValue = answer.value.map((value) => ANSWERS.formatRichText(value, null, linkTarget)); } else { - regularValue = ANSWERS.formatRichText(answer.value); + regularValue = ANSWERS.formatRichText(answer.value, null, linkTarget); } value = isArray ? arrayValue : regularValue; break; @@ -164,7 +165,6 @@ class allfields_standardComponent extends BaseDirectAnswerCard['allfields-standa // break; // } - return { // iconName: '', // Icon that appears on the top left of the direct answer card // iconUrl: '', // URL for Icon that appears on the top left of the direct answer card @@ -178,12 +178,12 @@ class allfields_standardComponent extends BaseDirectAnswerCard['allfields-standa viewDetailsEventOptions: this.addDefaultEventOptions({ ctaLabel: 'VIEW_DETAILS' }), // The event options for viewDetails click analytics - linkTarget: '_top', // Target for all links in the direct answer + linkTarget: linkTarget, // Target for all links in the direct answer // CTA: { // label: '', // The CTA's label // iconName: 'chevron', // The icon to use for the CTA // url: '', // The URL a user will be directed to when clicking - // target: '_top', // Where the new URL will be opened + // target: linkTarget, // Where the new URL will be opened // eventType: 'CTA_CLICK', // Type of Analytics event fired when clicking the CTA // eventOptions: this.addDefaultEventOptions() // The event options for CTA click analytics // }, diff --git a/directanswercards/documentsearch-standard/component.js b/directanswercards/documentsearch-standard/component.js index 51171cdc0..2dee30bcb 100644 --- a/directanswercards/documentsearch-standard/component.js +++ b/directanswercards/documentsearch-standard/component.js @@ -13,9 +13,10 @@ class documentsearch_standardComponent extends BaseDirectAnswerCard['documentsea */ dataForRender(type, answer, relatedItem, snippet) { const relatedItemData = relatedItem.data || {}; + const linkTarget = AnswersExperience.runtimeConfig.get('linkTarget') || '_top'; let snippetValue = ''; if (answer.fieldType === "rich_text" && snippet) { - snippetValue = ANSWERS.formatRichText(snippet.value, 'snippet'); + snippetValue = ANSWERS.formatRichText(snippet.value, 'snippet', linkTarget); } else if (snippet) { snippetValue = Formatter.highlightField(snippet.value, snippet.matchedSubstrings); } @@ -29,12 +30,12 @@ class documentsearch_standardComponent extends BaseDirectAnswerCard['documentsea ctaLabel: 'VIEW_DETAILS', fieldName: 'snippet' }), // The event options for viewDetails click analytics - linkTarget: '_top', // Target for all links in the direct answer + linkTarget: linkTarget, // Target for all links in the direct answer // CTA: { // label: '', // The CTA's label // iconName: 'chevron', // The icon to use for the CTA // url: '', // The URL a user will be directed to when clicking - // target: '_top', // Where the new URL will be opened + // target: linkTarget, // Where the new URL will be opened // eventType: 'CTA_CLICK', // Type of Analytics event fired when clicking the CTA // eventOptions: this.addDefaultEventOptions({ fieldName: 'snippet' }) // The event options for CTA click analytics // }, diff --git a/directanswercards/multilang-allfields-standard/component.js b/directanswercards/multilang-allfields-standard/component.js index 62a51b60e..3b50f0ba6 100644 --- a/directanswercards/multilang-allfields-standard/component.js +++ b/directanswercards/multilang-allfields-standard/component.js @@ -13,6 +13,7 @@ class multilang_allfields_standardComponent extends BaseDirectAnswerCard['multil dataForRender(type, answer, relatedItem) { let isArray = Array.isArray(answer.value); let value, arrayValue, regularValue; + const linkTarget = AnswersExperience.runtimeConfig.get('linkTarget') || '_top'; switch (answer.fieldType) { case 'url': @@ -131,9 +132,9 @@ class multilang_allfields_standardComponent extends BaseDirectAnswerCard['multil break; case 'rich_text': if (isArray) { - arrayValue = answer.value.map((value) => ANSWERS.formatRichText(value)); + arrayValue = answer.value.map((value) => ANSWERS.formatRichText(value, null, linkTarget)); } else { - regularValue = ANSWERS.formatRichText(answer.value); + regularValue = ANSWERS.formatRichText(answer.value, null, linkTarget); } value = isArray ? arrayValue : regularValue; case 'single_line_text': @@ -162,7 +163,6 @@ class multilang_allfields_standardComponent extends BaseDirectAnswerCard['multil // break; // } - return { // iconName: '', // Icon that appears on the top left of the direct answer card // iconUrl: '', // URL for Icon that appears on the top left of the direct answer card @@ -176,12 +176,12 @@ class multilang_allfields_standardComponent extends BaseDirectAnswerCard['multil viewDetailsEventOptions: this.addDefaultEventOptions({ ctaLabel: 'VIEW_DETAILS' }), // The event options for viewDetails click analytics - linkTarget: '_top', // Target for all links in the direct answer + linkTarget: linkTarget, // Target for all links in the direct answer // CTA: { // label: '', // The CTA's label // iconName: 'chevron', // The icon to use for the CTA // url: '', // The URL a user will be directed to when clicking - // target: '_top', // Where the new URL will be opened + // target: linkTarget, // Where the new URL will be opened // eventType: 'CTA_CLICK', // Type of Analytics event fired when clicking the CTA // eventOptions: this.addDefaultEventOptions() // The event options for CTA click analytics // }, diff --git a/global_config.json b/global_config.json index 703d03589..d3dff862f 100644 --- a/global_config.json +++ b/global_config.json @@ -3,6 +3,8 @@ // "apiKey": "", // The answers api key found on the experiences page. This will be provided automatically by the Yext CI system // "experienceVersion": "", // the Answers Experience version to use for API requests. This will be provided automatically by the Yext CI system // "businessId": "", // The business ID of the account. This will be provided automatically by the Yext CI system + // "initializeManually": true, // If true, the experience must be started by calling AnswersExperience.init() or AnswersExperienceFrame.init() for iframe integrations. + // "useJWT": true, // Whether or not to enable JWT. If true, the apiKey will be hidden from the build output and the token must be specified through manual initialization. "logo": "", // The link to the logo for open graph meta tag - og:image. "favicon": "", "googleTagManagerName": "dataLayer", // The name of your Google Tag Manager data layer diff --git a/hooks/templatedataformatter.js b/hooks/templatedataformatter.js index 5b3c1a338..3324b6a8a 100644 --- a/hooks/templatedataformatter.js +++ b/hooks/templatedataformatter.js @@ -1,3 +1,5 @@ +const getCleanedJamboInjectedData = require('../static/webpack/getCleanedJamboInjectedData'); + /** * Formats the data sent to the handlebars templates during Jambo builds. * @@ -26,6 +28,9 @@ module.exports = function (pageMetadata, siteLevelAttributes, pageNameToConfig) JAMBO_INJECTED_DATA: env.JAMBO_INJECTED_DATA } }; + if (globalConfig.useJWT) { + return getCleanedTemplateData(templateData); + } return templateData; } @@ -50,4 +55,25 @@ function getLocalizedGlobalConfig(globalConfig, currentLocaleConfig, locale) { localizedGlobalConfig.locale = locale; } return localizedGlobalConfig; +} + +/** + * Returns the provided template data without the API Key + * + * @param {Object} templateData + * @returns {Object} + */ +function getCleanedTemplateData(templateData) { + const jamboInjectedData = templateData.env.JAMBO_INJECTED_DATA; + const globalConfig = templateData.global_config; + return { + ...templateData, + global_config: { + ...globalConfig, + apiKey: undefined + }, + env: { + JAMBO_INJECTED_DATA: getCleanedJamboInjectedData(jamboInjectedData) + } + } } \ No newline at end of file diff --git a/layouts/html.hbs b/layouts/html.hbs index 9de2a85b0..7a17004ca 100644 --- a/layouts/html.hbs +++ b/layouts/html.hbs @@ -79,10 +79,14 @@ {{/if}} {{> script/partials/bundle-script-tags }} @@ -113,7 +117,7 @@ {{/if}} diff --git a/script/core.hbs b/script/core.hbs index 80b6ed22b..17db77a2b 100644 --- a/script/core.hbs +++ b/script/core.hbs @@ -12,7 +12,9 @@ const IS_STAGING = HitchhikerJS.isStaging(JAMBO_INJECTED_DATA?.pages?.stagingDomains || []); const injectedConfig = { experienceVersion: IS_STAGING ? 'STAGING' : 'PRODUCTION', - apiKey: HitchhikerJS.getInjectedProp('{{{global_config.experienceKey}}}', ['apiKey']), + {{#unless global_config.useJWT}} + apiKey: HitchhikerJS.getInjectedProp('{{{global_config.experienceKey}}}', ['apiKey']), + {{/unless}} {{#with env.JAMBO_INJECTED_DATA}} {{#if businessId}}businessId: "{{businessId}}",{{/if}} {{/with}} @@ -28,10 +30,12 @@ {{/if}} {{/with}} }; + const token = window.AnswersExperience.runtimeConfig?.get('token'); ANSWERS.init({ templateBundle: TemplateBundle.default, ...injectedConfig, ...userConfig, + ...token && { apiKey: token }, querySource: window.isOverlay ? 'OVERLAY' : 'STANDARD', onStateChange: (objParams, stringParams, replaceHistory) => { if ('parentIFrame' in window) { diff --git a/static/entry.js b/static/entry.js index 92f7f43e7..35d8ad20d 100644 --- a/static/entry.js +++ b/static/entry.js @@ -2,4 +2,4 @@ import * as HitchhikerJS from './js/HitchhikerJS'; window.HitchhikerJS = HitchhikerJS; // Import all SCSS -import Scss from './scss/answers/_default.scss'; \ No newline at end of file +import Scss from './scss/answers/_default.scss'; diff --git a/static/js/HitchhikerJS.js b/static/js/HitchhikerJS.js index a5cf90b5a..79e4e2d4f 100644 --- a/static/js/HitchhikerJS.js +++ b/static/js/HitchhikerJS.js @@ -28,4 +28,15 @@ export { StorageKeys }; import transformFacets from './transform-facets'; export { transformFacets } +import ManualInitializer from './manual-initializer'; +export { ManualInitializer }; + +import RuntimeConfigReceiver from './runtime-config-receiver'; +export { RuntimeConfigReceiver }; + +import RuntimeConfig from './runtime-config'; +window.AnswersExperience = { + runtimeConfig: new RuntimeConfig() +}; + export * from './video-apis'; diff --git a/static/js/answers-experience-frame.js b/static/js/answers-experience-frame.js new file mode 100644 index 000000000..865ba62c0 --- /dev/null +++ b/static/js/answers-experience-frame.js @@ -0,0 +1,41 @@ +import { sendToIframe } from './iframe-common'; + +export default class AnswersExperienceFrame { + constructor (runtimeConfig) { + this.runtimeConfig = runtimeConfig; + this._hasManuallyInitialized = false; + + runtimeConfig._onUpdate(updatedConfig => { + sendToIframe({ runtimeConfig: updatedConfig }); + }); + } + + /** + * Initializes the answers experience with the provided config set in the + * runtime config. + * + * @param {Object} config + */ + init (config) { + if (this.hasManuallyInitialized()) { + return; + } + Object.entries(config).forEach(([key, value]) => { + this.runtimeConfig.set(key, value); + }); + sendToIframe({ + initAnswersExperience: true, + runtimeConfig: this.runtimeConfig.getAll() + }); + this._hasManuallyInitialized = true; + } + + /** + * Returns whether or not the init function has been called + * + * @returns {boolean} + */ + hasManuallyInitialized () { + return this._hasManuallyInitialized; + } +} \ No newline at end of file diff --git a/static/js/iframe-common.js b/static/js/iframe-common.js index dbaf4d408..add2b567a 100644 --- a/static/js/iframe-common.js +++ b/static/js/iframe-common.js @@ -1,6 +1,19 @@ require('iframe-resizer'); -export function generateIFrame(domain, queryParam, urlParam) { +let iframeInitialized = false; +const iframeMessageQueue = []; + +/** + * @typedef {import('./runtime-config')} RuntimeConfig + */ + +/** + * Puts an iframe on the page of an Answers experience and sets up resizing and cross-domain communication + * + * @param {string} domain The location of the answers experience + * @param {AnswersExperienceFrame} answersExperienceFrame + */ +export function generateIFrame(domain, answersExperienceFrame) { var isLocalHost = window.location.host.split(':')[0] === 'localhost'; var containerEl = document.querySelector('#answers-container'); var iframe = document.createElement('iframe'); @@ -8,8 +21,6 @@ export function generateIFrame(domain, queryParam, urlParam) { iframe.allow = 'geolocation'; domain = domain || ''; - queryParam = queryParam || 'query'; - urlParam = urlParam || 'verticalUrl'; var calcFrameSrc = function() { var paramString = window.location.search; @@ -79,6 +90,16 @@ export function generateIFrame(domain, queryParam, urlParam) { // For dynamic iFrame resizing iFrameResize({ checkOrigin: false, + onInit: function() { + iframeInitialized = true; + iframeMessageQueue.push({ + initAnswersExperience: answersExperienceFrame.hasManuallyInitialized(), + runtimeConfig: answersExperienceFrame.runtimeConfig.getAll() + }); + while (iframeMessageQueue.length !== 0) { + sendToIframe(iframeMessageQueue.shift()); + } + }, onMessage: function(messageData) { const message = JSON.parse(messageData.message); if (message.action === "paginate") { @@ -99,3 +120,18 @@ export function generateIFrame(domain, queryParam, urlParam) { } }, '#answers-frame'); } + +/** + * Sends data to the answers iframe if possible. Otherwise the message is queued + * so that it can be sent when the iframe initializes. + * @param {Object} obj + */ +export function sendToIframe (obj) { + const iframe = document.querySelector('#answers-frame'); + if (!iframe || !iframe.iFrameResizer || !iframeInitialized) { + iframeMessageQueue.push(obj); + } + else { + iframe.iFrameResizer.sendMessage(obj); + } +} \ No newline at end of file diff --git a/static/js/iframe-prod.js b/static/js/iframe-prod.js index bba16890b..e5279065f 100644 --- a/static/js/iframe-prod.js +++ b/static/js/iframe-prod.js @@ -1,5 +1,11 @@ import { generateIFrame } from './iframe-common'; import InjectedData from './models/InjectedData'; +import RuntimeConfig from './runtime-config'; +import AnswersExperienceFrame from './answers-experience-frame'; -const prodDomain = new InjectedData().getProdDomain() -generateIFrame(prodDomain); +const runtimeConfig = new RuntimeConfig(); +const answersExperienceFrame = new AnswersExperienceFrame(runtimeConfig); +window.AnswersExperienceFrame = answersExperienceFrame; + +const prodDomain = new InjectedData().getProdDomain(); +generateIFrame(prodDomain, answersExperienceFrame); \ No newline at end of file diff --git a/static/js/iframe-staging.js b/static/js/iframe-staging.js index 396c48429..38c484f85 100644 --- a/static/js/iframe-staging.js +++ b/static/js/iframe-staging.js @@ -1,5 +1,11 @@ import { generateIFrame } from './iframe-common'; import InjectedData from './models/InjectedData'; +import RuntimeConfig from './runtime-config'; +import AnswersExperienceFrame from './answers-experience-frame'; + +const runtimeConfig = new RuntimeConfig(); +const answersExperienceFrame = new AnswersExperienceFrame(runtimeConfig); +window.AnswersExperienceFrame = answersExperienceFrame; const stagingDomain = new InjectedData().getStagingDomain(); -generateIFrame(stagingDomain); +generateIFrame(stagingDomain, answersExperienceFrame); \ No newline at end of file diff --git a/static/js/iframe.js b/static/js/iframe.js index 1d7f58201..6860f7735 100644 --- a/static/js/iframe.js +++ b/static/js/iframe.js @@ -1,5 +1,11 @@ import { generateIFrame } from './iframe-common'; import InjectedData from './models/InjectedData'; +import RuntimeConfig from './runtime-config'; +import AnswersExperienceFrame from './answers-experience-frame'; + +const runtimeConfig = new RuntimeConfig(); +const answersExperienceFrame = new AnswersExperienceFrame(runtimeConfig); +window.AnswersExperienceFrame = answersExperienceFrame; const domain = new InjectedData().getDomain(); -generateIFrame(domain); +generateIFrame(domain, answersExperienceFrame); \ No newline at end of file diff --git a/static/js/manual-initializer.js b/static/js/manual-initializer.js new file mode 100644 index 000000000..d9bb79f8b --- /dev/null +++ b/static/js/manual-initializer.js @@ -0,0 +1,49 @@ +/** + * Responsible for setting up manual initialization of the experience + */ +export default class ManualInitializer { + /** + * @param {Function} initAnswers the Answers initialization function which the manual init function calls to start answers + */ + constructor (initAnswers) { + this._initAnswers = initAnswers; + this._hasAnswersInitialized = false; + } + + /** + * Puts a manual initialization function on the window which initializes answers with the + * provided runtimeConfig + */ + setup () { + const runtimeConfigNotProvidedTimeout = setTimeout(() => { + console.warn( + 'An initialization function has not been called within 5 seconds of page load, and "initializeManually" is set to true.\n' + + 'Load the experience by calling AnswersExperience.init() or AnswersExperienceFrame.init() for iframe integrations.' + ); + }, 5000); + window.AnswersExperience.init = (config = {}) => { + this._fireOnDomLoad(() => { + Object.entries(config).forEach(([key, value]) => { + window.AnswersExperience.runtimeConfig.set(key, value); + }); + clearTimeout(runtimeConfigNotProvidedTimeout); + if (!this._hasAnswersInitialized) { + this._initAnswers(); + } + this._hasAnswersInitialized = true; + }); + } + } + + /** + * Executes the provided function on DOM load + * @param {Function} cb + */ + _fireOnDomLoad (cb) { + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', cb); + } else { + cb(); + } + } +} \ No newline at end of file diff --git a/static/js/runtime-config-receiver.js b/static/js/runtime-config-receiver.js new file mode 100644 index 000000000..4135b0f0b --- /dev/null +++ b/static/js/runtime-config-receiver.js @@ -0,0 +1,15 @@ +/** + * Responsible for handling runtime config messages from the parent + */ + export default class RuntimeConfigReceiver { + /** + * Updates the experience's runtime config to include the data provided by the received config + * @param {Object} config An object representation of the runtime config. + * (Not the data model with getters and setters) + */ + static handle (config) { + Object.entries(config).forEach(([key, value]) => { + window.AnswersExperience.runtimeConfig.set(key, value); + }); + } +} \ No newline at end of file diff --git a/static/js/runtime-config.js b/static/js/runtime-config.js new file mode 100644 index 000000000..ba27d6a7c --- /dev/null +++ b/static/js/runtime-config.js @@ -0,0 +1,58 @@ +/** + * A data model for runtime configuration + */ +export default class RuntimeConfig { + constructor (initialConfig = {}) { + this._data = { ...initialConfig }; + this._onUpdateListener = () => {}; + } + + /** + * Returns the value assocaited with a key + * @param {string} key + * @returns {*} + */ + get (key) { + return this._data[key]; + } + + /** + * Returns an object representation of the runtime config + * @returns {*} + */ + getAll () { + return { ...this._data }; + } + + /** + * Sets a value of the config + * @param {string} key + * @param {*} value + */ + set (key, value) { + this._validateSet(key, value); + this._data[key] = value; + this._onUpdateListener(this.getAll()); + } + + /** + * A function which is called any time the RuntimeConfig is updated + * @param {Function} cb + */ + _onUpdate (cb) { + this._onUpdateListener = cb; + } + + _validateSet (key, value) { + const newConfig = { + ...this._data, + [key]: value + }; + try { + JSON.stringify(newConfig); + } catch (e) { + console.error(`Cannot set the key ${key} and value ${value} because the resulting object would not be JSON serializable`); + throw e; + } + } +} \ No newline at end of file diff --git a/static/webpack-config.js b/static/webpack-config.js index 256d79793..6cd882792 100644 --- a/static/webpack-config.js +++ b/static/webpack-config.js @@ -5,6 +5,7 @@ const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const HtmlPlugin = require('html-webpack-plugin'); const RemovePlugin = require('remove-files-webpack-plugin'); const { merge } = require('webpack-merge'); +const { parse } = require('comment-json'); module.exports = function () { const jamboConfig = require('./jambo.json'); @@ -25,6 +26,24 @@ module.exports = function () { }); } + const globalConfigPath = `./${jamboConfig.dirs.config}/global_config.json`; + let globalConfig = {}; + if (fs.existsSync(globalConfigPath)) { + globalConfigRaw = fs.readFileSync(globalConfigPath, 'utf-8'); + globalConfig = parse(globalConfigRaw); + } + + const { useJWT } = globalConfig; + + let jamboInjectedData = process.env.JAMBO_INJECTED_DATA || null; + if (useJWT && jamboInjectedData) { + const getCleanedJamboInjectedData = + require(`./${jamboConfig.dirs.output}/static/webpack/getCleanedJamboInjectedData.js`); + jamboInjectedData = JSON.parse(jamboInjectedData) + jamboInjectedData = getCleanedJamboInjectedData(jamboInjectedData) + jamboInjectedData = JSON.stringify(jamboInjectedData) + } + const plugins = [ new MiniCssExtractPlugin({ filename: pathData => { @@ -35,8 +54,8 @@ module.exports = function () { } }), ...htmlPlugins, - new webpack.EnvironmentPlugin({ - JAMBO_INJECTED_DATA: null + new webpack.DefinePlugin({ + 'process.env.JAMBO_INJECTED_DATA': JSON.stringify(jamboInjectedData) }), new RemovePlugin({ after: { diff --git a/static/webpack/getCleanedJamboInjectedData.js b/static/webpack/getCleanedJamboInjectedData.js new file mode 100644 index 000000000..6ccb51c7c --- /dev/null +++ b/static/webpack/getCleanedJamboInjectedData.js @@ -0,0 +1,31 @@ +const _ = require('lodash'); + +/** + * Returns JAMBO_INJECTED_DATA with instances of the global config's apiKey removed + * + * @param {Object} data JAMBO_INJECTED_DATA + * @returns {Object} + */ +function getCleanedJamboInjectedData (data) { + if (!data || !data.answers || !data.answers.experiences) { + return; + } + const updatedData = _.cloneDeep(data); + const experiences = updatedData.answers.experiences; + + const removeApiKeyFromConfig = config => { + if ('apiKey' in config) { + delete config['apiKey']; + } + } + + Object.values(experiences).forEach(config => { + removeApiKeyFromConfig(config); + if ('configByLabel' in config) { + Object.values(config.configByLabel).forEach(removeApiKeyFromConfig); + } + }); + return updatedData; +} + +module.exports = getCleanedJamboInjectedData; \ No newline at end of file diff --git a/test-site/config/global_config.json b/test-site/config/global_config.json index cd8d22505..ed5dcaf5a 100644 --- a/test-site/config/global_config.json +++ b/test-site/config/global_config.json @@ -3,6 +3,8 @@ "apiKey": "2d8c550071a64ea23e263118a2b0680b", // The answers api key found on the experiences page. This will be provided automatically by the Yext CI system // "experienceVersion": "", // the Answers Experience version to use for API requests. This will be provided automatically by the Yext CI system // "businessId": "", // The business ID of the account. This will be provided automatically by the Yext CI system + // "initializeManually": true, // If true, the experience must be started by calling AnswersExperience.init() or AnswersExperienceFrame.init() for iframe integrations. + // "useJWT": true, // Whether or not to enable JWT. If true, the apiKey will be hidden from the build and the token must be specified through the runtime config. "logo": "", // The link to the logo for open graph meta tag - og:image. "favicon": "", "googleTagManagerName": "dataLayer", // The name of your Google Tag Manager data layer diff --git a/test-site/jambo.json b/test-site/jambo.json index d74f916ab..b5b8c36d6 100644 --- a/test-site/jambo.json +++ b/test-site/jambo.json @@ -10,8 +10,8 @@ "directanswercards" ], "preservedFiles": [ - "public/overlay.html", - "public/iframe_test.html" + "public/iframe_test.html", + "public/overlay.html" ] }, "defaultTheme": "answers-hitchhiker-theme" diff --git a/tests/static/webpack/getCleanedJamboInjectedData.js b/tests/static/webpack/getCleanedJamboInjectedData.js new file mode 100644 index 000000000..5b0b44b1e --- /dev/null +++ b/tests/static/webpack/getCleanedJamboInjectedData.js @@ -0,0 +1,34 @@ +import getCleanedJamboInjectedData from '../../../static/webpack/getCleanedJamboInjectedData'; + +describe('secures the injected data', () => { + const sampleConfig = { + apiKey: 999, + verticals: { + KM: { + displayName: 'Locations', + source: 'KNOWLEDGE_MANAGER' + } + } + }; + + const mockInjectedData = { + businessId: 999, + answers: { + experiences: { + test_experience: { + ...sampleConfig, + configByLabel: { + PRODUCTION: sampleConfig, + STAGING: sampleConfig + } + } + } + } + }; + + it('removes instances of the apiKey', () => { + const securedInjectedData = getCleanedJamboInjectedData(mockInjectedData); + expect(securedInjectedData).toEqual(expect.not.objectContaining({apiKey: 999})); + }); +}); + From 2be0f056fd5664a830d775ae237a918757080a77 Mon Sep 17 00:00:00 2001 From: cea2aj <42848445+cea2aj@users.noreply.github.com> Date: Tue, 22 Jun 2021 15:11:43 -0400 Subject: [PATCH 51/56] Styling fix for fieldset (#846) Update the fieldset styling to properly align the text with the thumbs on the document search standard card on Firefox This stying was likely missing from the cards initially because they seem to be releveant to only the allfields-standard card. However these CSS classes are present for both cards so we should use this styling to properly align the thumbs with the text. This styling is the same as the styling currently in use for allfields-standard. J=none TEST=manual View a document search direct answer on both chrome and firefox --- .../directanswercards/documentsearch-standard.scss | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/static/scss/answers/directanswercards/documentsearch-standard.scss b/static/scss/answers/directanswercards/documentsearch-standard.scss index a0a352906..a7d93c832 100644 --- a/static/scss/answers/directanswercards/documentsearch-standard.scss +++ b/static/scss/answers/directanswercards/documentsearch-standard.scss @@ -140,6 +140,15 @@ } } + &-fieldset + { + display: inline; + margin-inline-start: 2px; + margin-inline-end: 2px; + line-height: 0; + min-inline-size: min-content; + } + &-feedback { @include Text( From c5b39f586e2b2078504eb0baecac1b8b5c4fe891 Mon Sep 17 00:00:00 2001 From: Tom Meyer Date: Wed, 23 Jun 2021 10:43:55 -0400 Subject: [PATCH 52/56] Add the `product-prominentvideo` card to the Theme. (#847) This PR adds the English-only variant of the `multilang-product-prominentvideo` card to the Theme. All calls to `translateJS` were replaced with static text. This PR also fixes the toggling of `Show More`/`Show Less` in both cards by adding `super.onMount` to the cards' custom `onMount`. TEST=manual Verified I could use this card on a test vertical. --- .../component.js | 1 + cards/product-prominentvideo/component.js | 103 +++++++++++++++ cards/product-prominentvideo/template.hbs | 124 ++++++++++++++++++ 3 files changed, 228 insertions(+) create mode 100644 cards/product-prominentvideo/component.js create mode 100644 cards/product-prominentvideo/template.hbs diff --git a/cards/multilang-product-prominentvideo/component.js b/cards/multilang-product-prominentvideo/component.js index 779da89eb..631515086 100644 --- a/cards/multilang-product-prominentvideo/component.js +++ b/cards/multilang-product-prominentvideo/component.js @@ -57,6 +57,7 @@ class multilang_product_prominentvideoCardComponent extends BaseCard['multilang- } onMount() { + super.onMount(); const videoSelector = '.js-HitchhikerProductProminentVideo-video'; const videoEl = this._container.querySelector(videoSelector); if (!videoEl) { diff --git a/cards/product-prominentvideo/component.js b/cards/product-prominentvideo/component.js new file mode 100644 index 000000000..29015b903 --- /dev/null +++ b/cards/product-prominentvideo/component.js @@ -0,0 +1,103 @@ +{{> cards/card_component componentName='product-prominentvideo' }} + +class product_prominentvideoCardComponent extends BaseCard['product-prominentvideo'] { + constructor(config = {}, systemConfig = {}) { + super(config, systemConfig); + } + + /** + * This returns an object that will be called `card` + * in the template. Put all mapping logic here. + * + * @param profile profile of the entity in the card + */ + dataForRender(profile) { + this.youtubeUrl = Formatter.getYoutubeUrl(profile.videos || []); + this.vimeoUrl = profile.c_vimeo; + + const linkTarget = AnswersExperience.runtimeConfig.get('linkTarget') || '_top'; + + return { + title: profile.name, // The header text of the card + url: profile.landingPageUrl, // If the card title is a clickable link, set URL here + target: linkTarget, // If the title's URL should open in a new tab, etc. + titleEventOptions: this.addDefaultEventOptions(), + subtitle: profile.featuredMessage?.description, // The sub-header text of the card + videoUrl: this.youtubeUrl || this.vimeoUrl, + details: profile.richTextDescription ? ANSWERS.formatRichText(profile.richTextDescription, 'richTextDescription', linkTarget) : null, // The text in the body of the card + // If the card's details are longer than a certain character count, you can truncate the + // text. A toggle will be supplied that can show or hide the truncated text. + // Note: If you are using rich text for the details, you should not enable this feature. + // showMoreDetails: { + // showMoreLimit: 24, // Character count limit + // showMoreText: 'Show more', // Label when toggle will show truncated text + // showLessText: 'Show less' // Label when toggle will hide truncated text + // }, + // The primary CTA of the card + CTA1: { + label: profile.c_primaryCTA ? profile.c_primaryCTA.label : null, // The CTA's label + iconName: 'chevron', // The icon to use for the CTA + url: Formatter.generateCTAFieldTypeLink(profile.c_primaryCTA), // The URL a user will be directed to when clicking + target: linkTarget, // Where the new URL will be opened + eventType: 'CTA_CLICK', // Type of Analytics event fired when clicking the CTA + eventOptions: this.addDefaultEventOptions(), + // ariaLabel: '', // Accessible text providing a descriptive label for the CTA + }, + // The secondary CTA of the card + CTA2: { + label: profile.c_secondaryCTA ? profile.c_secondaryCTA.label : null, + iconName: 'chevron', + url: Formatter.generateCTAFieldTypeLink(profile.c_secondaryCTA), + target: linkTarget, + eventType: 'CTA_CLICK', + eventOptions: this.addDefaultEventOptions(), + // ariaLabel: '', + } + }; + } + + onMount() { + super.onMount(); + const videoSelector = '.js-HitchhikerProductProminentVideo-video'; + const videoEl = this._container.querySelector(videoSelector); + if (!videoEl) { + return; + } + const addPlayer = videoApi => { + videoApi.addPlayer(videoEl, { + onPlay: () => this.onPlay() + }); + }; + if (this.youtubeUrl) { + HitchhikerJS.requireYoutubeAPI().then(addPlayer); + } else if (this.vimeoUrl) { + HitchhikerJS.requireVimeoAPI().then(addPlayer); + } + } + + onPlay() { + const event = new ANSWERS.AnalyticsEvent('CTA_CLICK') + .addOptions({ + verticalKey: this.verticalKey, + entityId: this.result?._raw?.id, + searcher: this._config.isUniversal ? 'UNIVERSAL' : 'VERTICAL', + ctaLabel: 'video_played' + }); + this.analyticsReporter.report(event); + } + + /** + * The template to render + * @returns {string} + * @override + */ + static defaultTemplateName (config) { + return 'cards/product-prominentvideo'; + } +} + +ANSWERS.registerTemplate( + 'cards/product-prominentvideo', + {{{stringifyPartial (read 'cards/product-prominentvideo/template') }}} +); +ANSWERS.registerComponentType(product_prominentvideoCardComponent); diff --git a/cards/product-prominentvideo/template.hbs b/cards/product-prominentvideo/template.hbs new file mode 100644 index 000000000..a25c5f932 --- /dev/null +++ b/cards/product-prominentvideo/template.hbs @@ -0,0 +1,124 @@ +
+
+ {{> title }} + {{> subtitle }} +
+ {{> video }} + {{> content }} +
+ +{{#*inline 'title'}} +{{#if card.title}} +
+ {{#if card.url}} + + {{card.title}} + + {{else}} + {{card.title}} + {{/if}} +
+{{/if}} +{{/inline}} + +{{#*inline 'subtitle'}} +{{#if card.subtitle}} +
+ {{card.subtitle}} +
+{{/if}} +{{/inline}} + +{{#*inline 'video'}} +{{#if card.videoUrl}} +
+ +
+{{/if}} +{{/inline}} + +{{#*inline 'content'}} +{{#if (any card.details (all card.CTA1 card.CTA1.url card.CTA1.label) (all card.CTA2 card.CTA2.url card.CTA2.label))}} +
+ {{> details }} + {{> ctas }} +
+{{/if}} +{{/inline}} + +{{! Displays the details for the card. If showMoreDetails has been configured, + this partial handles the show more toggle, show less toggle, truncated details, + and full details. If showMoreDetails has not been configured, it will display the + the regular card details. +}} +{{#*inline 'details'}} +{{#if card.details}} +
+ {{#if showExcessDetailsToggle}} +
+ {{{truncatedDetails}}} +
+ {{/if}} +
+ {{{card.details}}} +
+ {{#if showExcessDetailsToggle}} + + + {{/if}} +
+{{/if}} +{{/inline}} + +{{#*inline 'ctas'}} +{{#if (any (all card.CTA1 card.CTA1.url card.CTA1.label) (all card.CTA2 card.CTA2.url card.CTA2.label))}} +
+ {{> CTA card.CTA1 ctaName="primaryCTA" }} + {{> CTA card.CTA2 ctaName="secondaryCTA" }} +
+{{/if}} +{{/inline}} + +{{#*inline 'CTA'}} +{{#if (all url label)}} + +{{/if}} +{{/inline}} From 4722c51a759a89c46ff60f1043bf7f9efddc541a Mon Sep 17 00:00:00 2001 From: Tom Meyer Date: Wed, 23 Jun 2021 10:46:26 -0400 Subject: [PATCH 53/56] Update version to v1.22.0. --- package-lock.json | 13 +++++++++++-- package.json | 2 +- static/package-lock.json | 2 +- static/package.json | 2 +- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index b53ed2ac1..720454f86 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "answers-hitchhiker-theme", - "version": "1.21.1", + "version": "1.22.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -6794,7 +6794,10 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/full-icu/-/full-icu-1.3.1.tgz", "integrity": "sha512-VMtK//85QJomhk3cXOCksNwOYaw1KWnYTS37GYGgyf7A3ajdBoPGhaJuJWAH2S2kq8GZeXkdKn+3Mfmgy11cVw==", - "dev": true + "dev": true, + "requires": { + "icu4c-data": "^0.64.2" + } }, "function-bind": { "version": "1.1.1", @@ -7213,6 +7216,12 @@ "safer-buffer": ">= 2.1.2 < 3" } }, + "icu4c-data": { + "version": "0.64.2", + "resolved": "https://registry.npmjs.org/icu4c-data/-/icu4c-data-0.64.2.tgz", + "integrity": "sha512-BPuTfkRTkplmK1pNrqgyOLJ0qB2UcQ12EotVLwiWh4ErtZR1tEYoRZk/LBLmlDfK5v574/lQYLB4jT9vApBiBQ==", + "dev": true + }, "ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", diff --git a/package.json b/package.json index abba97284..08d23aebe 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "answers-hitchhiker-theme", - "version": "1.21.1", + "version": "1.22.0", "description": "A starter answers theme for hitchhikers", "scripts": { "test": "cross-env NODE_ICU_DATA=node_modules/full-icu jest --verbose", diff --git a/static/package-lock.json b/static/package-lock.json index 7c21d6148..a4c9b0195 100644 --- a/static/package-lock.json +++ b/static/package-lock.json @@ -1,6 +1,6 @@ { "name": "answers-hitchhiker-theme", - "version": "1.21.1", + "version": "1.22.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/static/package.json b/static/package.json index d5a7acb23..39d3b326a 100644 --- a/static/package.json +++ b/static/package.json @@ -1,6 +1,6 @@ { "name": "answers-hitchhiker-theme", - "version": "1.21.1", + "version": "1.22.0", "description": "Toolchain for use with the HH Theme", "main": "Gruntfile.js", "scripts": { From 34c1d2de9c91c0c5482526336824424890830b23 Mon Sep 17 00:00:00 2001 From: cea2aj <42848445+cea2aj@users.noreply.github.com> Date: Wed, 23 Jun 2021 13:54:52 -0400 Subject: [PATCH 54/56] Use SDK version 1.9 (#848) Point to SDK version 1.9 TEST=none J=none --- global_config.json | 2 +- test-site/config/global_config.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/global_config.json b/global_config.json index d3dff862f..045833d0d 100644 --- a/global_config.json +++ b/global_config.json @@ -1,5 +1,5 @@ { - "sdkVersion": "release/v1.9", // The version of the Answers SDK to use + "sdkVersion": "1.9", // The version of the Answers SDK to use // "apiKey": "", // The answers api key found on the experiences page. This will be provided automatically by the Yext CI system // "experienceVersion": "", // the Answers Experience version to use for API requests. This will be provided automatically by the Yext CI system // "businessId": "", // The business ID of the account. This will be provided automatically by the Yext CI system diff --git a/test-site/config/global_config.json b/test-site/config/global_config.json index ed5dcaf5a..23988d98c 100644 --- a/test-site/config/global_config.json +++ b/test-site/config/global_config.json @@ -1,5 +1,5 @@ { - "sdkVersion": "release/v1.9", // The version of the Answers SDK to use + "sdkVersion": "1.9", // The version of the Answers SDK to use "apiKey": "2d8c550071a64ea23e263118a2b0680b", // The answers api key found on the experiences page. This will be provided automatically by the Yext CI system // "experienceVersion": "", // the Answers Experience version to use for API requests. This will be provided automatically by the Yext CI system // "businessId": "", // The business ID of the account. This will be provided automatically by the Yext CI system From 86cfe45ee4afb640987dc823ebc3a280c9923512 Mon Sep 17 00:00:00 2001 From: cea2aj <42848445+cea2aj@users.noreply.github.com> Date: Wed, 23 Jun 2021 14:03:09 -0400 Subject: [PATCH 55/56] Testcafe config file (#849) Add a testcafe config file to make the internet explorer tests more robust J=none TEST=manual Run the tests and confirm they pass --- tests/acceptance/index.js | 4 +++- tests/acceptance/testcafe.json | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 tests/acceptance/testcafe.json diff --git a/tests/acceptance/index.js b/tests/acceptance/index.js index d15051d57..86518b84c 100644 --- a/tests/acceptance/index.js +++ b/tests/acceptance/index.js @@ -21,7 +21,9 @@ runTests(argv.browsers); * @param {string[]} browsers The browsers to run the tests on */ async function runTests (browsers) { - const testcafe = await createTestCafe(); + const testcafe = await createTestCafe({ + configFile: './testcafe.json' + }); try { const numberTestsFailed = await testcafe.createRunner() .src('tests/acceptance/suites/*.js') diff --git a/tests/acceptance/testcafe.json b/tests/acceptance/testcafe.json new file mode 100644 index 000000000..6b0068bcf --- /dev/null +++ b/tests/acceptance/testcafe.json @@ -0,0 +1,5 @@ +{ + "selectorTimeout": 20000, // default is 10000 + "assertionTimeout": 6000, // default is 3000 + "pageLoadTimeout": 6000 // default is 3000 +} \ No newline at end of file From 432078062b17cbb5ead66746c2a83e48fb2bbea8 Mon Sep 17 00:00:00 2001 From: cea2aj <42848445+cea2aj@users.noreply.github.com> Date: Wed, 23 Jun 2021 14:32:24 -0400 Subject: [PATCH 56/56] Remove _fireOnDomLoad (#845) We can remove the `_fireOnDomLoad` from the manual initializer because the setup function itself is called during `DOMContentLoaded` J=none TEST=manual Smoke test runtime config and manual initialization --- static/js/manual-initializer.js | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/static/js/manual-initializer.js b/static/js/manual-initializer.js index d9bb79f8b..7776ab547 100644 --- a/static/js/manual-initializer.js +++ b/static/js/manual-initializer.js @@ -22,28 +22,14 @@ export default class ManualInitializer { ); }, 5000); window.AnswersExperience.init = (config = {}) => { - this._fireOnDomLoad(() => { - Object.entries(config).forEach(([key, value]) => { - window.AnswersExperience.runtimeConfig.set(key, value); - }); - clearTimeout(runtimeConfigNotProvidedTimeout); - if (!this._hasAnswersInitialized) { - this._initAnswers(); - } - this._hasAnswersInitialized = true; + Object.entries(config).forEach(([key, value]) => { + window.AnswersExperience.runtimeConfig.set(key, value); }); - } - } - - /** - * Executes the provided function on DOM load - * @param {Function} cb - */ - _fireOnDomLoad (cb) { - if (document.readyState === 'loading') { - document.addEventListener('DOMContentLoaded', cb); - } else { - cb(); + clearTimeout(runtimeConfigNotProvidedTimeout); + if (!this._hasAnswersInitialized) { + this._initAnswers(); + } + this._hasAnswersInitialized = true; } } } \ No newline at end of file