From 6cbdd26ad9e546556867135a8923e468fa0400d7 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Tue, 1 Dec 2020 10:25:48 +0100 Subject: [PATCH 01/60] feat: set up repo --- .eslintrc | 3 + .github/workflows/test.yaml | 27 + .gitignore | 3 + .mergify.yml | 16 + .prettierignore | 2 + .prettierrc.js | 3 + .snyk | 4 + LICENSE | 29 + README.md | 13 + commitlint.config.js | 1 + lib/loader.ts | 16 + package-lock.json | 8273 +++++++++++++++++++++++++++++++++++ package.json | 75 + renovate.json | 3 + tsconfig.json | 7 + 15 files changed, 8475 insertions(+) create mode 100644 .eslintrc create mode 100644 .github/workflows/test.yaml create mode 100644 .gitignore create mode 100644 .mergify.yml create mode 100644 .prettierignore create mode 100644 .prettierrc.js create mode 100644 .snyk create mode 100644 LICENSE create mode 100644 README.md create mode 100644 commitlint.config.js create mode 100644 lib/loader.ts create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 renovate.json create mode 100644 tsconfig.json diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..5a80290 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,3 @@ +{ + "extends": "@bifravst/eslint-config-typescript" +} diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..74df5c9 --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,27 @@ +name: Test + +on: push + +env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + +jobs: + tests: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: "14.x" + - name: Keep npm cache around to speed up installs + uses: actions/cache@v2 + with: + path: ~/.npm + key: ${{ runner.OS }}-build-${{ hashFiles('**/package-lock.json') }} + - name: Install dependencies + run: npm ci --no-audit + - name: Compile + run: npx tsc + - name: Test + run: npm test diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c6d8012 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +npm-debug.log +dist/ diff --git a/.mergify.yml b/.mergify.yml new file mode 100644 index 0000000..3cd0df4 --- /dev/null +++ b/.mergify.yml @@ -0,0 +1,16 @@ +pull_request_rules: + - name: Automatic merge security PRs when all status checks pass + conditions: + - author~=^(snyk-bot|dependabot\[bot\])$ + - status-success=security/snyk (coderbyheart) + - status-success=tests + actions: + merge: + method: rebase + rebase_fallback: squash + bot_account: coderbyheart + label: + add: + - mergify + rebase: + bot_account: coderbyheart diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..3ad4c84 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,2 @@ +dist/ +package-lock.json diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 0000000..ff901ec --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,3 @@ +module.exports = { + ...require('@bifravst/code-style/.prettierrc'), +} diff --git a/.snyk b/.snyk new file mode 100644 index 0000000..8cb541f --- /dev/null +++ b/.snyk @@ -0,0 +1,4 @@ +# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities. +version: v1.14.1 +ignore: {} +patch: {} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..19cdfa1 --- /dev/null +++ b/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2020, Nordic Semiconductor ASA | nordicsemi.no +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..3b0e78e --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# Advent of Code 2020 solutions in TypeScript + +[![GitHub Actions](https://github.com/coderbyheart/aoc/workflows/Test/badge.svg)](https://github.com/coderbyheart/aoc/actions) +[![Known Vulnerabilities](https://snyk.io/test/github/coderbyheart/aoc/badge.svg)](https://snyk.io/test/github/coderbyheart/aoc) +[![Renovate](https://img.shields.io/badge/renovate-enabled-brightgreen.svg)](https://renovatebot.com) +[![Mergify Status](https://img.shields.io/endpoint.svg?url=https://dashboard.mergify.io/badges/coderbyheart/aoc&style=flat)](https://mergify.io) +[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/) +[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier/) +[![ESLint: TypeScript](https://img.shields.io/badge/ESLint-TypeScript-blue.svg)](https://github.com/typescript-eslint/typescript-eslint) + + git clone https://github.com/coderbyheart/aoc + npm ci + npm test diff --git a/commitlint.config.js b/commitlint.config.js new file mode 100644 index 0000000..29cfa50 --- /dev/null +++ b/commitlint.config.js @@ -0,0 +1 @@ +module.exports = { extends: ["@commitlint/config-angular"] }; diff --git a/lib/loader.ts b/lib/loader.ts new file mode 100644 index 0000000..5dfe393 --- /dev/null +++ b/lib/loader.ts @@ -0,0 +1,16 @@ +import * as fs from 'fs' +import * as path from 'path' + +export const loader = (day: number) => (file: string): string[] => + fs + .readFileSync( + path.resolve( + process.cwd(), + `day${day.toString().padStart(2, '0')}`, + `${file}.txt`, + ), + 'utf-8', + ) + .split('\n') + .map((s) => s.trim()) + .filter((s) => s.length > 0) diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..29b86d3 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,8273 @@ +{ + "name": "@coderbyheart/advent-of-code", + "version": "0.0.0-development", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/core": { + "version": "7.12.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.3.tgz", + "integrity": "sha512-0qXcZYKZp3/6N2jKYVxZv0aNCsxTSVCiK72DTiTYZAu7sjg73W0/aynWjMbiGd87EQL4WyA8reiJVh92AVla9g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.12.1", + "@babel/helper-module-transforms": "^7.12.1", + "@babel/helpers": "^7.12.1", + "@babel/parser": "^7.12.3", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.12.1", + "@babel/types": "^7.12.1", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.19", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.5.tgz", + "integrity": "sha512-m16TQQJ8hPt7E+OS/XVQg/7U184MLXtvuGbCdA7na61vha+ImkyyNM/9DDA0unYCVZn3ZOhng+qz48/KBOT96A==", + "dev": true, + "requires": { + "@babel/types": "^7.12.5", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/helper-function-name": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.1.tgz", + "integrity": "sha512-k0CIe3tXUKTRSoEx1LQEPFU9vRQfqHtl+kf8eNnDqb4AUJEy5pz6aIiog+YWtVm2jpggjS1laH68bPsR+KWWPQ==", + "dev": true, + "requires": { + "@babel/types": "^7.12.1" + } + }, + "@babel/helper-module-imports": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", + "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.5" + } + }, + "@babel/helper-module-transforms": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz", + "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.12.1", + "@babel/helper-replace-supers": "^7.12.1", + "@babel/helper-simple-access": "^7.12.1", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/helper-validator-identifier": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.12.1", + "@babel/types": "^7.12.1", + "lodash": "^4.17.19" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz", + "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "dev": true + }, + "@babel/helper-replace-supers": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.5.tgz", + "integrity": "sha512-5YILoed0ZyIpF4gKcpZitEnXEJ9UoDRki1Ey6xz46rxOzfNMAhVIJMoune1hmPVxh40LRv1+oafz7UsWX+vyWA==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.12.1", + "@babel/helper-optimise-call-expression": "^7.10.4", + "@babel/traverse": "^7.12.5", + "@babel/types": "^7.12.5" + } + }, + "@babel/helper-simple-access": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz", + "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.1" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", + "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/helpers": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.5.tgz", + "integrity": "sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA==", + "dev": true, + "requires": { + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.12.5", + "@babel/types": "^7.12.5" + } + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.5.tgz", + "integrity": "sha512-FVM6RZQ0mn2KCf1VUED7KepYeUWoVShczewOCfm3nzoBybaih51h+sYVVGthW9M6lPByEPTQf+xm27PBdlpwmQ==", + "dev": true + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.1.tgz", + "integrity": "sha512-U40A76x5gTwmESz+qiqssqmeEsKvcSyvtgktrm0uzcARAmM9I1jR221f6Oq+GmHrcD+LvZDag1UTOTe2fL3TeA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.1.tgz", + "integrity": "sha512-i7ooMZFS+a/Om0crxZodrTzNEPJHZrlMVGMTEpFAj6rYY/bKCddB0Dk/YxfPuYXOopuhKk/e1jV6h+WUU9XN3A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/runtime": { + "version": "7.11.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.11.2.tgz", + "integrity": "sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/traverse": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.5.tgz", + "integrity": "sha512-xa15FbQnias7z9a62LwYAA5SZZPkHIXpd42C6uW68o8uTuua96FHZy1y61Va5P/i83FAAcMpW8+A/QayntzuqA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.12.5", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/parser": "^7.12.5", + "@babel/types": "^7.12.5", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + } + }, + "@babel/types": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.5.tgz", + "integrity": "sha512-gyTcvz7JFa4V45C0Zklv//GmFOAal5fL23OWpBLqc4nZ4Yrz67s4kCNwSK1Gu0MXGTU8mRY3zJYtacLdKXlzig==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "@bifravst/code-style": { + "version": "8.0.134", + "resolved": "https://registry.npmjs.org/@bifravst/code-style/-/code-style-8.0.134.tgz", + "integrity": "sha512-3MqjsPoE/GzFa34rZ/bU7Qq8G+kGESikMdaZopa47wEo9NgvMtfdu4RivgLvNqMPcxqBZdR4eN1un3G4Laj10Q==", + "dev": true + }, + "@bifravst/eslint-config-typescript": { + "version": "5.0.79", + "resolved": "https://registry.npmjs.org/@bifravst/eslint-config-typescript/-/eslint-config-typescript-5.0.79.tgz", + "integrity": "sha512-IJTuwuaBq90LMhyMzf74cPa8YBklMVorqlJtYGT9M7s7js1yjmTdVK42BuvpnuhW6FShVoZZrObSqfE/EPpyvw==", + "dev": true, + "requires": { + "@typescript-eslint/eslint-plugin": "4.9.0", + "@typescript-eslint/parser": "4.9.0", + "eslint-config-prettier": "6.15.0" + } + }, + "@cnakazawa/watch": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", + "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", + "dev": true, + "requires": { + "exec-sh": "^0.3.2", + "minimist": "^1.2.0" + } + }, + "@commitlint/cli": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-11.0.0.tgz", + "integrity": "sha512-YWZWg1DuqqO5Zjh7vUOeSX76vm0FFyz4y0cpGMFhrhvUi5unc4IVfCXZ6337R9zxuBtmveiRuuhQqnRRer+13g==", + "dev": true, + "requires": { + "@babel/runtime": "^7.11.2", + "@commitlint/format": "^11.0.0", + "@commitlint/lint": "^11.0.0", + "@commitlint/load": "^11.0.0", + "@commitlint/read": "^11.0.0", + "chalk": "4.1.0", + "core-js": "^3.6.1", + "get-stdin": "8.0.0", + "lodash": "^4.17.19", + "resolve-from": "5.0.0", + "resolve-global": "1.0.0", + "yargs": "^15.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "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 + }, + "get-stdin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "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 + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "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" + } + } + } + }, + "@commitlint/config-angular": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/config-angular/-/config-angular-11.0.0.tgz", + "integrity": "sha512-H8QSEOmfRsPW0Iehid5fY7NZ2HXmyKC6Q83MLFf9KRnmCcbgJtH+faECtqlvPntayO3CYbA4UenIerOaQ0vOAg==", + "dev": true, + "requires": { + "@commitlint/config-angular-type-enum": "^11.0.0" + } + }, + "@commitlint/config-angular-type-enum": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/config-angular-type-enum/-/config-angular-type-enum-11.0.0.tgz", + "integrity": "sha512-dSyxdkU36aEgDUWBSiM5lsZ/h2K7uCyKf+A5Sf3+Z5JhcLD9GzTo5W+c8KgwTBdL39dkL7sN+EVgsXNjW99pJg==", + "dev": true + }, + "@commitlint/ensure": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-11.0.0.tgz", + "integrity": "sha512-/T4tjseSwlirKZdnx4AuICMNNlFvRyPQimbZIOYujp9DSO6XRtOy9NrmvWujwHsq9F5Wb80QWi4WMW6HMaENug==", + "dev": true, + "requires": { + "@commitlint/types": "^11.0.0", + "lodash": "^4.17.19" + } + }, + "@commitlint/execute-rule": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-11.0.0.tgz", + "integrity": "sha512-g01p1g4BmYlZ2+tdotCavrMunnPFPhTzG1ZiLKTCYrooHRbmvqo42ZZn4QMStUEIcn+jfLb6BRZX3JzIwA1ezQ==", + "dev": true + }, + "@commitlint/format": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-11.0.0.tgz", + "integrity": "sha512-bpBLWmG0wfZH/svzqD1hsGTpm79TKJWcf6EXZllh2J/LSSYKxGlv967lpw0hNojme0sZd4a/97R3qA2QHWWSLg==", + "dev": true, + "requires": { + "@commitlint/types": "^11.0.0", + "chalk": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "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" + } + } + } + }, + "@commitlint/is-ignored": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-11.0.0.tgz", + "integrity": "sha512-VLHOUBN+sOlkYC4tGuzE41yNPO2w09sQnOpfS+pSPnBFkNUUHawEuA44PLHtDvQgVuYrMAmSWFQpWabMoP5/Xg==", + "dev": true, + "requires": { + "@commitlint/types": "^11.0.0", + "semver": "7.3.2" + } + }, + "@commitlint/lint": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-11.0.0.tgz", + "integrity": "sha512-Q8IIqGIHfwKr8ecVZyYh6NtXFmKw4YSEWEr2GJTB/fTZXgaOGtGFZDWOesCZllQ63f1s/oWJYtVv5RAEuwN8BQ==", + "dev": true, + "requires": { + "@commitlint/is-ignored": "^11.0.0", + "@commitlint/parse": "^11.0.0", + "@commitlint/rules": "^11.0.0", + "@commitlint/types": "^11.0.0" + } + }, + "@commitlint/load": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-11.0.0.tgz", + "integrity": "sha512-t5ZBrtgvgCwPfxmG811FCp39/o3SJ7L+SNsxFL92OR4WQxPcu6c8taD0CG2lzOHGuRyuMxZ7ps3EbngT2WpiCg==", + "dev": true, + "requires": { + "@commitlint/execute-rule": "^11.0.0", + "@commitlint/resolve-extends": "^11.0.0", + "@commitlint/types": "^11.0.0", + "chalk": "4.1.0", + "cosmiconfig": "^7.0.0", + "lodash": "^4.17.19", + "resolve-from": "^5.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "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 + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "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" + } + } + } + }, + "@commitlint/message": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-11.0.0.tgz", + "integrity": "sha512-01ObK/18JL7PEIE3dBRtoMmU6S3ecPYDTQWWhcO+ErA3Ai0KDYqV5VWWEijdcVafNpdeUNrEMigRkxXHQLbyJA==", + "dev": true + }, + "@commitlint/parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-11.0.0.tgz", + "integrity": "sha512-DekKQAIYWAXIcyAZ6/PDBJylWJ1BROTfDIzr9PMVxZRxBPc1gW2TG8fLgjZfBP5mc0cuthPkVi91KQQKGri/7A==", + "dev": true, + "requires": { + "conventional-changelog-angular": "^5.0.0", + "conventional-commits-parser": "^3.0.0" + } + }, + "@commitlint/read": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-11.0.0.tgz", + "integrity": "sha512-37V0V91GSv0aDzMzJioKpCoZw6l0shk7+tRG8RkW1GfZzUIytdg3XqJmM+IaIYpaop0m6BbZtfq+idzUwJnw7g==", + "dev": true, + "requires": { + "@commitlint/top-level": "^11.0.0", + "fs-extra": "^9.0.0", + "git-raw-commits": "^2.0.0" + } + }, + "@commitlint/resolve-extends": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-11.0.0.tgz", + "integrity": "sha512-WinU6Uv6L7HDGLqn/To13KM1CWvZ09VHZqryqxXa1OY+EvJkfU734CwnOEeNlSCK7FVLrB4kmodLJtL1dkEpXw==", + "dev": true, + "requires": { + "import-fresh": "^3.0.0", + "lodash": "^4.17.19", + "resolve-from": "^5.0.0", + "resolve-global": "^1.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } + } + }, + "@commitlint/rules": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-11.0.0.tgz", + "integrity": "sha512-2hD9y9Ep5ZfoNxDDPkQadd2jJeocrwC4vJ98I0g8pNYn/W8hS9+/FuNpolREHN8PhmexXbkjrwyQrWbuC0DVaA==", + "dev": true, + "requires": { + "@commitlint/ensure": "^11.0.0", + "@commitlint/message": "^11.0.0", + "@commitlint/to-lines": "^11.0.0", + "@commitlint/types": "^11.0.0" + } + }, + "@commitlint/to-lines": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-11.0.0.tgz", + "integrity": "sha512-TIDTB0Y23jlCNubDROUVokbJk6860idYB5cZkLWcRS9tlb6YSoeLn1NLafPlrhhkkkZzTYnlKYzCVrBNVes1iw==", + "dev": true + }, + "@commitlint/top-level": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-11.0.0.tgz", + "integrity": "sha512-O0nFU8o+Ws+py5pfMQIuyxOtfR/kwtr5ybqTvR+C2lUPer2x6lnQU+OnfD7hPM+A+COIUZWx10mYQvkR3MmtAA==", + "dev": true, + "requires": { + "find-up": "^5.0.0" + }, + "dependencies": { + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "p-limit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz", + "integrity": "sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + } + } + }, + "@commitlint/types": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-11.0.0.tgz", + "integrity": "sha512-VoNqai1vR5anRF5Tuh/+SWDFk7xi7oMwHrHrbm1BprYXjB2RJsWLhUrStMssDxEl5lW/z3EUdg8RvH/IUBccSQ==", + "dev": true + }, + "@eslint/eslintrc": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.1.tgz", + "integrity": "sha512-XRUeBZ5zBWLYgSANMpThFddrZZkEbGHgUdt5UJjZfnlN9BGCiUBrf+nvbRupSjMvqzwnQN0qwCmOxITt1cfywA==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "lodash": "^4.17.19", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + } + } + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } + } + }, + "@istanbuljs/schema": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", + "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", + "dev": true + }, + "@jest/console": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", + "slash": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/core": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.6.3.tgz", + "integrity": "sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==", + "dev": true, + "requires": { + "@jest/console": "^26.6.2", + "@jest/reporters": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-changed-files": "^26.6.2", + "jest-config": "^26.6.3", + "jest-haste-map": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-resolve-dependencies": "^26.6.3", + "jest-runner": "^26.6.3", + "jest-runtime": "^26.6.3", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "jest-watcher": "^26.6.2", + "micromatch": "^4.0.2", + "p-each-series": "^2.1.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/environment": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "dev": true, + "requires": { + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" + } + }, + "@jest/fake-timers": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" + } + }, + "@jest/globals": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz", + "integrity": "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==", + "dev": true, + "requires": { + "@jest/environment": "^26.6.2", + "@jest/types": "^26.6.2", + "expect": "^26.6.2" + } + }, + "@jest/reporters": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz", + "integrity": "sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^26.6.2", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "node-notifier": "^8.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^7.0.0" + }, + "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.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/source-map": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz", + "integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==", + "dev": true, + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + } + }, + "@jest/test-result": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", + "dev": true, + "requires": { + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/test-sequencer": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz", + "integrity": "sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==", + "dev": true, + "requires": { + "@jest/test-result": "^26.6.2", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.6.2", + "jest-runner": "^26.6.3", + "jest-runtime": "^26.6.3" + } + }, + "@jest/transform": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz", + "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^26.6.2", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-util": "^26.6.2", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "dependencies": { + "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.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "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" + } + } + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", + "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.3", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", + "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.3", + "fastq": "^1.6.0" + } + }, + "@sinonjs/commons": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz", + "integrity": "sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "@types/babel__core": { + "version": "7.1.12", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.12.tgz", + "integrity": "sha512-wMTHiiTiBAAPebqaPiPDLFA4LYPKr6Ph0Xq/6rq1Ur3v66HXyG+clfR9CNETkD7MQS8ZHvpQOtA53DLws5WAEQ==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.2.tgz", + "integrity": "sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.3.tgz", + "integrity": "sha512-uCoznIPDmnickEi6D0v11SBpW0OuVqHJCa7syXqQHy5uktSCreIlt0iglsCnmvz8yCb38hGcWeseA8cWJSwv5Q==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.15.tgz", + "integrity": "sha512-Pzh9O3sTK8V6I1olsXpCfj2k/ygO2q1X0vhhnDrEQyYLHZesWz+zMZMVcwXLCYf0U36EtmyYaFGPfXlTtDHe3A==", + "dev": true, + "requires": { + "@babel/types": "^7.3.0" + } + }, + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "dev": true + }, + "@types/graceful-fs": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.4.tgz", + "integrity": "sha512-mWA/4zFQhfvOA8zWkXobwJvBD7vzcxgrOQ0J5CH1votGqdq9m7+FwtGaqyCZqC3NyyBkc9z4m+iry4LlqcMWJg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", + "dev": true + }, + "@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/jest": { + "version": "26.0.15", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.15.tgz", + "integrity": "sha512-s2VMReFXRg9XXxV+CW9e5Nz8fH2K1aEhwgjUqPPbQd7g95T0laAcvLv032EhFHIa5GHsZ8W7iJEQVaJq6k3Gog==", + "dev": true, + "requires": { + "jest-diff": "^26.0.0", + "pretty-format": "^26.0.0" + } + }, + "@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==", + "dev": true + }, + "@types/minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY=", + "dev": true + }, + "@types/node": { + "version": "14.14.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.10.tgz", + "integrity": "sha512-J32dgx2hw8vXrSbu4ZlVhn1Nm3GbeCFNw2FWL8S5QKucHGY0cyNwjdQdO+KMBZ4wpmC7KhLCiNsdk1RFRIYUQQ==", + "dev": true + }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true + }, + "@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/prettier": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.1.5.tgz", + "integrity": "sha512-UEyp8LwZ4Dg30kVU2Q3amHHyTn1jEdhCIE59ANed76GaT1Vp76DD3ZWSAxgCrw6wJ0TqeoBpqmfUHiUDPs//HQ==", + "dev": true + }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", + "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==", + "dev": true + }, + "@typescript-eslint/eslint-plugin": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.9.0.tgz", + "integrity": "sha512-WrVzGMzzCrgrpnQMQm4Tnf+dk+wdl/YbgIgd5hKGa2P+lnJ2MON+nQnbwgbxtN9QDLi8HO+JAq0/krMnjQK6Cw==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "4.9.0", + "@typescript-eslint/scope-manager": "4.9.0", + "debug": "^4.1.1", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.0.0", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + } + }, + "@typescript-eslint/experimental-utils": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.9.0.tgz", + "integrity": "sha512-0p8GnDWB3R2oGhmRXlEnCvYOtaBCijtA5uBfH5GxQKsukdSQyI4opC4NGTUb88CagsoNQ4rb/hId2JuMbzWKFQ==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/scope-manager": "4.9.0", + "@typescript-eslint/types": "4.9.0", + "@typescript-eslint/typescript-estree": "4.9.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + } + }, + "@typescript-eslint/parser": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.9.0.tgz", + "integrity": "sha512-QRSDAV8tGZoQye/ogp28ypb8qpsZPV6FOLD+tbN4ohKUWHD2n/u0Q2tIBnCsGwQCiD94RdtLkcqpdK4vKcLCCw==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "4.9.0", + "@typescript-eslint/types": "4.9.0", + "@typescript-eslint/typescript-estree": "4.9.0", + "debug": "^4.1.1" + } + }, + "@typescript-eslint/scope-manager": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.9.0.tgz", + "integrity": "sha512-q/81jtmcDtMRE+nfFt5pWqO0R41k46gpVLnuefqVOXl4QV1GdQoBWfk5REcipoJNQH9+F5l+dwa9Li5fbALjzg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.9.0", + "@typescript-eslint/visitor-keys": "4.9.0" + } + }, + "@typescript-eslint/types": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.9.0.tgz", + "integrity": "sha512-luzLKmowfiM/IoJL/rus1K9iZpSJK6GlOS/1ezKplb7MkORt2dDcfi8g9B0bsF6JoRGhqn0D3Va55b+vredFHA==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.9.0.tgz", + "integrity": "sha512-rmDR++PGrIyQzAtt3pPcmKWLr7MA+u/Cmq9b/rON3//t5WofNR4m/Ybft2vOLj0WtUzjn018ekHjTsnIyBsQug==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.9.0", + "@typescript-eslint/visitor-keys": "4.9.0", + "debug": "^4.1.1", + "globby": "^11.0.1", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.9.0.tgz", + "integrity": "sha512-sV45zfdRqQo1A97pOSx3fsjR+3blmwtdCt8LDrXgCX36v4Vmz4KHrhpV6Fo2cRdXmyumxx11AHw0pNJqCNpDyg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.9.0", + "eslint-visitor-keys": "^2.0.0" + } + }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, + "abab": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", + "dev": true + }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "dev": true, + "requires": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, + "acorn-jsx": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "dev": true + }, + "acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "dev": true, + "requires": { + "type-fest": "^0.11.0" + }, + "dependencies": { + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "dev": true + } + } + }, + "ansi-regex": { + "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": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=", + "dev": true + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "dev": true + }, + "babel-jest": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.6.3.tgz", + "integrity": "sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==", + "dev": true, + "requires": { + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/babel__core": "^7.1.7", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^26.6.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "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" + } + } + } + }, + "babel-plugin-istanbul": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^4.0.0", + "test-exclude": "^6.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz", + "integrity": "sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==", + "dev": true, + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-current-node-syntax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.0.tgz", + "integrity": "sha512-mGkvkpocWJes1CmMKtgGUwCeeq0pOhALyymozzDWYomHTbDLwueDYG6p4TK1YOeYHCzBzYPsWkgTto10JubI1Q==", + "dev": true, + "requires": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + } + }, + "babel-preset-jest": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz", + "integrity": "sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^26.6.2", + "babel-preset-current-node-syntax": "^1.0.0" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + } + } + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", + "dev": true + }, + "bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "requires": { + "fast-json-stable-stringify": "2.x" + } + }, + "bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "requires": { + "node-int64": "^0.4.0" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "dependencies": { + "quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true + } + } + }, + "capture-exit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", + "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", + "dev": true, + "requires": { + "rsvp": "^4.8.4" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "cjs-module-lexer": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz", + "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==", + "dev": true + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "requires": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + } + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "dev": true + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.0.tgz", + "integrity": "sha512-zP4jEKbe8SHzKJYQmq8Y9gYjtO/POJLgIdKgV7B9qNmABVFVc+ctqSX6iXh4mCpJfRBOabiZ2YKPg8ciDw6C+Q==", + "dev": true + }, + "compare-func": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", + "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", + "dev": true, + "requires": { + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" + } + }, + "compare-versions": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", + "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==", + "dev": true + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "conventional-changelog-angular": { + "version": "5.0.11", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.11.tgz", + "integrity": "sha512-nSLypht/1yEflhuTogC03i7DX7sOrXGsRn14g131Potqi6cbGbGEE9PSDEHKldabB6N76HiSyw9Ph+kLmC04Qw==", + "dev": true, + "requires": { + "compare-func": "^2.0.0", + "q": "^1.5.1" + } + }, + "conventional-commits-parser": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.1.0.tgz", + "integrity": "sha512-RSo5S0WIwXZiRxUGTPuYFbqvrR4vpJ1BDdTlthFgvHt5kEdnd1+pdvwWphWn57/oIl4V72NMmOocFqqJ8mFFhA==", + "dev": true, + "requires": { + "JSONStream": "^1.0.4", + "is-text-path": "^1.0.1", + "lodash": "^4.17.15", + "meow": "^7.0.0", + "split2": "^2.0.0", + "through2": "^3.0.0", + "trim-off-newlines": "^1.0.0" + }, + "dependencies": { + "through2": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", + "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "2 || 3" + } + } + } + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "core-js": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz", + "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "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" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "dev": true + }, + "cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "requires": { + "cssom": "~0.3.6" + }, + "dependencies": { + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + } + } + }, + "dargs": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", + "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", + "dev": true + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "dev": true, + "requires": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + } + }, + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decamelize-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", + "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "dev": true, + "requires": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + } + } + }, + "decimal.js": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz", + "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true + }, + "diff-sequences": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", + "dev": true + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "dev": true, + "requires": { + "webidl-conversions": "^5.0.0" + }, + "dependencies": { + "webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "dev": true + } + } + }, + "dot-prop": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz", + "integrity": "sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==", + "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", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "emittery": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", + "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.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" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "dev": true, + "requires": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "eslint": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.14.0.tgz", + "integrity": "sha512-5YubdnPXrlrYAFCKybPuHIAH++PINe1pmKNc5wQRB9HSbqIK1ywAnntE3Wwua4giKu0bjligf1gLF6qxMGOYRA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@eslint/eslintrc": "^0.2.1", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.0", + "esquery": "^1.2.0", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash": "^4.17.19", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "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.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "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 + }, + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + }, + "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 + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "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" + } + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + } + } + }, + "eslint-config-prettier": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.15.0.tgz", + "integrity": "sha512-a1+kOYLR8wMGustcgAjdydMsQ2A/2ipRPwRKUmfYaSxc9ZPcrku080Ctl6zrZzZNs/U82MjSv+qKREkoq3bJaw==", + "dev": true, + "requires": { + "get-stdin": "^6.0.0" + } + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", + "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "dev": true + }, + "espree": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.0.tgz", + "integrity": "sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw==", + "dev": true, + "requires": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.3.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", + "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "exec-sh": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", + "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==", + "dev": true + }, + "execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "expect": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-regex-util": "^26.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-glob": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", + "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fastq": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.9.0.tgz", + "integrity": "sha512-i7FVWL8HhVY+CTkwFxkN2mk3h+787ixS5S63eb78diVRc1MCssarHq3W5cj0av7YDSwmaV928RNag+U1etRQ7w==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "dev": true, + "requires": { + "bser": "2.1.1" + } + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "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" + } + }, + "find-versions": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-3.2.0.tgz", + "integrity": "sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww==", + "dev": true, + "requires": { + "semver-regex": "^2.0.0" + } + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + }, + "dependencies": { + "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" + } + } + } + }, + "flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "dev": true + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fs-extra": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", + "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", + "dev": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^1.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.2.0.tgz", + "integrity": "sha512-pKnaUh2TNvk+/egJdBw1h46LwyLx8BzEq+MGCf/RMCVfEHHsGOCWG00dqk91kUPPArIIwMBg9T/virxwzP03cA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", + "dev": true + }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true + }, + "get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true + }, + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "git-raw-commits": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.7.tgz", + "integrity": "sha512-SkwrTqrDxw8y0G1uGJ9Zw13F7qu3LF8V4BifyDeiJCxSnjRGZD9SaoMiMqUvvXMXh6S3sOQ1DsBN7L2fMUZW/g==", + "dev": true, + "requires": { + "dargs": "^7.0.0", + "lodash.template": "^4.0.2", + "meow": "^7.0.0", + "split2": "^2.0.0", + "through2": "^3.0.0" + }, + "dependencies": { + "through2": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", + "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "2 || 3" + } + } + } + }, + "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" + } + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "globby": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", + "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "dependencies": { + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + } + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "dev": true, + "optional": true + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "dev": true, + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + } + }, + "hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "dev": true, + "requires": { + "whatwg-encoding": "^1.0.5" + } + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true + }, + "husky": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/husky/-/husky-4.3.0.tgz", + "integrity": "sha512-tTMeLCLqSBqnflBZnlVDhpaIMucSGaYyX6855jM4AguGeWCeSzNdb1mfyWduTZ3pe3SJVvVWGL0jO1iKZVPfTA==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "ci-info": "^2.0.0", + "compare-versions": "^3.6.0", + "cosmiconfig": "^7.0.0", + "find-versions": "^3.2.0", + "opencollective-postinstall": "^2.0.2", + "pkg-dir": "^4.2.0", + "please-upgrade-node": "^3.2.0", + "slash": "^3.0.0", + "which-pm-runs": "^1.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "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" + } + } + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "import-fresh": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", + "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "import-local": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "dev": true + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.0.0.tgz", + "integrity": "sha512-jq1AH6C8MuteOoBPwkxHafmByhL9j5q4OaPGdbuD+ZtQJVzH+i6E3BJDQcBA09k57i2Hh2yQbEG8yObZ0jdlWw==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-docker": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.1.1.tgz", + "integrity": "sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw==", + "dev": true, + "optional": true + }, + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "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", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "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": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-potential-custom-element-name": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz", + "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=", + "dev": true + }, + "is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", + "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-text-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", + "integrity": "sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4=", + "dev": true, + "requires": { + "text-extensions": "^1.0.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "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 + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "optional": true, + "requires": { + "is-docker": "^2.0.0" + } + }, + "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", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "requires": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + } + }, + "istanbul-reports": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jest": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest/-/jest-26.6.3.tgz", + "integrity": "sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==", + "dev": true, + "requires": { + "@jest/core": "^26.6.3", + "import-local": "^3.0.2", + "jest-cli": "^26.6.3" + } + }, + "jest-changed-files": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.6.2.tgz", + "integrity": "sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "execa": "^4.0.0", + "throat": "^5.0.0" + } + }, + "jest-cli": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz", + "integrity": "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==", + "dev": true, + "requires": { + "@jest/core": "^26.6.3", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "is-ci": "^2.0.0", + "jest-config": "^26.6.3", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "prompts": "^2.0.1", + "yargs": "^15.4.1" + }, + "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.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-config": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", + "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^26.6.3", + "@jest/types": "^26.6.2", + "babel-jest": "^26.6.3", + "chalk": "^4.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^26.6.2", + "jest-environment-node": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-jasmine2": "^26.6.3", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2" + }, + "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.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-diff": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-docblock": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", + "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", + "dev": true, + "requires": { + "detect-newline": "^3.0.0" + } + }, + "jest-each": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", + "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "jest-get-type": "^26.3.0", + "jest-util": "^26.6.2", + "pretty-format": "^26.6.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-environment-jsdom": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz", + "integrity": "sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==", + "dev": true, + "requires": { + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2", + "jsdom": "^16.4.0" + } + }, + "jest-environment-node": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.2.tgz", + "integrity": "sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==", + "dev": true, + "requires": { + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" + } + }, + "jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "dev": true + }, + "jest-haste-map": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", + "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-regex-util": "^26.0.0", + "jest-serializer": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7" + } + }, + "jest-jasmine2": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz", + "integrity": "sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==", + "dev": true, + "requires": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^26.6.2", + "@jest/source-map": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^26.6.2", + "is-generator-fn": "^2.0.0", + "jest-each": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-runtime": "^26.6.3", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "pretty-format": "^26.6.2", + "throat": "^5.0.0" + }, + "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.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-leak-detector": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz", + "integrity": "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==", + "dev": true, + "requires": { + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + } + }, + "jest-matcher-utils": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-message-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "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.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-mock": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*" + } + }, + "jest-pnp-resolver": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "dev": true + }, + "jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true + }, + "jest-resolve": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", + "read-pkg-up": "^7.0.1", + "resolve": "^1.18.1", + "slash": "^3.0.0" + }, + "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.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-resolve-dependencies": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz", + "integrity": "sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-snapshot": "^26.6.2" + } + }, + "jest-runner": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz", + "integrity": "sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==", + "dev": true, + "requires": { + "@jest/console": "^26.6.2", + "@jest/environment": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.7.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-config": "^26.6.3", + "jest-docblock": "^26.0.0", + "jest-haste-map": "^26.6.2", + "jest-leak-detector": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", + "jest-runtime": "^26.6.3", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "source-map-support": "^0.5.6", + "throat": "^5.0.0" + }, + "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.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-runtime": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz", + "integrity": "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==", + "dev": true, + "requires": { + "@jest/console": "^26.6.2", + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/globals": "^26.6.2", + "@jest/source-map": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0", + "cjs-module-lexer": "^0.6.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-config": "^26.6.3", + "jest-haste-map": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.4.1" + }, + "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.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-serializer": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", + "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", + "dev": true, + "requires": { + "@types/node": "*", + "graceful-fs": "^4.2.4" + } + }, + "jest-snapshot": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", + "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0", + "@jest/types": "^26.6.2", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.0.0", + "chalk": "^4.0.0", + "expect": "^26.6.2", + "graceful-fs": "^4.2.4", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-haste-map": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", + "natural-compare": "^1.4.0", + "pretty-format": "^26.6.2", + "semver": "^7.3.2" + }, + "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.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-validate": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", + "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "camelcase": "^6.0.0", + "chalk": "^4.0.0", + "jest-get-type": "^26.3.0", + "leven": "^3.1.0", + "pretty-format": "^26.6.2" + }, + "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" + } + }, + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-watcher": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz", + "integrity": "sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==", + "dev": true, + "requires": { + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^26.6.2", + "string-length": "^4.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "dependencies": { + "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" + } + } + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "jsdom": { + "version": "16.4.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.4.0.tgz", + "integrity": "sha512-lYMm3wYdgPhrl7pDcRmvzPhhrGVBeVhPIqeHjzeiHN3DFmD1RBpbExbi8vU7BJdH8VAZYovR8DMt0PNNDM7k8w==", + "dev": true, + "requires": { + "abab": "^2.0.3", + "acorn": "^7.1.1", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.2.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.0", + "domexception": "^2.0.1", + "escodegen": "^1.14.1", + "html-encoding-sniffer": "^2.0.1", + "is-potential-custom-element-name": "^1.0.0", + "nwsapi": "^2.2.0", + "parse5": "5.1.1", + "request": "^2.88.2", + "request-promise-native": "^1.0.8", + "saxes": "^5.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^3.0.1", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0", + "ws": "^7.2.3", + "xml-name-validator": "^3.0.0" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "jsonfile": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", + "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^1.0.0" + } + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "dev": true + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "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 + }, + "lint-staged": { + "version": "10.5.2", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-10.5.2.tgz", + "integrity": "sha512-e8AYR1TDlzwB8VVd38Xu2lXDZf6BcshVqKVuBQThDJRaJLobqKnpbm4dkwJ2puypQNbLr9KF/9mfA649mAGvjA==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "cli-truncate": "^2.1.0", + "commander": "^6.2.0", + "cosmiconfig": "^7.0.0", + "debug": "^4.2.0", + "dedent": "^0.7.0", + "enquirer": "^2.3.6", + "execa": "^4.1.0", + "listr2": "^3.2.2", + "log-symbols": "^4.0.0", + "micromatch": "^4.0.2", + "normalize-path": "^3.0.0", + "please-upgrade-node": "^3.2.0", + "string-argv": "0.3.1", + "stringify-object": "^3.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "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" + } + } + } + }, + "listr2": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.2.3.tgz", + "integrity": "sha512-vUb80S2dSUi8YxXahO8/I/s29GqnOL8ozgHVLjfWQXa03BNEeS1TpBLjh2ruaqq5ufx46BRGvfymdBSuoXET5w==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "cli-truncate": "^2.1.0", + "figures": "^3.2.0", + "indent-string": "^4.0.0", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rxjs": "^6.6.3", + "through": "^2.3.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.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "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" + } + } + } + }, + "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" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", + "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.template": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", + "dev": true, + "requires": { + "lodash._reinterpolate": "^3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "lodash.templatesettings": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "dev": true, + "requires": { + "lodash._reinterpolate": "^3.0.0" + } + }, + "log-symbols": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "dev": true, + "requires": { + "chalk": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "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" + } + } + } + }, + "log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "requires": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + } + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "dev": true, + "requires": { + "tmpl": "1.0.x" + } + }, + "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": "4.1.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.1.0.tgz", + "integrity": "sha512-glc9y00wgtwcDmp7GaE/0b0OnxpNJsVf3ael/An6Fe2Q51LLwN1er6sdomLRzz5h0+yMpiYLhWYF5R7HeqVd4g==", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "meow": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-7.1.1.tgz", + "integrity": "sha512-GWHvA5QOcS412WCo8vwKDlTelGLsCGBVevQB5Kva961rmNfun0PCbv5+xta2kUMFJyR8/oWnn7ddeKdosbAPbA==", + "dev": true, + "requires": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^2.5.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.13.1", + "yargs-parser": "^18.1.3" + }, + "dependencies": { + "type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "dev": true + } + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", + "dev": true + }, + "mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "dev": true, + "requires": { + "mime-db": "1.44.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + } + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "dev": true + }, + "node-notifier": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.0.tgz", + "integrity": "sha512-46z7DUmcjoYdaWyXouuFNNfUo6eFa94t23c53c+lG/9Cvauk4a98rAUp9672X5dxGdQmLpPzTxzu8f/OeEPaFA==", + "dev": true, + "optional": true, + "requires": { + "growly": "^1.3.0", + "is-wsl": "^2.2.0", + "semver": "^7.3.2", + "shellwords": "^0.1.1", + "uuid": "^8.3.0", + "which": "^2.0.2" + }, + "dependencies": { + "uuid": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.1.tgz", + "integrity": "sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg==", + "dev": true, + "optional": true + } + } + }, + "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" + }, + "dependencies": { + "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==", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "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 + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.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", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "opencollective-postinstall": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz", + "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==", + "dev": true + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "p-each-series": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.1.0.tgz", + "integrity": "sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ==", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "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-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "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", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, + "pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "dev": true, + "requires": { + "node-modules-regexp": "^1.0.0" + } + }, + "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" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + } + } + }, + "please-upgrade-node": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", + "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", + "dev": true, + "requires": { + "semver-compare": "^1.0.0" + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "prettier": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", + "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", + "dev": true + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "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 + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "prompts": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.0.tgz", + "integrity": "sha512-awZAKrk3vN6CroQukBL+R9051a4R3zCZBlJm/HBfrSZ8iTpYix3VX1vU4mveiLpiwmOJT4wokTF9m6HUk4KqWQ==", + "dev": true, + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + } + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "react-is": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", + "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", + "dev": true + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, + "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" + }, + "dependencies": { + "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" + } + } + } + }, + "redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "requires": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + } + }, + "regenerator-runtime": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", + "dev": true + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "dev": true + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + } + } + }, + "request-promise-core": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", + "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", + "dev": true, + "requires": { + "lodash": "^4.17.19" + } + }, + "request-promise-native": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", + "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", + "dev": true, + "requires": { + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + } + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "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.18.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.18.1.tgz", + "integrity": "sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA==", + "dev": true, + "requires": { + "is-core-module": "^2.0.0", + "path-parse": "^1.0.6" + } + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } + } + }, + "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 + }, + "resolve-global": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-global/-/resolve-global-1.0.0.tgz", + "integrity": "sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==", + "dev": true, + "requires": { + "global-dirs": "^0.1.1" + }, + "dependencies": { + "global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "dev": true, + "requires": { + "ini": "^1.3.4" + } + } + } + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "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" + } + }, + "rsvp": { + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", + "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", + "dev": true + }, + "run-parallel": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.10.tgz", + "integrity": "sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw==", + "dev": true + }, + "rxjs": { + "version": "6.6.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.3.tgz", + "integrity": "sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sane": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", + "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", + "dev": true, + "requires": { + "@cnakazawa/watch": "^1.0.3", + "anymatch": "^2.0.0", + "capture-exit": "^2.0.0", + "exec-sh": "^0.3.2", + "execa": "^1.0.0", + "fb-watchman": "^2.0.0", + "micromatch": "^3.1.4", + "minimist": "^1.1.1", + "walker": "~1.0.5" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "dev": true, + "requires": { + "xmlchars": "^2.2.0" + } + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + }, + "semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", + "dev": true + }, + "semver-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-2.0.0.tgz", + "integrity": "sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw==", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + } + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "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 + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "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 + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "split2": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz", + "integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==", + "dev": true, + "requires": { + "through2": "^2.0.2" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + } + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true + }, + "string-argv": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", + "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", + "dev": true + }, + "string-length": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.1.tgz", + "integrity": "sha512-PKyXUd0LK0ePjSOnWn34V2uD6acUWev9uy0Ft05k0E8xRW+SKcA0F7eMr7h5xlzfn+4O3N+55rduYyet3Jk+jw==", + "dev": true, + "requires": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + } + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dev": true, + "requires": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "dependencies": { + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + } + } + }, + "strip-ansi": { + "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": "^5.0.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, + "strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "requires": { + "min-indent": "^1.0.0" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "supports-hyperlinks": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz", + "integrity": "sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA==", + "dev": true, + "requires": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "dependencies": { + "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" + } + } + } + }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "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 + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, + "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 + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + } + }, + "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" + } + } + } + }, + "terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "text-extensions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", + "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", + "dev": true + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "throat": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "tmpl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "tough-cookie": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", + "dev": true, + "requires": { + "ip-regex": "^2.1.0", + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "tr46": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz", + "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==", + "dev": true, + "requires": { + "punycode": "^2.1.1" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "trim-newlines": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.0.tgz", + "integrity": "sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA==", + "dev": true + }, + "trim-off-newlines": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz", + "integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=", + "dev": true + }, + "ts-jest": { + "version": "26.4.4", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.4.4.tgz", + "integrity": "sha512-3lFWKbLxJm34QxyVNNCgXX1u4o/RV0myvA2y2Bxm46iGIjKlaY0own9gIckbjZJPn+WaJEnfPPJ20HHGpoq4yg==", + "dev": true, + "requires": { + "@types/jest": "26.x", + "bs-logger": "0.x", + "buffer-from": "1.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^26.1.0", + "json5": "2.x", + "lodash.memoize": "4.x", + "make-error": "1.x", + "mkdirp": "1.x", + "semver": "7.x", + "yargs-parser": "20.x" + }, + "dependencies": { + "yargs-parser": { + "version": "20.2.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.3.tgz", + "integrity": "sha512-emOFRT9WVHw03QSvN5qor9QQT9+sw5vwxfYweivSMHTcAXPefwVae2FjO7JJjj8hCE4CzPOPeFM83VwT29HCww==", + "dev": true + } + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "tsutils": { + "version": "3.17.1", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", + "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "typescript": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.2.tgz", + "integrity": "sha512-thGloWsGH3SOxv1SoY7QojKi0tc+8FnOmiarEGMbd/lar7QOEd3hvlx3Fp5y6FlDUGl9L+pd4n2e+oToGMmhRQ==", + "dev": true + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + } + } + }, + "universalify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", + "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==", + "dev": true + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "uri-js": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", + "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + }, + "v8-compile-cache": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz", + "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==", + "dev": true + }, + "v8-to-istanbul": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.0.0.tgz", + "integrity": "sha512-fLL2rFuQpMtm9r8hrAV2apXX/WqHJ6+IC4/eQVdMDGBUgH/YMV4Gv3duk3kjmyg6uiQWBAA9nJwue4iJUOkHeA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } + } + }, + "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" + } + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "dev": true, + "requires": { + "browser-process-hrtime": "^1.0.0" + } + }, + "w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "dev": true, + "requires": { + "xml-name-validator": "^3.0.0" + } + }, + "walker": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "dev": true, + "requires": { + "makeerror": "1.0.x" + } + }, + "webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "dev": true + }, + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "requires": { + "iconv-lite": "0.4.24" + } + }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, + "whatwg-url": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.4.0.tgz", + "integrity": "sha512-vwTUFf6V4zhcPkWp/4CQPr1TW9Ml6SF4lVyaIMBdJw5i6qUUJ1QWM4Z6YYVkfka0OUIzVo/0aNtGVGk256IKWw==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^2.0.2", + "webidl-conversions": "^6.1.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "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 + }, + "which-pm-runs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", + "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", + "dev": true + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + }, + "dependencies": { + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + } + } + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "ws": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz", + "integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==", + "dev": true + }, + "xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true + }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "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 + }, + "yaml": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz", + "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==", + "dev": true + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.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": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..06bc093 --- /dev/null +++ b/package.json @@ -0,0 +1,75 @@ +{ + "name": "@coderbyheart/advent-of-code", + "version": "0.0.0-development", + "description": "Advent of Code 2020 solutions in TypeScript", + "scripts": { + "test": "jest" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/coderbyheart/aoc.git" + }, + "bugs": { + "url": "https://github.com/coderbyheart/aoc/issues" + }, + "homepage": "https://github.com/coderbyheart/aoc", + "keywords": [ + "Advent of Code", + "TypeScript", + "aoc2020" + ], + "author": "Markus Tacker | https://coderbyheart.com", + "license": "MIT", + "devDependencies": { + "@bifravst/code-style": "8.0.134", + "@bifravst/eslint-config-typescript": "5.0.79", + "@commitlint/cli": "11.0.0", + "@commitlint/config-angular": "11.0.0", + "@types/jest": "26.0.15", + "@types/node": "14.14.10", + "eslint": "^7.14.0", + "husky": "^4.3.0", + "jest": "26.6.3", + "lint-staged": "^10.5.2", + "prettier": "2.2.1", + "ts-jest": "26.4.4", + "typescript": "4.1.2" + }, + "husky": { + "hooks": { + "commit-msg": "commitlint -E HUSKY_GIT_PARAMS", + "pre-commit": "lint-staged && npx jest --onlyChanged" + } + }, + "lint-staged": { + "*.ts": [ + "prettier --write", + "eslint --ext .js,.ts" + ], + "*.{md,json,yaml,yml}": [ + "prettier --write" + ] + }, + "engines": { + "node": ">=14.0.0", + "npm": ">=6.0.0" + }, + "jest": { + "testURL": "http://localhost", + "moduleFileExtensions": [ + "ts", + "tsx", + "js", + "json" + ], + "transform": { + "^.+\\.tsx?$": "ts-jest" + }, + "testRegex": ".+\\.spec\\.ts$", + "globals": { + "ts-jest": { + "diagnostics": true + } + } + } +} diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..6e30f5d --- /dev/null +++ b/renovate.json @@ -0,0 +1,3 @@ +{ + "extends": ["github>bifravst/code-style"] +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..5e2a8bc --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "@bifravst/code-style/tsconfig.json", + "include": ["**/*.ts"], + "compilerOptions": { + "outDir": "dist/" + } +} From b39b72afd7f6ca2d7326a6275fad13db6d8bf312 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Tue, 1 Dec 2020 10:29:34 +0100 Subject: [PATCH 02/60] feat(day01): step 1 --- day01/day01.spec.ts | 20 ++++ day01/findEntriesWithSum.ts | 11 ++ day01/sample.txt | 6 ++ day01/step1.txt | 200 ++++++++++++++++++++++++++++++++++++ 4 files changed, 237 insertions(+) create mode 100644 day01/day01.spec.ts create mode 100644 day01/findEntriesWithSum.ts create mode 100644 day01/sample.txt create mode 100644 day01/step1.txt diff --git a/day01/day01.spec.ts b/day01/day01.spec.ts new file mode 100644 index 0000000..d15b4bc --- /dev/null +++ b/day01/day01.spec.ts @@ -0,0 +1,20 @@ +import { loader } from '../lib/loader' +import { findEntriesWithSum } from './findEntriesWithSum' + +const load = loader(1) + +const toInt = (s: string) => parseInt(s, 10) +const mul = (total: number, n: number) => n * total + +describe('Day 01: Expenses Report', () => { + it('should solve the sample', () => { + const sample = load('sample') + expect(findEntriesWithSum(sample.map(toInt), 2020)).toEqual([1721, 299]) + }) + it('should solve part 1', () => { + const part1 = load('step1') + expect(findEntriesWithSum(part1.map(toInt), 2020).reduce(mul, 1)).toEqual( + 982464, + ) + }) +}) diff --git a/day01/findEntriesWithSum.ts b/day01/findEntriesWithSum.ts new file mode 100644 index 0000000..b34fa74 --- /dev/null +++ b/day01/findEntriesWithSum.ts @@ -0,0 +1,11 @@ +export const findEntriesWithSum = ( + entries: number[], + expectedSum: number, +): number[] => { + for (const i of entries) { + for (const j of entries) { + if (i + j === expectedSum) return [i, j] + } + } + return [] +} diff --git a/day01/sample.txt b/day01/sample.txt new file mode 100644 index 0000000..0bb977d --- /dev/null +++ b/day01/sample.txt @@ -0,0 +1,6 @@ +1721 +979 +366 +299 +675 +1456 \ No newline at end of file diff --git a/day01/step1.txt b/day01/step1.txt new file mode 100644 index 0000000..71a40c2 --- /dev/null +++ b/day01/step1.txt @@ -0,0 +1,200 @@ +1864 +1880 +1300 +1961 +1577 +1900 +1307 +1818 +1736 +1846 +1417 +1372 +1351 +1860 +1738 +1525 +1798 +1218 +1723 +1936 +1725 +1998 +1466 +1922 +1782 +1947 +1717 +1914 +1843 +1732 +1918 +814 +1771 +1712 +1804 +1213 +1859 +1820 +1793 +1870 +1993 +1787 +1824 +1849 +1646 +1489 +1348 +1978 +1628 +1781 +2002 +1297 +1829 +1596 +1819 +1313 +1413 +1726 +1449 +1810 +1295 +1679 +1358 +1949 +1644 +1825 +1891 +490 +1962 +1939 +1228 +1889 +1977 +1980 +1763 +1752 +1983 +1785 +1678 +2000 +1857 +1658 +1863 +1330 +1380 +1799 +1789 +1633 +1663 +296 +1985 +1117 +1239 +1854 +1960 +2004 +1940 +1876 +1739 +1858 +1283 +1423 +1982 +1836 +1451 +1840 +1347 +1652 +1695 +1210 +1861 +1199 +1346 +1786 +1814 +1958 +1853 +1974 +1917 +1308 +654 +1743 +1847 +1367 +1559 +1614 +1897 +2003 +1886 +1885 +1682 +1204 +1986 +1816 +1994 +1817 +1751 +1701 +1619 +1970 +816 +1852 +1832 +1631 +703 +1604 +1444 +1842 +1984 +1259 +1948 +1620 +1681 +1822 +1865 +1521 +1741 +1455 +1909 +1764 +261 +1464 +1905 +1325 +1766 +1749 +1292 +1874 +1267 +1269 +1969 +1991 +1219 +1345 +1976 +1369 +1942 +1388 +1776 +1629 +1987 +1684 +1813 +1203 +1965 +1729 +1930 +1609 +1801 +1402 +121 +1833 +1898 +1957 +1051 +1430 +1893 +1784 +1800 +1910 \ No newline at end of file From bf57fc8d9bcfddcd798d74998c16105141781a07 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Tue, 1 Dec 2020 22:36:50 +0100 Subject: [PATCH 03/60] fix: update dependencies --- day01/day01.spec.ts | 32 ++++++++++++++++++++++++-------- day01/findEntriesWithSum.ts | 17 ++++++++--------- day01/{step1.txt => input.txt} | 0 lib/combine.ts | 21 +++++++++++++++++++++ package-lock.json | 6 +++--- package.json | 2 +- 6 files changed, 57 insertions(+), 21 deletions(-) rename day01/{step1.txt => input.txt} (100%) create mode 100644 lib/combine.ts diff --git a/day01/day01.spec.ts b/day01/day01.spec.ts index d15b4bc..b60772d 100644 --- a/day01/day01.spec.ts +++ b/day01/day01.spec.ts @@ -2,19 +2,35 @@ import { loader } from '../lib/loader' import { findEntriesWithSum } from './findEntriesWithSum' const load = loader(1) +const sample = load('sample') +const input = load('input') const toInt = (s: string) => parseInt(s, 10) const mul = (total: number, n: number) => n * total describe('Day 01: Expenses Report', () => { - it('should solve the sample', () => { - const sample = load('sample') - expect(findEntriesWithSum(sample.map(toInt), 2020)).toEqual([1721, 299]) + describe('Part 1', () => { + it('should solve the sample', () => { + expect( + findEntriesWithSum(2)(sample.map(toInt), 2020).reduce(mul, 1), + ).toEqual(1721 * 299) + }) + it('should solve', () => { + expect( + findEntriesWithSum(2)(input.map(toInt), 2020).reduce(mul, 1), + ).toEqual(982464) + }) }) - it('should solve part 1', () => { - const part1 = load('step1') - expect(findEntriesWithSum(part1.map(toInt), 2020).reduce(mul, 1)).toEqual( - 982464, - ) + describe('Part 2', () => { + it('should solve the sample', () => { + expect( + findEntriesWithSum(3)(sample.map(toInt), 2020).reduce(mul, 1), + ).toEqual(979 * 366 * 675) + }) + it('should solve', () => { + expect( + findEntriesWithSum(3)(input.map(toInt), 2020).reduce(mul, 1), + ).toEqual(162292410) + }) }) }) diff --git a/day01/findEntriesWithSum.ts b/day01/findEntriesWithSum.ts index b34fa74..ab94b84 100644 --- a/day01/findEntriesWithSum.ts +++ b/day01/findEntriesWithSum.ts @@ -1,11 +1,10 @@ -export const findEntriesWithSum = ( +import { combine } from '../lib/combine' + +const sum = (total: number, n: number) => n + total + +export const findEntriesWithSum = (numEntries: number) => ( entries: number[], expectedSum: number, -): number[] => { - for (const i of entries) { - for (const j of entries) { - if (i + j === expectedSum) return [i, j] - } - } - return [] -} +): number[] => + combine(entries, numEntries).find((e) => e.reduce(sum, 0) === expectedSum) ?? + [] diff --git a/day01/step1.txt b/day01/input.txt similarity index 100% rename from day01/step1.txt rename to day01/input.txt diff --git a/lib/combine.ts b/lib/combine.ts new file mode 100644 index 0000000..7d9d2cd --- /dev/null +++ b/lib/combine.ts @@ -0,0 +1,21 @@ +/** + * Creates combinations of a with length n + */ +export const combine = ( + arr: number[], + numEntries: number, + combinations: number[][] = [], + remaining: number[] = [], +): number[][] => + arr.reduce((p, c, i, a) => { + numEntries > 1 + ? combine( + a.slice(i + 1), + numEntries - 1, + p, + (remaining.push(c), remaining), + ) + : p.push((remaining.push(c), remaining).slice(0)) + remaining.pop() + return p + }, combinations) diff --git a/package-lock.json b/package-lock.json index 29b86d3..49c1fbb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1412,9 +1412,9 @@ } }, "@types/jest": { - "version": "26.0.15", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.15.tgz", - "integrity": "sha512-s2VMReFXRg9XXxV+CW9e5Nz8fH2K1aEhwgjUqPPbQd7g95T0laAcvLv032EhFHIa5GHsZ8W7iJEQVaJq6k3Gog==", + "version": "26.0.16", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.16.tgz", + "integrity": "sha512-Gp12+7tmKCgv9JjtltxUXokohCAEZfpJaEW5tn871SGRp8I+bRWBonQO7vW5NHwnAHe5dd50+Q4zyKuN35i09g==", "dev": true, "requires": { "jest-diff": "^26.0.0", diff --git a/package.json b/package.json index 06bc093..cd9d16d 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "@bifravst/eslint-config-typescript": "5.0.79", "@commitlint/cli": "11.0.0", "@commitlint/config-angular": "11.0.0", - "@types/jest": "26.0.15", + "@types/jest": "26.0.16", "@types/node": "14.14.10", "eslint": "^7.14.0", "husky": "^4.3.0", From 51a867f414804f4a95b92fc240298547889640a7 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Tue, 1 Dec 2020 22:45:50 +0100 Subject: [PATCH 04/60] docs: fix repo url --- README.md | 8 ++++---- package.json | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 3b0e78e..fb13f81 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@ # Advent of Code 2020 solutions in TypeScript -[![GitHub Actions](https://github.com/coderbyheart/aoc/workflows/Test/badge.svg)](https://github.com/coderbyheart/aoc/actions) -[![Known Vulnerabilities](https://snyk.io/test/github/coderbyheart/aoc/badge.svg)](https://snyk.io/test/github/coderbyheart/aoc) +[![GitHub Actions](https://github.com/coderbyheart/adventofcode/workflows/Test/badge.svg)](https://github.com/coderbyheart/adventofcode/actions) +[![Known Vulnerabilities](https://snyk.io/test/github/coderbyheart/adventofcode/badge.svg)](https://snyk.io/test/github/coderbyheart/adventofcode) [![Renovate](https://img.shields.io/badge/renovate-enabled-brightgreen.svg)](https://renovatebot.com) -[![Mergify Status](https://img.shields.io/endpoint.svg?url=https://dashboard.mergify.io/badges/coderbyheart/aoc&style=flat)](https://mergify.io) +[![Mergify Status](https://img.shields.io/endpoint.svg?url=https://dashboard.mergify.io/badges/coderbyheart/adventofcode&style=flat)](https://mergify.io) [![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/) [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier/) [![ESLint: TypeScript](https://img.shields.io/badge/ESLint-TypeScript-blue.svg)](https://github.com/typescript-eslint/typescript-eslint) - git clone https://github.com/coderbyheart/aoc + git clone https://github.com/coderbyheart/adventofcode npm ci npm test diff --git a/package.json b/package.json index cd9d16d..a60e6fb 100644 --- a/package.json +++ b/package.json @@ -7,12 +7,12 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/coderbyheart/aoc.git" + "url": "git+https://github.com/coderbyheart/adventofcode.git" }, "bugs": { - "url": "https://github.com/coderbyheart/aoc/issues" + "url": "https://github.com/coderbyheart/adventofcode/issues" }, - "homepage": "https://github.com/coderbyheart/aoc", + "homepage": "https://github.com/coderbyheart/adventofcode", "keywords": [ "Advent of Code", "TypeScript", From 13243a70e7f5d48ca4802bd548184a608f5c7e6d Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Tue, 1 Dec 2020 23:53:15 +0100 Subject: [PATCH 05/60] refactor: re-implement combine to improve readability --- day01/findEntriesWithSum.ts | 7 ++++--- lib/combine.ts | 21 -------------------- lib/uniqueCombinations.spec.ts | 35 ++++++++++++++++++++++++++++++++++ lib/uniqueCombinations.ts | 25 ++++++++++++++++++++++++ 4 files changed, 64 insertions(+), 24 deletions(-) delete mode 100644 lib/combine.ts create mode 100644 lib/uniqueCombinations.spec.ts create mode 100644 lib/uniqueCombinations.ts diff --git a/day01/findEntriesWithSum.ts b/day01/findEntriesWithSum.ts index ab94b84..de64179 100644 --- a/day01/findEntriesWithSum.ts +++ b/day01/findEntriesWithSum.ts @@ -1,4 +1,4 @@ -import { combine } from '../lib/combine' +import { uniqueCombinations } from '../lib/uniqueCombinations' const sum = (total: number, n: number) => n + total @@ -6,5 +6,6 @@ export const findEntriesWithSum = (numEntries: number) => ( entries: number[], expectedSum: number, ): number[] => - combine(entries, numEntries).find((e) => e.reduce(sum, 0) === expectedSum) ?? - [] + uniqueCombinations(numEntries)(entries).find( + (e) => e.reduce(sum, 0) === expectedSum, + ) ?? [] diff --git a/lib/combine.ts b/lib/combine.ts deleted file mode 100644 index 7d9d2cd..0000000 --- a/lib/combine.ts +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Creates combinations of a with length n - */ -export const combine = ( - arr: number[], - numEntries: number, - combinations: number[][] = [], - remaining: number[] = [], -): number[][] => - arr.reduce((p, c, i, a) => { - numEntries > 1 - ? combine( - a.slice(i + 1), - numEntries - 1, - p, - (remaining.push(c), remaining), - ) - : p.push((remaining.push(c), remaining).slice(0)) - remaining.pop() - return p - }, combinations) diff --git a/lib/uniqueCombinations.spec.ts b/lib/uniqueCombinations.spec.ts new file mode 100644 index 0000000..c6fa97e --- /dev/null +++ b/lib/uniqueCombinations.spec.ts @@ -0,0 +1,35 @@ +import { uniqueCombinations } from './uniqueCombinations' + +const seq = [2, 3, 5, 7] +describe('uniqueCombinations', () => { + it.each([ + [0, seq, []], + [1, seq, [[2], [3], [5], [7]]], + [ + 2, + seq, + [ + [2, 3], + [2, 5], + [2, 7], + [3, 5], + [3, 7], + [5, 7], + ], + ], + [ + 3, + seq, + [ + [2, 3, 5], + [2, 3, 7], + [2, 5, 7], + [3, 5, 7], + ], + ], + [4, seq, [[2, 3, 5, 7]]], + [5, seq, []], + ])('combinations of length %d', (length, items, expected) => + expect(uniqueCombinations(length)(items)).toEqual(expected), + ) +}) diff --git a/lib/uniqueCombinations.ts b/lib/uniqueCombinations.ts new file mode 100644 index 0000000..4e5f2a5 --- /dev/null +++ b/lib/uniqueCombinations.ts @@ -0,0 +1,25 @@ +/** + * Returns a list of unique combinations of length n of the items + */ +export const uniqueCombinations = (len: number) => (items: T[]): T[][] => { + // Trivial case: only one item per combination + if (len === 1) return items.map((i) => [i]) + // Otherwise: go over all items in the list ... + return items.reduce((combinations, item, i) => { + // ... and combine it with the remaining entries in the list + const pairs = uniqueCombinations( + // which means the list will be one item less + len - 1, + )( + // and starts from the next entry in the list + items.slice(i + 1), + ) + // which is all previous entries + combinations.push( + // and this element, combined with all found pairs + ...pairs.map((p) => [item, ...p]), + ) + // Return the result + return combinations + }, [] as T[][]) +} From 4cefc4c4137f1160c12c97bc21d44a9c850c0bdb Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Wed, 2 Dec 2020 09:35:51 +0100 Subject: [PATCH 06/60] refactor: rename files --- day01/{day01.spec.ts => solution.spec.ts} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename day01/{day01.spec.ts => solution.spec.ts} (95%) diff --git a/day01/day01.spec.ts b/day01/solution.spec.ts similarity index 95% rename from day01/day01.spec.ts rename to day01/solution.spec.ts index b60772d..e9b2c2d 100644 --- a/day01/day01.spec.ts +++ b/day01/solution.spec.ts @@ -8,7 +8,7 @@ const input = load('input') const toInt = (s: string) => parseInt(s, 10) const mul = (total: number, n: number) => n * total -describe('Day 01: Expenses Report', () => { +describe('Day 1: Report Repair', () => { describe('Part 1', () => { it('should solve the sample', () => { expect( From 2f8889c5ee56c71f56f529d6413d1f1db31e2f71 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Wed, 2 Dec 2020 09:37:00 +0100 Subject: [PATCH 07/60] feat(day02): step 1 --- day02/findValidPasswords.ts | 29 + day02/input.txt | 1000 +++++++++++++++++++++++++++++++++++ day02/sample.txt | 3 + day02/solution.spec.ts | 17 + 4 files changed, 1049 insertions(+) create mode 100644 day02/findValidPasswords.ts create mode 100644 day02/input.txt create mode 100644 day02/sample.txt create mode 100644 day02/solution.spec.ts diff --git a/day02/findValidPasswords.ts b/day02/findValidPasswords.ts new file mode 100644 index 0000000..4da6e29 --- /dev/null +++ b/day02/findValidPasswords.ts @@ -0,0 +1,29 @@ +const policyAndPasswordsLine = new RegExp( + /^(?[0-9]+)-(?[0-9]+) (?[a-z]): (?[a-z]+)$/, +) + +const containsChar = ( + s: string, + char: string, + min: number, + max: number, +): boolean => { + const numChars = s.split('').filter((s) => s === char).length + return numChars >= min && numChars <= max +} + +export const findValidPasswords = (policyAndPasswords: string[]): number => + policyAndPasswords.reduce((count, s) => { + const { minChars, maxChars, char, password } = + policyAndPasswordsLine.exec(s)?.groups ?? {} + if ( + containsChar( + password, + char, + parseInt(minChars, 10), + parseInt(maxChars, 10), + ) + ) + return count + 1 + return count + }, 0) diff --git a/day02/input.txt b/day02/input.txt new file mode 100644 index 0000000..ebd0c1b --- /dev/null +++ b/day02/input.txt @@ -0,0 +1,1000 @@ +15-16 l: klfbblslvjclmlnqklvg +6-13 h: pghjchdxhnjhjd +4-13 n: nnznntzznqnzbtzj +10-16 r: nrrrrkrjtxwrrrwx +1-6 t: rttftttttttttmdttttt +4-12 l: zhllfxlmvqtnhx +6-8 d: wxpwgdbjtffddkb +7-9 q: rqcqxjqhsm +6-8 x: xxxfxdxxx +5-9 d: dwnwnbsddfmc +2-6 j: jvdrrjchml +8-10 x: xxxcxxxzxxxxx +15-16 f: ffffffffffffffnfc +3-12 v: vgvvvvvvvvfqvvvv +2-5 p: tknppm +11-12 r: frrnrfqtshrgw +13-16 f: rfjmkrqkqrxmfnqj +3-5 f: ffffxffn +2-4 f: fffwf +11-13 s: srslssshssssx +1-6 c: cccdcn +2-6 t: tthhnc +12-17 w: wwwwwwwwwwwmwwwwg +5-6 k: kqkksskkp +4-5 p: ppppx +5-12 h: hbjhqhdwnqxhhsh +6-8 p: ppgzpppw +3-4 z: zzcz +6-15 x: hfvxxsqbfxxlhpxtb +4-7 m: qmxzhgt +18-20 b: fvzbbrbcvskxrpkwnmwb +1-11 c: ccccccccccggccc +1-3 p: dppp +2-6 j: fjbmljmdb +2-4 l: slpmqpk +3-5 b: stbpbbndtgzxlsnbdk +6-11 h: hlzkdhhhrhchmhbhl +1-4 w: wwpv +10-12 p: pmpppkpppgph +11-14 f: fbdxffpffffffkfffjvf +4-9 v: vkvfhfvvrvvv +16-17 t: tmtbztrptdlvttvkt +2-6 w: wwwwphwwwwnwwj +6-11 x: xxxxxxxxxxkxx +9-10 t: ttftchttnd +2-9 w: wkwwwwwwlww +2-4 g: ggvcgggggggggg +5-6 d: dldddsddddddd +5-8 j: jddjjnld +9-12 l: xldxlklvlkll +2-3 w: xwnrwdwndlvl +16-18 m: mmmmrmmmmmrvvmmvmm +3-4 t: ctts +11-12 b: ndgjdbppcdbhhssw +2-11 s: nssksssnssxvq +2-5 g: qggwcvf +10-14 l: llxlllrjlmlllwllll +8-9 w: wwwwfpwtvtjwjw +8-10 m: mmmmmmmmmmm +1-11 z: rldjzzzpzzs +16-17 v: qvsrnvvvwxgmvjjcvhcx +14-18 k: kkkkkkkkkkkkkkkkklk +2-3 q: qqrqqqxqqqq +4-9 c: lclckhcgn +2-3 b: nbbbbldlbbb +15-18 v: vtvvrvxvvnvxhvnvvv +4-7 q: qqqnqqqq +3-13 j: svjjdcnkwnbpl +4-11 q: blnqvqsngwj +3-4 j: dxdkj +5-7 c: dzxbsctqwclcgc +3-4 f: jfhffff +3-5 t: sttwk +7-8 t: tnqtvsztqwpvtftknt +1-12 r: grrrrrrrrrrrrrrr +7-8 k: kkkkkkqkk +3-4 l: llls +1-14 h: khhhjhhhhhhhhh +3-5 d: ttcdddd +1-7 w: dqwhwkww +4-5 p: pppqppppp +10-14 l: lqlltwlllllllzjk +15-17 d: ddddddddddddddddcdd +1-8 z: xpbbjxrzlzznxlz +1-2 v: vrvv +7-11 l: llllllclllslll +3-14 h: hhvhhhhhhhhhhhh +6-7 m: mmgpbjmgqmm +9-13 h: hhhhhhhhhhhhfnhhhhwh +12-17 c: cccpfcccccnccccqscc +6-12 x: kqfxbhxbdxxxl +6-8 z: zqkbtzzb +6-8 l: llllllllllllll +6-13 d: wdzdxdddddlzdtbd +3-8 h: gzcknrxkjgtggnqwqjs +1-6 t: tttttvtt +5-8 x: fjxnxrtn +6-9 z: zzzzzzzzszzz +2-4 v: vpvvtv +1-7 w: wcwrxgf +2-3 t: vxftld +1-2 n: nnxmntsqzk +5-11 l: nmvllllnlckl +7-13 c: cwchccjcrfsccc +2-3 z: dzdz +7-8 s: sddgbhws +3-11 w: qqsqrgmwwmwgfdhpsct +16-17 q: qqqqzqqqqqqqqqqqh +7-15 h: thqthdphmbhhjphhh +6-10 k: gcflljjwkk +9-17 f: ffffffffffffffffdf +10-12 q: qqqqbqlpqqfdqq +3-16 x: dbxmwtlqdmvldxlgxdhk +1-2 x: xxjxh +10-11 p: ppqpppkpptp +3-5 w: wwwwwwwww +10-11 j: xjmhqgdznjf +9-11 n: dxnnnnnnnnmnnn +1-5 l: mlllvllwlrblllll +14-16 q: tqqqqqqwqqqqqmqqqqq +2-3 b: nvbbbcf +5-8 x: xmkxxgxq +1-4 x: xxxfx +1-6 n: nnnrnm +9-17 p: pppppppppppppppppp +2-4 d: ddqd +13-14 p: fmpkxpprppppzhpp +5-6 t: tttttgrttt +10-12 r: rrrrrrrrrlrrrrrrrr +4-7 h: gnmqvqrhwhh +4-5 m: smsmmmm +4-5 q: qgzqb +6-12 c: rdnnsccnrjkcnm +4-16 k: gfkxktpwhxzkgcdnb +4-5 f: ffgvf +6-13 n: nfslcrnkksfmnmvcfnnz +15-18 s: sssqsssssmshmsmsss +1-15 v: vvvvwvvxvvvcvvwvvvvv +2-8 h: gphlnhph +4-13 t: vtjvrcxqwbsrk +2-10 t: tvttftzttttqttt +12-13 t: dvsbstlkfpztdqs +7-8 w: rvwncwww +13-16 v: vlqzjlvxljrvvjvvzp +12-13 w: wwwwwwwwnwdwwgwwwx +14-15 d: dcpdddddddddddmdbd +1-3 b: bbdbbbb +11-12 t: rkdtncbtkktzmvtghb +3-7 n: nzbfgbnnx +5-13 v: vsvbkvvvvvvvv +3-8 n: nltdrmbn +14-15 p: mzkmmqdfpcptzbzc +4-6 q: qtqkgqfmqwm +9-10 v: vvdvvxvvxvwd +5-7 m: mmmmmmkm +6-7 k: kkkkkgkk +8-9 h: shhhhhhhh +8-11 p: pppppppppczplbwcpb +11-17 k: kkkkkkkkkkkkkktkc +9-17 w: mwtfbvsfnhwxqqvxw +8-12 j: jhjjjjjrkjnjjjjjjjj +3-5 g: sgfgqgg +12-14 j: jjjjjjjjjjjjjjjjjjjj +1-11 f: jsffffzfffffxffftf +16-17 f: fffffffffftfffffff +2-4 k: klkwkk +5-8 g: gtjngzkhgb +4-7 b: bbbmbbbb +4-5 w: wwwdw +5-15 g: tplhhgmggbhggrllqg +9-13 v: jvvbqvsbvzhxvh +1-3 d: ddsddn +2-5 w: cfwds +7-11 x: xxxxjxvvxvxhxvml +5-6 v: jwqxvb +3-15 s: ssqsssssssssssss +5-9 d: dddddddddddddddd +5-8 l: vklnlclj +10-13 s: sltdlfbssxsss +11-18 j: hxjxjnjcpmkppnpjpjk +4-6 t: ttbzhvt +2-17 v: rzmhrssrjvpncwqwl +2-4 x: mtcxz +11-12 d: dddddddwddbd +2-13 h: whgpdxvkfxrhg +5-7 d: ddddddxdtddddddhdddq +4-8 b: lhcfbkbbdmb +8-15 l: lvtmkgwllqttgplbgjj +3-5 n: nqngjvw +12-19 m: mmmmmmmmmmmmmmmmmmgm +5-9 g: grhgsdcwgmdt +6-9 j: msgrcrfvzksfxxjq +6-10 s: xdssssssssssssssg +8-9 h: hhhnhhnfhh +12-15 f: fffffffffffffffwfff +3-7 p: pzzpbjkfcczbmnpkf +6-7 r: cnjlbhr +2-5 f: dwxcftrbljgstf +5-11 h: hhhhjhhhhhqh +16-18 r: rrrrrrrrrrrrrrrrrmrr +2-4 r: rxmrd +7-9 c: ccccczccccc +7-13 d: ddddddddddddfd +3-11 k: mmkspkltjwm +8-11 c: rvccccgtclc +1-3 v: vvhhv +4-7 t: jttnttgx +4-16 n: nnnjnfnnnnnnnnnnnn +5-6 m: mmmdmqmm +9-10 x: xxxxxxxkxrx +2-4 m: tmcmzjmvtcghlgm +6-7 q: lqqjqqnzqqmq +16-19 k: kjwkhkkjhkskskpnkfk +19-20 b: pbbpsbnbbmnntbnbbbbn +4-5 p: ppppmp +3-4 d: grlqndd +4-7 n: nnnnnnsn +9-12 k: kkkkkkkkfkkkkk +4-10 h: hfhhhxhfhd +4-9 t: ttttxbbbcdmxsrhjj +4-11 l: npxwbsmklbls +17-20 d: dddddwdhdkddjdddtfdd +3-4 s: nldssq +4-8 s: sssdsssgs +5-16 t: ttttprtcttttttzt +9-17 j: tjjtjjjjgljjjcjjfj +7-8 b: bbbbtbkbb +2-13 l: szllllllllxllll +8-11 n: bmpnwrnngnmsfw +1-5 d: jddqtdwddxddjd +10-11 s: hqgnvslssstqdnvs +14-16 p: ppppppppvpplpgpp +2-8 h: khhjfcqp +6-7 d: fxdpdwvdjkd +5-7 n: bnnprnf +9-13 f: vfffwfffffffkfxff +2-10 j: vjhcggzrjqt +5-7 g: gggfggzwgg +5-6 d: ddbsjddfsdnddxfpgdd +12-13 g: gggqjgxgzpgsggxggxk +1-8 l: hlslllllll +12-13 f: sbfftpvbjsmff +6-7 s: hqcthsb +5-11 s: qsstnssssqsrsskdss +2-6 x: hxrfnjfclx +1-2 w: swwwwwwwwwwwjwmwwwww +7-12 s: whsbkgsmvnfjnnkq +10-12 l: fllllllllsllll +8-9 s: lsssssssqs +1-7 p: pdpppghqppxpppppp +1-3 x: jhxmjhkdrxgd +1-7 b: lbxbbbvbwbbbbt +4-5 c: cdckcbcmqcc +5-9 k: kkmklhlmkkgkrld +12-18 x: dvjxqxxxxxdxxxzxhp +5-8 h: nhfhnfqx +15-16 k: kkkkktrkkkkkpkhqxkkd +1-13 j: dcnbwjxllpksj +11-13 v: wvqhznrrfgmnvz +2-5 m: bpjbmbrmfh +10-15 t: mgtttttqspthnttkktt +9-10 n: nnpnnnnpnh +8-10 b: bjbzhbbbcq +4-12 n: nnnvnnnnnnnnnn +13-14 v: zbkchmmvjvsgkvhcz +2-9 j: jdqjgnnjjjvjt +11-16 g: ggggxqglgglfhvgggn +1-2 b: bsbm +8-11 v: lvvvjhvmxvvvv +5-7 x: xxsxxxpr +2-15 t: stwqdkrqcwbmngtd +5-8 r: rcrrvndr +5-6 v: vvvvvr +4-5 x: qpxxr +1-2 k: nkkkkkd +10-13 r: znlqhvwdvrqbrrrfzwc +1-2 h: hwhhhchhhhhhhhhhhh +3-6 b: bbbbbvbbbvbb +13-14 s: ssssssssmssssdss +7-11 x: cwxhmnhzxrxdrzzxbw +5-16 m: rgjtmrqqmfmmckxm +17-18 b: bbbbbbbbbbbbbbbbbk +11-20 k: kppkqkftkgkkknbtglkb +13-14 t: rtcfrkjvtgnrtf +5-6 z: kdzjxzjgmd +2-3 p: rxppj +9-12 b: mtpbbbbbbbbgp +8-9 b: rbbbbbsbbbbxb +13-17 r: rxgbrrnrrrrrrkrrlrrr +8-11 w: pzqswqwcfln +3-4 x: xxxx +6-9 j: fjhkjjklc +6-7 m: ctmzmfm +8-9 l: lllllllgllpts +8-9 t: hgpwblqkvqtb +4-7 d: dddpddd +4-5 c: ccccwcccg +1-7 q: lvvtpqqvnsqbzqpr +8-15 q: qqqqqqqqqqpqqqlqqq +4-8 f: frfffffffxf +7-12 r: rrrrrrrrrrrkprrtrrrp +14-15 j: jsjjjjjjjjjjjjl +6-17 b: khgflbrbrjbgzjtjt +5-7 j: jjknjpw +2-9 h: rhlqbdklh +5-7 j: lrtvccjbzgjh +12-14 t: tltwtxtctttnttttft +8-9 q: qqqqqqqqx +4-15 p: ppppppppppppppc +2-3 v: vvvvv +5-7 h: djvplxb +11-12 g: gjxlvggsgggxsgfgp +5-6 g: gggggfg +1-6 x: wxtxxxxxxxxxx +1-4 r: rqrcrvrzbrxrwjr +9-10 w: wwwmwwwwpww +7-15 z: pzrbrxpzzzzzntzv +4-5 q: qjqwqqnlqhclq +12-16 g: ggccgzggggsggjgg +11-13 b: phbmbsgkvszbbrbb +2-3 l: xhlbhl +1-7 q: qwdqmtv +5-9 x: xxxxjxxxxx +6-8 p: kvpwqbdp +11-13 t: tqttttttttttmt +9-16 l: wzdxdmlxlkfjknnz +1-11 j: vjjjjjjjjjjj +2-18 t: tsttttttttttttttthtt +6-7 n: fnnncnl +3-5 s: lssvgfssgsshsvstsss +3-5 h: hhhbhhh +4-10 x: tsxxxxxxbls +2-4 n: nnjw +17-18 p: bptpftnxjchrwthtppk +14-15 d: dddddddddddddddd +10-14 m: mmmwnmmgmdmmmmmmmmm +8-9 k: pkpqffpkktbgkbk +7-11 l: lllllllllqplllllllll +11-15 n: nnnzngknbnzdnsnnn +2-4 l: vbqm +10-11 w: wwwwwwwwwwq +3-5 x: xxtxxxxx +3-15 b: spbcxjlbbbrbbbbb +4-5 n: nvfsn +13-16 n: bppjnncnbgjndnnntwgs +1-8 t: mttttttttt +6-9 d: jvmssdkdhxsd +9-10 d: gdrllcfdnd +7-11 c: cscxccccnztccccz +15-16 p: pppppkphpppppspg +2-4 n: vnkjlwwsswscmxktnj +9-11 r: rrrrrkrzslr +7-10 t: tttgqtnttttttttt +4-10 b: bbrzbzpbsbnbbjnbsb +7-8 j: jlljxtsj +5-15 z: lzzzfqzzzzzqzzzzzz +10-11 r: rrrrrrrrrrcrrrr +6-8 t: tztpbttttt +2-9 c: vcgtfxfbr +9-16 r: vgjrwcxhrrhbzxnj +17-18 r: bczjtmjwrtzwvmgbrl +5-6 d: dqgddvd +1-2 r: krzrkr +8-9 j: rxjjjjgbj +8-9 c: cjccccccc +13-14 b: bbbbgbbbbbbbbvb +5-6 p: hbhwtp +1-2 w: wfhrfsfbjtpkqcjrwdb +10-13 q: qqqqqqqnqrqqzqq +3-4 m: xcmcz +11-15 d: dldddcddddjddqd +4-10 h: khhlhhhhhhhhhhhh +2-4 d: bdfpmxzqzbzmxmmwg +4-5 l: lgrbl +9-13 s: ssssssssfsssss +7-8 p: pplkpmkppppppxp +3-8 j: jjjjjjjj +7-8 f: jfffffhzfff +2-5 p: pppppppp +8-9 l: tlclllmlz +4-5 m: mtrmx +13-16 x: xxxxsxmxxxxvwxxw +5-8 n: jknnngnv +4-7 p: ppptppgpppp +12-15 r: rrrrrrrrrrrxrrrhr +2-9 s: sssssssssss +5-6 z: zphzzr +13-17 m: mmlmmsmzmsddbxmkb +5-7 g: gggggggg +8-9 f: ndzfvfkfz +2-10 g: wtngwdkcxgrth +6-13 r: rrqrrqrrqrrrcrrrr +1-6 z: hfzzzz +10-13 j: jjjjjjjjjjjjdj +5-11 m: wfqvmhbjhhnmzdlmpjc +6-8 d: clddzxcdghn +8-12 n: qfqbbvkpjbznrz +3-6 r: rrbrrrrrrx +9-10 r: rrrrrrrrrrr +4-5 m: chltmcm +7-8 r: rrrnprrzrhr +3-4 j: jfcj +16-17 n: nnnnnnnnnnnnnnnnwnnn +7-8 r: rrrrrrnfr +4-12 n: nnnnspnlcnmsnnnn +11-12 v: vvvvvvfvvvhvvv +2-8 h: hlhhkhhchhhghh +4-5 t: stntztttmp +3-5 v: vvvmbvhvvvlvn +9-14 x: srxmtbtgxgmqxxxc +4-5 z: zrlgz +10-11 p: phxkvklpmdp +8-15 m: mmmmmmmpmmmmmmm +1-13 h: mzwqkhhhphsgh +17-19 s: qssssmssgfmssmmpssk +6-8 b: bbbbbbbjbb +3-4 l: rllr +2-4 j: kvjj +2-5 n: lnnkrm +15-16 w: wwwkwwwwwwwwwwwc +1-3 c: ccncc +2-5 s: bhppmsttzcscss +1-4 t: tttxtttt +1-9 r: rfrrrbhtxrrbrmrmr +12-13 s: qplrssssmfswrsswss +2-4 h: zrhhhhzhzhch +1-5 g: rgjgg +11-14 t: ttttvftttttqlsttt +3-4 s: sskss +5-15 m: mmmmnmmmmmvmmmm +1-8 j: sjjjjjjj +1-4 c: ccclcc +5-7 d: ddddhdd +2-8 z: tczzjzzzzzzzgz +1-5 s: qsqdz +8-11 z: zhzpzrvzhzkzzgm +5-9 g: nvdfgshgbgltlqggbp +1-12 r: rrrrrrrrrrrrr +3-4 m: xmmb +8-10 j: jjjjdjmjshqjzk +2-4 t: tptttftt +4-13 t: ggqscfggftnxgjpn +4-12 q: hvzjzqsqwqjlqx +7-8 q: qqqlqqqkqq +9-10 f: ffffffffdfff +2-7 k: kgkkkkkk +7-11 t: xbpdkrtplmfbtkwgp +4-7 c: ccccccccc +12-14 d: dddddddddddqdddddd +6-7 k: xhnntkpnbkfwlr +3-5 q: qqxxq +13-17 d: ddddddddddddvddddd +2-3 g: smglpgpflsrbwxcjctb +5-9 z: zjzzznfzf +7-13 l: lmrkvvxtltcnj +15-16 r: vjrrrkzxrrrqrtrpzv +2-7 x: xsxxxxxx +7-14 m: npmnmgdvnqmgrmm +2-4 x: pxxl +7-15 k: nkkkckgwdkffkmb +7-11 n: dznnmcnssmcn +8-10 s: skssgswssmsss +14-16 n: nnnnnnnncdnjnnhwnnn +4-7 g: kggmgggbggggwggcqgng +4-7 g: gggqggggg +1-2 c: cccc +4-8 j: mzzvwjgrbrv +11-12 x: pksjnwlltskxlj +1-9 k: zfkkkksrkkkkkkz +1-6 k: xkkkkknkk +1-6 c: gccccncbccccc +14-15 h: hhhhhrhhgkhhhmhh +7-8 f: qffgnfhf +2-6 m: vmqwxzgsm +5-8 k: kkzjkwkvk +3-4 s: dcsss +2-4 p: jjbps +2-11 z: zjzzzzzzzzzz +4-7 f: bnkhvjfff +13-16 m: mmmmmmmmmmmmjmmmmmm +5-10 t: kdwjmcgtvtdttmtvw +3-12 j: jjljwjfjjjjjnhjjjjc +13-14 f: fffffflffxfffbf +2-6 m: zmhmsm +4-18 n: nnnvnnnnnhnnnfnnnhnn +3-6 n: xznnsnn +7-11 g: ggggpgggggggsg +6-8 l: llllltllll +4-5 s: ssnttsrs +6-14 w: wwwwwwwwwwwpwlwwww +9-12 q: pxqvswnqqbsqvgsd +1-4 j: mjjjjz +9-19 f: fffffffflfffffffffff +2-6 t: rttqtstct +6-9 d: dddddtddddd +7-12 l: lllllllllllllll +1-12 p: gppppppplpppppp +1-4 s: fslssssssfcd +6-7 v: wvvzffggdfvbvvv +2-7 t: kkwgspt +6-16 n: nncbnnnntwrxlzzwdrsj +3-4 z: zzszzhrqwngprjt +4-5 v: vkvvvcfjc +4-5 j: hcjtj +2-4 k: kqkkkkkkkksk +7-9 g: gzgmgpgkv +5-9 s: kjnwsrjrzssssdlnsqs +2-8 j: jtjxxgmjkjx +5-12 r: bfrcrtjkzqffsjtvwj +1-2 v: xvvvmvvvv +5-9 v: vzrgdldfvx +3-5 m: mqsfmmlmvdfj +12-15 v: wswvvbqqhlvqvwx +6-7 b: bbmjdhb +2-4 b: hbjmjr +6-7 n: pnnnnln +13-15 z: zzlgzpmztfzqzzl +5-6 c: pcppscccccc +6-7 z: zzzzzzz +6-14 l: lllllllllllllqllqlll +13-16 r: rrrrrwrrrrrrhrrr +11-12 r: rrrrhrvhqmqrwr +15-19 w: wwwwwwwwwwwwwwwwwwdw +3-6 w: wwqxkw +17-18 z: zzzzzzzzszzzzzzczvz +3-4 g: lgxx +4-5 x: nsdxdskjxtrz +11-12 w: wvdgqppfwwdf +2-3 w: qgrz +7-8 w: wwrppwfwwrcwr +2-6 n: gtspnngz +3-7 j: jjpjjjzjjjjj +1-2 l: pllblvgmfjvv +15-18 r: rrlgctrrrcrqqgldpr +3-6 v: vvvvvt +2-10 s: vslltcxpbg +5-8 j: blvzjtjnfmjnjtsrzmc +9-13 b: bbbbbbbbbbbbsb +3-4 w: wwfjw +6-7 x: xxxxxxmx +7-15 g: ggggggrgggggggfggg +16-18 f: zffffffffffffffwfff +3-4 q: qcqn +3-4 k: kvzqk +4-18 z: wpclkbsxwbmbmkdpzzcm +1-8 z: zkzzzzzgzzzzz +7-16 x: xxxxxxxxxxxxxxjkxxx +3-6 t: xwcjztz +8-9 r: rdrprrtrs +1-7 v: dvvvvvcvvd +6-8 t: tttttkttt +1-5 w: xzwww +6-7 c: ctdjbwcc +3-4 t: ttnttt +9-10 q: qmcqqqsqqqvqqq +11-12 d: dpftdmdmdmld +7-8 j: tbjmbjlj +3-6 t: tttttqtt +6-8 t: tdttthbnqt +2-5 q: qqqqp +1-3 t: ttht +13-17 n: nnnnnnnnnnnnnnnndnn +4-6 j: ftkvjj +5-10 c: hvccfcsccb +7-11 v: vmqvqnnnvzglvvvv +5-8 k: kkkkkksckkk +1-12 z: rzzzzzzzzzzzzzzzvzz +17-18 t: tttttmtttmttttttpttt +16-17 z: xljjnngmjmhprcqzw +4-11 d: dtddbpddlhn +17-18 t: tptttttttttttttttbtt +9-12 w: wwwwwwwwwwwcw +3-4 z: zdzj +1-8 q: qlqqkqqhqtqhxqbbwcp +6-8 r: rkrrlrrmzrcnnrk +13-17 b: dbsbbbbbbbsbmkbbb +5-16 q: gqnvqwwgqshmtrdbplfb +7-9 c: mcvccccczc +10-11 p: pppxppppppc +1-6 v: vvvvvmvvvvv +5-6 s: ssssks +6-14 r: prgrbvrjrgrkrrr +2-11 c: qbnxcvxgldcvdd +11-15 d: ddddddddddsddddd +13-14 w: rwwwwwwwwwwwwsw +12-15 t: ttttttttttttttt +5-8 g: skjgxsjpgvsgr +5-11 g: ggddglggxgqgg +2-4 c: cccc +2-3 h: rvdg +9-13 r: rrrrrrrrsrrrjrrr +2-7 f: dflmgzsdftgkgc +1-5 f: jffffffnfcff +3-4 c: cccrqc +2-7 m: kblcghm +3-4 r: rscrnbbpfkr +2-3 d: wdtqpd +5-6 q: qqqpqnqq +13-15 d: ddddsdddddddddjd +3-4 c: cmcw +2-7 q: qqqqqqjqqqqbqfqq +11-14 x: txxxxpxdxxkxqcv +10-11 b: bbbbbbbbbkbb +7-11 p: ppppppppppmpv +5-6 r: dnxrcvrrr +1-4 d: rdddddd +5-9 f: lxgfvffdf +8-16 k: vmfksjkwkrkkkhkkvknk +15-16 v: vvvvvqvvvvvvvvgv +2-5 p: xpctr +11-15 w: wfwwwwwkwwwwwpr +11-13 x: xxxxxxxlxrfxxs +18-19 b: bbbbbbbbbbqbbbbbbbb +2-4 l: fgwl +8-11 m: xmjnmmmmnmh +4-6 g: lgvpksgq +5-7 t: jtgtvttjlfhpljtzzstd +7-11 p: mjcgvcmxgqpntxkpb +2-3 r: rrgrrnr +6-7 r: rrrrrcr +4-14 d: dddjdddddddddpdddd +5-7 q: qqqqkqqqq +1-4 t: qttqt +4-10 f: hbfjbzrfgvffq +16-17 j: wjjwjwpsjjdvfjnhv +3-4 v: vvtwv +5-6 s: ssdswspdss +1-2 r: rnrrmskrr +4-7 h: rqxbjjhsfh +4-9 l: llllllllhl +4-6 w: sgtwwmcpwd +4-11 l: fjdllznlllmdnll +4-5 k: kkklk +4-6 s: sszrssssssss +12-14 w: wwwwwwwwwwwvwww +2-4 b: vnzb +7-18 g: ggggggggggggggggggg +1-13 s: srjdvvpqnrsnnkzfj +14-15 g: bmhbclmqcgtqxgg +8-12 g: gggfhxgglgzb +3-5 c: scrkcshctccmhm +7-12 q: qklqqqhqvxqqqqw +1-6 m: mlmxzwkmm +3-16 r: rswggrrrrczxfpjt +14-16 l: llldlblllqllllns +2-5 w: wwwwmw +7-9 r: rrrhrprrr +2-3 j: zjmdfcth +3-8 w: xwgwwwwww +1-5 l: plllllll +2-4 b: fbqp +2-3 p: jwpmp +3-4 c: kscm +2-5 b: mbpbnfkvh +4-15 m: qrswmmmgmvmfqtmrrn +12-15 r: rxrrrrrdrhpfrrrrcrrr +10-13 j: jjljjjjjjnjjjjj +8-20 w: gjccptmwtrwxjtskrdfp +11-14 j: jjjjjxjjjjgjjk +1-4 g: gggzzgg +4-8 q: wqqqqblsmsk +1-11 h: lhhhfhhhhbvhhtjwrbh +4-8 x: xlxqxxtxxxxx +13-14 x: xxxxsxxxxxxxqxxx +12-16 b: bxvbbbqbbbbfzbblb +1-4 j: jzbd +5-6 q: qqqqwqkkqqq +2-5 x: xxxxgx +8-10 n: nnnnnnnnnhn +5-10 m: mmmmrmmmmmmmm +2-3 c: qwcz +3-5 n: cckvz +18-19 q: qqqqqqlqtqqqqqqqjqv +5-13 k: kkpkkkkkkkkklkkk +5-10 q: jfjgqllmqzv +15-17 l: llllllllllllllhll +4-10 b: pgqbfrsnvbhzfmtbtw +1-4 c: mccc +6-16 f: fffffpfffffffcfffff +4-9 j: qjbjlcsgljtbvv +11-12 z: dstqbtxxvdchsg +3-8 d: jvdpnvqs +2-3 n: nfvnnnn +6-12 r: zdbfdrvtmpkrjkr +1-15 k: kbdckwtkfhvrbjk +6-8 v: fvhsvgcv +2-3 p: ppkppp +2-14 r: drclhnrdhtcbmnr +7-10 p: vchpmlpjfxbfnwsdxjr +1-3 v: lvvv +1-3 b: bbjbb +2-12 q: qmxbbbgqlscqvdtpq +7-9 l: lllllkllqlllclll +16-17 r: hrrrrrrrrrrrrrrrr +8-9 g: gggggggfg +6-8 v: zvqffmkv +9-12 t: tttttznttjtfrtsjxtd +5-12 q: bqhbltqnjlhqqhtkq +8-9 d: ddddddddkd +2-8 q: tvpqmrrq +13-16 q: qqqgmqqqqqsqmqqpqqqs +7-9 p: pppppplppp +4-6 h: hhxhlhhhxhp +6-8 g: gggggdggggg +4-5 j: jjjkjj +4-5 x: xxxfg +2-13 x: xxhrhxwbrgrdskghtkj +12-19 x: cxxxxxxxxxxhxxxxxxx +1-4 m: tmmmm +5-11 x: mgqnkjxxscxdxr +3-4 t: tttctt +4-13 b: bfkbfbbwbcbpvcbkdqww +5-7 d: dwddddqd +4-15 l: lvvlfclwbssvsdl +9-14 d: ndkfnddtdddfjpvdqt +8-9 s: ssssssssk +9-13 l: dlljknlsllbslhlml +4-5 n: lnnwn +8-12 v: rlvbqlwvfhvv +6-7 f: rcpfwfvffqfcpf +10-11 g: rnqgxbtnxqfzgggtn +8-11 d: ntdzzddkbdhcdddrgdld +5-6 s: xkmssxscvbpwj +1-3 r: rrmr +9-14 p: pvppppppppppppppp +11-15 t: vhftnbtmwpgbcvt +2-7 t: pmbwnrj +10-11 c: cccccccdcvcc +9-14 s: ssksssssssssslsss +2-5 t: ctrtqpn +4-6 t: mttjftttt +4-5 z: zfbzz +2-3 x: xwxlwstzmvvt +4-5 b: vbsbjwpbsbbb +3-4 x: cwxxlmdf +5-6 z: zzzqszzzzzz +1-4 c: ncczc +3-6 k: kkkkkkk +2-3 z: rjzkpxxdvzlzxjzz +8-10 z: fzjzszzdnzbzkzzfz +1-9 c: ccccxccjpccccc +3-12 j: jjjjjjjjjjjcj +10-14 l: llplllvbllllsp +8-12 r: hnrcrxfzrkcjcprrzjbr +17-20 q: qqkqqqqqqqqqqqqbqqqh +6-9 l: lllljlrlpxllllll +8-9 v: vzzmtwfgv +3-7 v: fqdbsshw +12-13 f: fwffnjfbfffzzqfxfffx +1-3 m: zjmdvjjg +5-7 r: nrswrlbw +8-11 c: crzfvzpcbcbchgxbln +9-17 g: ggggggzgwwjpggpgvgrk +6-9 k: hhkrvkkqfhqwbdb +10-16 q: mzzjqfmtkqwvgdfttj +11-13 m: mmmmmmmmmmtmm +1-2 j: jjhrrj +3-12 h: hhhhhhhhhhhhh +8-11 w: zwkrwznrppw +7-14 d: dpxjnddbvdbcllqr +5-8 c: ccccfcccccc +12-16 p: tnptbppgwxxpppjb +1-14 t: qktttttttttttttt +9-12 t: tttttcttgjtt +3-5 p: tcpdgwhrkxkzjjhvsgqp +13-14 k: kkkkkkkkkkkkklk +11-13 x: xxxxxxsxxxxxt +5-12 n: nxxnnznnnnmlnnn +12-14 h: hhlhhhhhhhzcnnhhhhkh +8-10 j: jbjbjmjvjj +6-9 c: ccccccccsc +5-12 j: jjjjjjjjjjjcj +1-2 f: fhffff +13-17 x: xnlxxxxsxxxxxxxxp +2-5 d: sddzn +2-4 q: qqqt +2-6 p: fmxfxnkp +9-11 k: nkdgncqkkgwjp +2-5 p: hpmgcfcmz +1-3 f: ffczf +5-9 r: rtrrprrrrrr +2-4 p: pnpprdn +9-11 l: ltllbllvllc +4-5 x: xxxmxxx +5-9 x: xxxxxxxxxx +16-20 b: hgcbhbbhbgbbdxhdgjwb +10-15 c: qcccpcccdcccccfccwcf +10-11 x: xndsgkwqpxb +15-17 f: wwbqxrffgfvffdmdffw +5-6 q: qqqhqvqqqq +3-4 h: hhhchc +7-9 x: xxxxxxxxgx +7-8 f: fmfflfgf +12-13 v: vvvvvvvvvvvcvvvv +3-7 g: gggbggsgg +1-5 w: wpswsggtw +3-5 h: hhhhkhhhhhdhw +6-7 w: wwwwwmwwwww +5-11 m: mfdmcwmlvpmfc +14-15 j: jjjjjjjjjjjjjjrjj +3-5 v: rvtvkdvqv +3-6 p: frppxpdpg +3-5 t: ttttrt +2-7 x: xxwxxkfxxxxxxxxxxgxr +6-8 k: kkkkkpkgkkkk +10-11 f: fffffpfffkfdf +11-12 g: gggghgnggflg +1-7 x: xxnxxxxkxx +3-4 h: rhhx +6-8 r: bcwrrrrrhrxmqgrhrzm +2-6 l: mpdlnnp +2-4 j: jbjjdhx +2-15 d: dfdddddddnddddfzddjd +5-12 h: gbngwvffshph +1-2 t: txcpth +14-15 f: ffffkfflfffffgf +8-9 b: bbbbbbpbj +5-6 f: zffhfz +8-15 j: qjjfrtjllqfjjcj +3-5 l: llxllll +10-15 z: tpdzhnzkzrtzrzzzrfrz +3-5 q: qqlqq +3-4 d: vmzddpm +8-11 c: cmvzlxtqxcvckxqm +2-13 r: drpppdsqsmvnlkjb +7-9 w: wwwwwwkww +3-6 s: svfspfnpzq +3-4 b: fqpbbbbzpgqf +2-4 s: smssm +8-9 q: qqqqqlqbq +4-7 s: stcssbw +15-16 k: kkkkkkkkkkkkkkkk +10-13 x: xxsxxzxzxxsxphxxxxx +4-5 p: drpsx +7-11 v: vvvvvvvvvvvvv +14-15 n: nnnnnnnnnpnnnbnn +5-8 k: blgkkkkc +12-16 g: ggggggggggvggggggg +1-8 c: cccccccdc +3-9 p: ppqppppppp +7-9 q: cxqqqbhqqzhjqv +1-12 m: mrkvwmmsjmkmw +2-4 s: xrrj +2-4 w: mbww +7-14 v: vvvvvvvvvvvvvbv +3-8 p: kppjprpxppb +4-10 n: znncndnnjncnrnkn +5-7 k: kktnkks +10-13 r: rrrrrrrrrrrrnr +1-6 k: kkkkkrvk +3-5 k: jhjzkbqsjwkxsvd +5-8 p: pcqpprckrp +2-5 f: fsjwf +6-9 l: jxhtplclr +4-13 x: gdxdcdmmxlfxxs +2-10 v: vvvrvvvvvhvvvvvvvv +11-12 v: wqnwrlvjsxvs +1-4 m: mfqm +3-5 d: bmddv +8-10 h: hbhhdhfchh +4-5 s: sssdb +2-3 l: lsll +10-11 k: kkkkdcpnkkgkk +6-8 r: vrrrrxrrrrr +3-4 s: gxsbfr +17-18 p: ptppppppbbpbprpcqpp +16-17 s: gpgwvvnjbdqpksnsd +5-10 f: gfkfzqflfzffvf +6-18 m: kxxfrxjmwmltdvxwmmb +5-6 d: ddntbd +11-15 b: bbbrbhbgbbltbbhb +6-7 r: krbrrrp +5-6 q: qqqqqkqqqqq +3-6 k: kfkmjt +8-10 d: drbwtrdshdbg +13-15 n: tqnprfnndhplcjn +2-4 w: wjwg +10-11 p: xprpnpvhppp +9-10 r: rrrrrrrrqrrr +2-8 w: wjwnwhwwwwwww +12-13 g: gggggggggggwggg +1-6 s: sssssss +1-9 k: xkkkkkkkkkkkkkv +2-4 c: ccccc +3-7 s: ftssfrm +12-13 k: kkkkkkkkbkksk +9-16 q: qqqmqbbqhzqwtlwqb +7-9 p: ppppppppdppp +4-6 b: pcvbvkhb +9-10 g: qmchkfggmgpqgxxgxq +2-9 t: sthtnttthtlsq +3-4 x: xxxx +8-14 s: ssssssssdssssssss +1-3 m: gmbmvbmqbxvm +10-15 s: sgwkdvnsswsszwrn +3-4 s: gmgs +5-11 f: fffffffffffffffff +7-9 v: vvfvsvzdhvv +4-8 l: lllllllpllllllllll +11-16 x: xxxplxxxxxpxxxxxxxxx +9-13 t: tdtftttjdtttc +9-13 g: rknsckngkvdxg +3-4 d: sdqwddmr +1-3 l: lljl +7-17 r: trhrpmrqswrmnrbrrhb +7-8 g: ghkxwgttgk +5-7 b: fbnbtbndb +6-7 v: vnxlvgv +1-6 t: txtkttg +2-13 n: ljnnnnlpsnscfnnnnnnf +4-11 b: bbbbbbbbbbfb +6-9 x: wxdkxxnnnx +2-4 w: wswww +5-13 j: jjsjjjjjjjjjkjjjj +1-4 f: fszhf +5-9 z: wzgfpzzzzjszfvfpwz +5-9 x: xxxxhxxxsx +15-17 b: bbbbbbbbbbbbbbkbqb +2-7 x: xvdmgxxwgxx +3-4 q: qqqq +6-7 m: mqmlltc +8-10 k: kkkfkhkkkpkkkk +2-6 n: cnxnts +1-6 s: gsssssssssscssss +1-9 n: bbvkmnkdn +2-5 p: nmlhpv +4-6 g: vnggdpgm +7-12 b: bbbbbbvwsbbbbbbbbbbx +2-3 b: lgbjjr +7-12 n: chqccgnwsznngz +4-6 v: nntkvvv +2-5 g: qkrjgkqgljh +1-5 f: rffffsfzxfjfzffff +15-16 z: zpzzzzzzzzzhzzkszz +3-4 l: lmflkl +7-8 f: fffvzxff +2-4 r: rrrgrrrr +12-14 w: tjwgwkkwwwwwwwwww +2-12 m: mzmkmmmmmhmmcmmmrmf +5-7 q: nfqbgqqqpqqgjq +1-4 r: ktpr +5-6 j: jjjgbj +9-13 d: ddpbdddwbbdmd +8-9 r: rphfrrrsrr +10-12 f: fffffffffffbffpff +5-12 b: xhbbcbbbbxtbbb +9-10 j: jjjjjjjjqjjj +3-4 q: qqqn +3-9 r: srrtqqprjmqgnp +2-3 c: gcqc +3-4 c: bclc +3-6 n: jnxhshghnnqncgncn +2-4 h: ckhh +9-12 t: tdjjqcdbtkbtmb +11-13 x: cxxkxbxktxxxkxxxpxxh +4-14 m: hjqmqjvqgjdjzsssdkm +6-12 r: rrrrrlrrrrrrrr +14-16 g: gngggggkfglzgggv +9-13 h: hvhhdzhhmhhhh +3-15 x: xxjxxxxxxxxxxxbxx +10-12 z: zzzzzzzzzpzzz +3-4 h: dnhv +13-14 g: gggggggggggggg +7-11 r: rrrrrrrrrrr +6-9 x: czxxlsxxx +3-5 h: hhchh +1-9 j: jjjjjgdjjjjjjjf +7-10 b: ctsbpxrvwbkbjklghnbn +10-11 g: gggggggggglg +1-7 x: xnpsxfm +9-10 q: xxxzqbpdqj +4-10 q: pqsqbqcvllfn +11-12 x: xxxkxxxxxxgxxxx +3-12 s: pstrsssntsssssbssj +9-12 s: wnsdfrtssllsfbsssccb +1-6 r: nrrrrmrc +11-13 k: kkskkkbkkkzkkk +4-5 h: hhhhshh +5-19 f: ffffffffffffffffffcf +3-4 z: zczzz +5-8 l: ghlllsllfw +3-9 g: ggpngglkkf +7-9 b: xwbbbhhbmgjhbbbhnbb +4-5 c: cjmgczcccpzqr +15-16 j: jqfqsnnvffpjjjqj +5-6 z: zzzztvws +3-7 t: tftxtvfzs +1-5 l: tlllll +5-18 n: nnnngnnnnnnnnnnnnnn +5-6 m: bchzqm +9-10 p: lmpsbqgzpxggltl +2-9 h: hqdpjwpxhg +4-6 n: nqbnbnknnzd +2-7 q: qbqqqvq +7-8 c: cccccclc +8-12 r: rrkrrrprvrcqnr +14-15 j: jkpjjnjjjwjjjjjjhjwj +7-9 s: stsstspsn +8-11 h: hhhhbhhhhjhhhh +5-6 d: dddtpdd \ No newline at end of file diff --git a/day02/sample.txt b/day02/sample.txt new file mode 100644 index 0000000..2eab335 --- /dev/null +++ b/day02/sample.txt @@ -0,0 +1,3 @@ +1-3 a: abcde +1-3 b: cdefg +2-9 c: ccccccccc \ No newline at end of file diff --git a/day02/solution.spec.ts b/day02/solution.spec.ts new file mode 100644 index 0000000..0716ad0 --- /dev/null +++ b/day02/solution.spec.ts @@ -0,0 +1,17 @@ +import { loader } from '../lib/loader' +import { findValidPasswords } from './findValidPasswords' + +const load = loader(2) +const sample = load('sample') +const input = load('input') + +describe('Day 2: Password Philosophy', () => { + describe('Part 1', () => { + it('should solve the sample', () => { + expect(findValidPasswords(sample)).toEqual(2) + }) + it('should solve', () => { + expect(findValidPasswords(input)).toEqual(424) + }) + }) +}) From e18faa0749c5408bb92814f6da1365d40424d154 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Wed, 2 Dec 2020 09:45:04 +0100 Subject: [PATCH 08/60] refactor: make password policy plugable --- day02/findValidPasswords.ts | 34 ++++++++++++++++++---------------- day02/solution.spec.ts | 6 +++--- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/day02/findValidPasswords.ts b/day02/findValidPasswords.ts index 4da6e29..ee88099 100644 --- a/day02/findValidPasswords.ts +++ b/day02/findValidPasswords.ts @@ -1,29 +1,31 @@ const policyAndPasswordsLine = new RegExp( - /^(?[0-9]+)-(?[0-9]+) (?[a-z]): (?[a-z]+)$/, + /^(?[0-9]+)-(?[0-9]+) (?[a-z]): (?[a-z]+)$/, ) -const containsChar = ( +type PasswordChecker = ( + password: string, + letter: string, + n1: number, + n2: number, +) => boolean + +export const oldPasswordChecker: PasswordChecker = ( s: string, char: string, min: number, max: number, -): boolean => { - const numChars = s.split('').filter((s) => s === char).length - return numChars >= min && numChars <= max -} +): boolean => + ((numChars: number) => numChars >= min && numChars <= max)( + s.split('').filter((s) => s === char).length, + ) -export const findValidPasswords = (policyAndPasswords: string[]): number => +export const findValidPasswords = (passwordChecker: PasswordChecker) => ( + policyAndPasswords: string[], +): number => policyAndPasswords.reduce((count, s) => { - const { minChars, maxChars, char, password } = + const { n1, n2, letter, password } = policyAndPasswordsLine.exec(s)?.groups ?? {} - if ( - containsChar( - password, - char, - parseInt(minChars, 10), - parseInt(maxChars, 10), - ) - ) + if (passwordChecker(password, letter, parseInt(n1, 10), parseInt(n2, 10))) return count + 1 return count }, 0) diff --git a/day02/solution.spec.ts b/day02/solution.spec.ts index 0716ad0..f90bb14 100644 --- a/day02/solution.spec.ts +++ b/day02/solution.spec.ts @@ -1,5 +1,5 @@ import { loader } from '../lib/loader' -import { findValidPasswords } from './findValidPasswords' +import { findValidPasswords, oldPasswordChecker } from './findValidPasswords' const load = loader(2) const sample = load('sample') @@ -8,10 +8,10 @@ const input = load('input') describe('Day 2: Password Philosophy', () => { describe('Part 1', () => { it('should solve the sample', () => { - expect(findValidPasswords(sample)).toEqual(2) + expect(findValidPasswords(oldPasswordChecker)(sample)).toEqual(2) }) it('should solve', () => { - expect(findValidPasswords(input)).toEqual(424) + expect(findValidPasswords(oldPasswordChecker)(input)).toEqual(424) }) }) }) From 3578e5694d4be867ff04cffe5495f3f5ff7917cd Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Wed, 2 Dec 2020 09:53:44 +0100 Subject: [PATCH 09/60] feat(day02): part 2 --- day02/findValidPasswords.ts | 30 ++++++++++++++++++++++++++---- day02/solution.spec.ts | 18 +++++++++++++++--- 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/day02/findValidPasswords.ts b/day02/findValidPasswords.ts index ee88099..113cb29 100644 --- a/day02/findValidPasswords.ts +++ b/day02/findValidPasswords.ts @@ -9,16 +9,38 @@ type PasswordChecker = ( n2: number, ) => boolean -export const oldPasswordChecker: PasswordChecker = ( - s: string, - char: string, +/** + * indicates the lowest and highest number of times a given letter must appear for the password to be valid + */ +export const LegacyPasswordChecker: PasswordChecker = ( + password: string, + letter: string, min: number, max: number, ): boolean => ((numChars: number) => numChars >= min && numChars <= max)( - s.split('').filter((s) => s === char).length, + password.split('').filter((s) => s === letter).length, ) +/** + * describes two positions in the password, where 1 means the first character, + * 2 means the second character, and so on. + * (Be careful; Toboggan Corporate Policies have no concept of "index zero"!) + * Exactly one of these positions must contain the given letter. + * Other occurrences of the letter are irrelevant for the purposes of policy enforcement. + */ +export const TobogganPasswordChecker: PasswordChecker = ( + password: string, + letter: string, + pos1: number, + pos2: number, +): boolean => { + let count = 0 + if (password.charAt(pos1 - 1) === letter) count++ + if (password.charAt(pos2 - 1) === letter) count++ + return count === 1 +} + export const findValidPasswords = (passwordChecker: PasswordChecker) => ( policyAndPasswords: string[], ): number => diff --git a/day02/solution.spec.ts b/day02/solution.spec.ts index f90bb14..dce577c 100644 --- a/day02/solution.spec.ts +++ b/day02/solution.spec.ts @@ -1,5 +1,9 @@ import { loader } from '../lib/loader' -import { findValidPasswords, oldPasswordChecker } from './findValidPasswords' +import { + findValidPasswords, + LegacyPasswordChecker, + TobogganPasswordChecker, +} from './findValidPasswords' const load = loader(2) const sample = load('sample') @@ -8,10 +12,18 @@ const input = load('input') describe('Day 2: Password Philosophy', () => { describe('Part 1', () => { it('should solve the sample', () => { - expect(findValidPasswords(oldPasswordChecker)(sample)).toEqual(2) + expect(findValidPasswords(LegacyPasswordChecker)(sample)).toEqual(2) }) it('should solve', () => { - expect(findValidPasswords(oldPasswordChecker)(input)).toEqual(424) + expect(findValidPasswords(LegacyPasswordChecker)(input)).toEqual(424) + }) + }) + describe('Part 2', () => { + it('should solve the sample', () => { + expect(findValidPasswords(TobogganPasswordChecker)(sample)).toEqual(1) + }) + it('should solve', () => { + expect(findValidPasswords(TobogganPasswordChecker)(input)).toEqual(747) }) }) }) From 49c5735d782899899f0bdea02a3a54af032fc0ca Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Thu, 3 Dec 2020 08:05:08 +0100 Subject: [PATCH 10/60] feat(day03): solve sample --- day03/countTrees.ts | 20 +++ day03/input.txt | 323 +++++++++++++++++++++++++++++++++++++++++ day03/sample.txt | 11 ++ day03/solution.spec.ts | 29 ++++ 4 files changed, 383 insertions(+) create mode 100644 day03/countTrees.ts create mode 100644 day03/input.txt create mode 100644 day03/sample.txt create mode 100644 day03/solution.spec.ts diff --git a/day03/countTrees.ts b/day03/countTrees.ts new file mode 100644 index 0000000..bb263f6 --- /dev/null +++ b/day03/countTrees.ts @@ -0,0 +1,20 @@ +const tree = '#' + +export const countTrees = ({ + down, + right, +}: { + down: number + right: number +}) => (slopes: string[]): number => { + const width = slopes[0].length + let currentSlope = down, + currentIndex = right % width, + numTrees = 0 + do { + if (slopes[currentSlope][currentIndex] === tree) numTrees += 1 + currentSlope += down + currentIndex = (currentIndex + right) % width + } while (currentSlope < slopes.length) + return numTrees +} diff --git a/day03/input.txt b/day03/input.txt new file mode 100644 index 0000000..43deaca --- /dev/null +++ b/day03/input.txt @@ -0,0 +1,323 @@ +......#..##..#...#...#.###..... +#..#............#..........#... +..........#....#..........#.... +....#..#.#..........#..#.....#. +#.......#...#......#........### +#####........#.#....##..##..#.. +......#.#..#..#..##.#..#.##.... +.#..#.#..............##....##.. +..##......#....#........#...### +...#....#.#....#.#..#......#..# +..................#.....#.....# +#.#...#...#....#............#.# +.#...#.....#...##........#..... +...#....#........#..#....#..### +#...##.....##.#.#...........#.# +.###........#.#.#.........#.... +...#.............###.....#.#..# +.####.#..#....#.....#.........# +.#.#........#.#.....#.....#.... +.#.......#................##.## +...#.#..#...###.....#....#..##. +...#....##..#............##...# +#...#............######...#.##. +.........#........#.#...#..##.. +.....###..#.#.....##.#.#......# +..#.#...#.#..#.#.##..#.....#.#. +..#......#.#....#...#.......... +..#...#.....#.#...##.....#..... +.##...........####........##... +....#............#.#........... +.....####.........#.##....###.. +#..#..#.#..............#.#..... +...#.#........#.........#...... +......#.#.#...#.....#....#..... +........#.#...#####..#..#...... +.....#.#....#....#...........## +.#...#.........#.......##...... +.#.##..##......#............... +...#.....#.......#.#.#......... +.........#..#...#...#.#.##....# +.#......##....#..#.........#... +....#.....#........#.........## +......#...........##........... +.....#..............###.#....#. +........#..#...#..#..#..#..#.#. +.#.....#.##.#..#..#.#.....#.... +...#....#...#.#.....##.#...#..# +#..#......#..#.###...........#. +.##...##.#........#.#......#.#. +...#.#..#.#.......#..###...##.. +#.......#.#....#..........#.... +.#.....#..#.#.#..#..#........#. +.#...#......#.#...#.##.....#.## +...######..#.#....#.........##. +#.#.......................#.... +..#..##...#...#.#..##.......#.. +.##..#.......##......##.#..#... +#.#....##.......#..#........... +..#...#............#..#........ +........#.#.........#...#..#..# +.#...###...............##...#.. +...........#.....#....#....###. +#..#....##..#................## +...#.#..#..##......#....##....# +...#.##...#....#..#....#....... +#...##..##.#.........#...#....# +.##........###.#..........#.... +..#..#..#...#.##..#.#......#... +.......##..#....###.##.....#..# +#....#...#.#.....#..###....##.. +.#.......#.........#....#.#..#. +.........#.......#.#.......#... +..........#...##..#...#....#.## +..#........#.......#........... +#....#.....##......#....#.#...# +......#.....#....#.....#..#.... +.#....##...#...##.............. +..#....#......#...#....#...#... +#....###...##..#.#....##......# +..#.......#.........#..#......# +...#...#.##.......#....##..#... +..#.#...#.##..#..#..#...#.#...# +.#.........###....#....#.....#. +.#.##.#..##..#...........#....# +....##..#..##.#.......#....#..# +....#..#.........##..#......#.# +..........#.#.#....##.#......## +.##...#....###...#..........#.. +#..#.....#..#.#.#.#..#......#.# +......#....#......##.#......#.# +...#.....#.......#....#.......# +.#.#................#.......... +......#..#..#...............##. +##......#...#.####....#.#.#.... +...#..##............#....#..... +..#..#.#...#..................# +.##.#.#..##.###.....#..#....... +..#...#.#...#......#..#........ +.###..........##...###..##..#.. +#.#...#........#.......##...... +..##...#........#....##...##... +.......#.##.....#.#.##..#..##.. +........#............#....##... +...#.#.#..#.........#.#.......# +..#..##.##...#.##...#....#...#. +.....##.#...##............##... +.#...#.###....#.......#...#...# +.......#######.#....#.....#.#.. +......#.......#............##.. +.....#...........#......#.....# +........#....#.##.#............ +.#........#.......##.#.#....#.. +#.....#..####.#................ +.....#.......................## +.#.....#..##.#..##........#.#.# +#...##....#..##................ +......##.###..........#.....#.. +.#........#...#..............## +..#..........###.........#..... +....#.....##....#..#..#.#.#.... +....#.......#.##...#.####.#.... +#........#............#.##..... +..#......##.....#..#...#....... +..#......###...#.##......#..#.. +#..#..#............#..#.###.... +...##.........#..##...#..#.#... +..#.###..#.##.#........#..#.... +......#..###.#........#........ +.#....#.#..#.....#..#..#....... +#.....##.##...#...###.#.#..#.#. +.#....#..#.........#..#....###. +......##.####...#....#........# +##..#........#..#..##...#...... +#.........#.........#...#..#.#. +..........#...................# +###....#....#....#......###...# +#....##........#..###.#..#..... +.#......#.....#.#.........#..#. +...#.......##.....#.........### +..............#........#.....## +....#.#..#.....###.#....##..... +.........#..##.#....#.#........ +...#....#.......#.#.#..#.#....# +...........#...#..........#.#.. +#.................##........### +####..#.#..#...#.....###....... +..#.#......##.#.......#........ +.......##........#..#.....#..#. +...#..#......#..#.#.......###.. +#....#...##..#.#.#.#.........#. +....#....#....#.#..#..........# +...###........#.#.###......##.. +................#.....#.#...##. +..#..#.###...........#...###.#. +.........................#..#.# +#...#..#..##.###.....##.##.#... +...#..................#.#....#. +......#..##.#.......#.......#.. +.##....#.#................#.... +.#...#..#.#.#....##....#....... +.##......#.....#..........#.... +..#...........#..##.........#.. +....#.#...........#..........## +....#.#.#...........#.#........ +......#.....#..#....##....##... +............##...##......#.#.## +#.#.....#..#....#..#...#.#...#. +.#...###..#..#.......#.......#. +.....#..#.##.....#....#...#.... +##.....#..##.......##..#.#.#..# +....#.#......##....#.....#..### +.#...#.#......#.##...#..##..... +.#...#...#......##..#..#...#.#. +.#.........#....##...###...##.. +###.....#......####.....#.#.... +.....#..##.##................#. +.#.................#...#..##.#. +....#....#..#.......#.....#.... +.##....#..#..#.....###.#..#..#. +#.#.......#.....##...#.....#... +#.#........#.#.###...#....#.... +.#.....#.....##.#...#..#....... +..###.#............#...##.###.. +.....#.....#..#..##............ +.#.#..#.#..##..#....#...##..... +.#...........#..#.......#...#.# +#.#.#.#.....##....#............ +...#.................#.#......# +.....##.............#...#.#.... +.##......#.#....#..........#.#. +.#.##.......##...#...#.....#.#. +#...#.#........#......##....#.# +#....##....#....#...#..#..#.#.# +......#..........#...#.....#..# +#..#....#....#..##.#..#.#...#.. +......#..#.#....#.....#.#..#..# +...#.#...###........#.#......## +..#............................ +...#.#..##...##...#...#......## +...#.####......#.........#....# +.#...#.#...##....#......#.#.... +.#.....##..##.#................ +.#...............#............. +......#.....#...#..##..##...... +...#..##.......#.......#..#.#.# +......##.....#..#.....#...#.#.# +........##........#.#........## +.#....#.....###..#.......#...#. +#...#....#.........#.......#... +...##..#........#####.#........ +###..#....#.#..#...#.####...... +..#..........#.#.............#. +#......#.#....#.#.#....#.##.... +.#.#.#.............#....#...#.. +......#.....#.#...#..###.#..#.. +.....#..#............#...#...## +..#......###..#........#.#..... +#..##......#.#.#.#...........#. +#..#...##.##.....#....#..#..... +...##.#..........#.#....#...#.. +.#.#.#.#..#.#...#......#....... +....#......###.#............... +.........#...#....#...#.#....#. +##.#.........#...##............ +........#..........#.#...#..... +..#........#....#.......#...... +#..#...............#..#...##.#. +#........#.....##.#..#....#...# +..##....#....#.#...........##.. +....#.#.........#..#.....#..#.. +.......##....#.#.#....###.#.... +......#....#.#...#..#.........# +.....##..#....#.#......#.#.#... +#.##..##.#.......#..#...##.#.## +........#.#..#...##.#.#..#..... +#..#......#......#...#.#..#.... +.....#......#.#....##....##.... +....#.##...##..#..........##.#. +.#....#.......#.........#...... +.#.......#.#...#............... +....#.##.......#.##..#.##..#... +#..#.......#.....#..#.......... +..#.##.......#....#.#..##..#... +.#.....#...##.#.#..#...#....... +.......#.........#......#.#.... +#.##.....##.......#....#....... +##.#.#.........##..#.....#....# +....#.#.#.#....#..#..##.......# +#...#...........#.#............ +...#...#.#..#..##.............. +......#.......#.........#..#.#. +#.....##.#....#...#..#......... +#...#..###.##..###...##.....#.. +#....#.#.#...#.#..........#.... +................#.#....#.....## +#.##..............####.....#.## +................#.....#........ +#...#..#......#.....#......#... +.........##...........#...#...# +#.#....#...##.....#.....#..#..# +.....#...##..##.............#.. +....###.#.......#.........#...# +..#.......#......#..#...#.#.... +#.#....#......#.##....#.##.#... +.#.#...#.......#.#...#.##..#... +..........#......#.....#....... +........#...#.....#...##...#.#. +.....##....#.##..#........#.##. +..........##.....#..#........#. +.#....#..#.......#.##.......... +.#..#..#...#...#........#.##... +.#...#.##.......#...#........#. +.....#....#.............#..#... +...#....##...#...#.....##...... +#.#####.........##...#.....#... +......#.......#....#.....#..#.. +..#..............#.#..#..#..... +....#.................#...#.... +###.#..##.#....#...#.#......#.# +..##......#.#........#.#...##.. +.....#...#...#..#.#..#..##..#.. +.##...#......#...#...##.#...#.. +.......###.#...........##.##... +.#.##..#.#.###.......#..##...#. +..#....#.......#..##......#.... +.#....#.#..#..#.#.#....#...#... +..........##....#....#.#....... +.....#.......#.#..###.#.###.... +.#.#....#.##..#.#..#.....#.#.#. +....#.....#.#.#............#... +.###....#...##......##..###..#. +...#.#..#.....#...#....##..#... +.#.#....#..........#...##.....# +#.....##...#........#.#..##..#. +.......#....#.#..........#...#. +.........#..#.#.###.........##. +..................#.#....#....# +....#....#.#..#.......###.##.## +....#...#.................#.... +...#..#####.......#.#..##.##... +##.#....#...............#..#... +....#..........#...........#.#. +..##.#.##.#..#.#....#.......... +.....#....#....##.#....#....#.# +.......#..##.....###...#....#.# +.#.......#..#.#.#...........#.. +.#...........##.#.##....#.#.... +....#.#....#.#.#......##....... +.........##......#.#.....###... +........#.#...#.##.....#.##.##. +##.#..##.#.........#....#...... +.#.#.#....#..........#.#....#.. +....###.........#.#.#.......... +#..#....##.....#............... +#.##....#.#...#.....#......#.#. +............#.##........#...... +.....#.#.....##..##............ +.##..........#.......#......#.. +...##..##......#.....#..#....## +.##.##...#.................##.. +#....#.#........#..#....#..##.# +....##..##......#....###.#.#..# +.....#....#..#..#...##...#...#. \ No newline at end of file diff --git a/day03/sample.txt b/day03/sample.txt new file mode 100644 index 0000000..8f551de --- /dev/null +++ b/day03/sample.txt @@ -0,0 +1,11 @@ +..##....... +#...#...#.. +.#....#..#. +..#.#...#.# +.#...##..#. +..#.##..... +.#.#.#....# +.#........# +#.##...#... +#...##....# +.#..#...#.# \ No newline at end of file diff --git a/day03/solution.spec.ts b/day03/solution.spec.ts new file mode 100644 index 0000000..e90b369 --- /dev/null +++ b/day03/solution.spec.ts @@ -0,0 +1,29 @@ +import { loader } from '../lib/loader' +import { countTrees } from './countTrees' + +const load = loader(3) +const sample = load('sample') +const input = load('input') + +describe('Day 3: Toboggan Trajectory', () => { + describe('Part 1', () => { + it('should solve the sample', () => { + expect(countTrees({ down: 1, right: 3 })(sample)).toEqual(7) + }) + /* + it('should solve', () => { + expect(countTrees(3,1)(input)).toEqual(424) + }) + */ + }) + /* + describe('Part 2', () => { + it('should solve the sample', () => { + expect(countTrees(3,1)(sample)).toEqual(1) + }) + it('should solve', () => { + expect(countTrees(3,1)(input)).toEqual(747) + }) + }) + */ +}) From 9d1ecba3a5182538d2175916d60352a7ebfd1ebd Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Thu, 3 Dec 2020 08:06:02 +0100 Subject: [PATCH 11/60] feat(day03): solve part 1 --- day03/solution.spec.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/day03/solution.spec.ts b/day03/solution.spec.ts index e90b369..4f644c3 100644 --- a/day03/solution.spec.ts +++ b/day03/solution.spec.ts @@ -10,11 +10,9 @@ describe('Day 3: Toboggan Trajectory', () => { it('should solve the sample', () => { expect(countTrees({ down: 1, right: 3 })(sample)).toEqual(7) }) - /* it('should solve', () => { - expect(countTrees(3,1)(input)).toEqual(424) + expect(countTrees({ down: 1, right: 3 })(input)).toEqual(274) }) - */ }) /* describe('Part 2', () => { From 35399d225fc4b156ce29119272204e7dc5b3a02e Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Thu, 3 Dec 2020 08:10:13 +0100 Subject: [PATCH 12/60] feat(day03): solve part 2 --- day03/solution.spec.ts | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/day03/solution.spec.ts b/day03/solution.spec.ts index 4f644c3..6596f9b 100644 --- a/day03/solution.spec.ts +++ b/day03/solution.spec.ts @@ -14,14 +14,24 @@ describe('Day 3: Toboggan Trajectory', () => { expect(countTrees({ down: 1, right: 3 })(input)).toEqual(274) }) }) - /* describe('Part 2', () => { + const slopes = [ + { right: 1, down: 1 }, + { right: 3, down: 1 }, + { right: 5, down: 1 }, + { right: 7, down: 1 }, + { right: 1, down: 2 }, + ] + const mul = (prod: number, n: number) => prod * n it('should solve the sample', () => { - expect(countTrees(3,1)(sample)).toEqual(1) + expect(slopes.map((s) => countTrees(s)(sample)).reduce(mul, 1)).toEqual( + 336, + ) }) it('should solve', () => { - expect(countTrees(3,1)(input)).toEqual(747) + expect(slopes.map((s) => countTrees(s)(input)).reduce(mul, 1)).toEqual( + 6050183040, + ) }) }) - */ }) From 500d9d52ca1985b25e0750b16ed1e535ddb2228b Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Fri, 4 Dec 2020 07:57:07 +0100 Subject: [PATCH 13/60] feat(day04): implement passport validation for step 1 --- day04/validatePassport.spec.ts | 56 ++++++++++++++++++++++++++++++++++ day04/validatePassport.ts | 15 +++++++++ 2 files changed, 71 insertions(+) create mode 100644 day04/validatePassport.spec.ts create mode 100644 day04/validatePassport.ts diff --git a/day04/validatePassport.spec.ts b/day04/validatePassport.spec.ts new file mode 100644 index 0000000..9861ee0 --- /dev/null +++ b/day04/validatePassport.spec.ts @@ -0,0 +1,56 @@ +import { validatePassport } from './validatePassport' + +describe('validatePassport', () => { + it.each([ + [ + { + ecl: 'gry', + pid: '860033327', + eyr: '2020', + hcl: '#fffffd', + byr: '1937', + iyr: '2017', + cid: '147', + hgt: '183cm', + }, + true, // all eight fields are present + ], + [ + { + iyr: '2013', + ecl: 'amb', + cid: '350', + eyr: '2023', + pid: '028048884', + hcl: '#cfa07d', + byr: '1929', + }, + false, // missing hgt + ], + [ + { + hcl: '#ae17e1', + iyr: '2013', + eyr: '2024', + ecl: 'brn', + pid: '760753108', + byr: '1931', + hgt: '179cm', + }, + true, // temporarily ignore missing cid fields + ], + [ + { + hcl: '#cfa07d', + eyr: '2025', + pid: '166559648', + iyr: '2011', + ecl: 'brn', + hgt: '59in', + }, + false, // Missing cid is fine, but missing any other field is not, so this passport is invalid. + ], + ])('passport %s validity is %s', (passport, valid) => + expect(validatePassport(passport)).toEqual(valid), + ) +}) diff --git a/day04/validatePassport.ts b/day04/validatePassport.ts new file mode 100644 index 0000000..9c185c3 --- /dev/null +++ b/day04/validatePassport.ts @@ -0,0 +1,15 @@ +/** + * Validate a passport. + * cid field is optional + */ +export const validatePassport = (p: Record): boolean => { + if (!('ecl' in p)) return false + if (!('pid' in p)) return false + if (!('eyr' in p)) return false + if (!('hcl' in p)) return false + if (!('byr' in p)) return false + if (!('iyr' in p)) return false + // if (!('cid' in p)) return false + if (!('hgt' in p)) return false + return true +} From a097577290f6b9a4ecc776b0a16b32fd553b7150 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Fri, 4 Dec 2020 09:08:15 +0100 Subject: [PATCH 14/60] feat(day04): implement password list parser --- day04/parsePassportList.spec.ts | 47 +++++++++++++++++++++++++++++++++ day04/parsePassportList.ts | 18 +++++++++++++ day04/sample.txt | 13 +++++++++ lib/loader.ts | 2 +- 4 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 day04/parsePassportList.spec.ts create mode 100644 day04/parsePassportList.ts create mode 100644 day04/sample.txt diff --git a/day04/parsePassportList.spec.ts b/day04/parsePassportList.spec.ts new file mode 100644 index 0000000..8de735d --- /dev/null +++ b/day04/parsePassportList.spec.ts @@ -0,0 +1,47 @@ +import { loader } from '../lib/loader' +import { parsePassportList } from './parsePassportList' + +const load = loader(4) +const sample = load('sample') + +describe('parsePassportList', () => { + it('should parse the sample', () => + expect(parsePassportList(sample)).toEqual([ + { + ecl: 'gry', + pid: '860033327', + eyr: '2020', + hcl: '#fffffd', + byr: '1937', + iyr: '2017', + cid: '147', + hgt: '183cm', + }, + { + iyr: '2013', + ecl: 'amb', + cid: '350', + eyr: '2023', + pid: '028048884', + hcl: '#cfa07d', + byr: '1929', + }, + { + hcl: '#ae17e1', + iyr: '2013', + eyr: '2024', + ecl: 'brn', + pid: '760753108', + byr: '1931', + hgt: '179cm', + }, + { + hcl: '#cfa07d', + eyr: '2025', + pid: '166559648', + iyr: '2011', + ecl: 'brn', + hgt: '59in', + }, + ])) +}) diff --git a/day04/parsePassportList.ts b/day04/parsePassportList.ts new file mode 100644 index 0000000..ef7d95e --- /dev/null +++ b/day04/parsePassportList.ts @@ -0,0 +1,18 @@ +export const parsePassportList = (input: string[]): Record[] => + input.reduce( + (list, line) => { + if (line.length === 0) list.push({}) + list[list.length - 1] = { + ...list[list.length - 1], + ...line.split(' ').reduce( + (props, entry) => ({ + ...props, + [entry.split(':')[0]]: entry.split(':')[1], + }), + {}, + ), + } + return list + }, + [{}], + ) diff --git a/day04/sample.txt b/day04/sample.txt new file mode 100644 index 0000000..3b38741 --- /dev/null +++ b/day04/sample.txt @@ -0,0 +1,13 @@ +ecl:gry pid:860033327 eyr:2020 hcl:#fffffd +byr:1937 iyr:2017 cid:147 hgt:183cm + +iyr:2013 ecl:amb cid:350 eyr:2023 pid:028048884 +hcl:#cfa07d byr:1929 + +hcl:#ae17e1 iyr:2013 +eyr:2024 +ecl:brn pid:760753108 byr:1931 +hgt:179cm + +hcl:#cfa07d eyr:2025 pid:166559648 +iyr:2011 ecl:brn hgt:59in \ No newline at end of file diff --git a/lib/loader.ts b/lib/loader.ts index 5dfe393..f2142ce 100644 --- a/lib/loader.ts +++ b/lib/loader.ts @@ -11,6 +11,6 @@ export const loader = (day: number) => (file: string): string[] => ), 'utf-8', ) + .trim() .split('\n') .map((s) => s.trim()) - .filter((s) => s.length > 0) From 38036afbeb060e76c6d508a68f22004b0e317fd2 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Fri, 4 Dec 2020 09:11:15 +0100 Subject: [PATCH 15/60] feat(day04): part 1 --- day04/input.txt | 1121 ++++++++++++++++++++++++++++++++++++++++ day04/solution.spec.ts | 20 + 2 files changed, 1141 insertions(+) create mode 100644 day04/input.txt create mode 100644 day04/solution.spec.ts diff --git a/day04/input.txt b/day04/input.txt new file mode 100644 index 0000000..9b04221 --- /dev/null +++ b/day04/input.txt @@ -0,0 +1,1121 @@ +eyr:2024 pid:662406624 hcl:#cfa07d byr:1947 iyr:2015 ecl:amb hgt:150cm + +iyr:2013 byr:1997 hgt:182cm hcl:#ceb3a1 +eyr:2027 +ecl:gry cid:102 pid:018128535 + +hgt:61in iyr:2014 pid:916315544 hcl:#733820 ecl:oth + +hcl:#a97842 +eyr:2026 byr:1980 ecl:grn pid:726519569 hgt:184cm cid:132 iyr:2011 + +ecl:grn hcl:#6b5442 pid:619743219 cid:69 hgt:176cm eyr:2027 iyr:2012 +byr:1980 + +ecl:brn byr:1969 iyr:2014 +hgt:164cm eyr:2020 pid:982796633 hcl:#602927 + +ecl:gmt +iyr:1987 eyr:2039 pid:15115163 byr:2006 +hcl:bfab0d + +cid:117 +hcl:#efcc98 +iyr:2010 pid:322719183 +hgt:176cm +eyr:2020 +byr:1957 +ecl:brn + +byr:1954 hgt:178cm hcl:#38f7fd pid:838813262 ecl:blu +eyr:2029 iyr:2019 + +eyr:2023 ecl:amb iyr:2020 byr:1927 pid:242570886 hcl:#18171d hgt:192cm + +iyr:1990 cid:295 hgt:131 pid:187cm byr:2014 +ecl:xry hcl:z +eyr:1928 + +ecl:hzl +byr:1953 +eyr:2023 hcl:#866857 +hgt:181cm iyr:2010 pid:568185567 + +byr:2030 hcl:#fffffd ecl:#a4a596 hgt:168cm +iyr:1936 eyr:2020 cid:296 pid:168786676 + +byr:2030 iyr:2026 eyr:1974 hcl:7fcaa5 ecl:utc +pid:190cm +hgt:67cm + +byr:2023 eyr:2037 hgt:59cm +ecl:lzr hcl:z iyr:2026 pid:#ea9083 + +byr:2003 hcl:z hgt:91 iyr:1990 eyr:2024 ecl:#123d73 +pid:48494230 + +byr:2022 eyr:2020 iyr:2030 ecl:gmt +hgt:191cm pid:3509331253 hcl:#888785 + +iyr:1994 +ecl:#c3d564 byr:2009 +hgt:162cm hcl:336498 pid:#e99d09 +cid:288 +eyr:1921 + +byr:1924 cid:290 iyr:2010 ecl:amb eyr:2020 +hgt:156cm hcl:#7d3b0c pid:795497164 + +cid:301 iyr:2017 hgt:67cm +hcl:#888785 ecl:#0405b9 byr:1964 pid:707857518 eyr:1976 + +ecl:gry pid:474303066 +iyr:2011 hcl:#18171d hgt:165cm byr:1921 eyr:2024 + +hcl:#6b5442 ecl:amb iyr:2020 hgt:191cm +byr:1949 cid:301 +pid:075846582 eyr:2029 + +hcl:#a97842 cid:186 iyr:2014 +ecl:gry +hgt:191cm eyr:2023 pid:645548969 +byr:1956 + +pid:154cm hcl:z ecl:gmt iyr:1989 hgt:69in cid:53 byr:2010 + +hgt:72cm byr:2023 +eyr:2034 hcl:z ecl:#f5249e iyr:1997 pid:#79af7a + +eyr:2038 byr:2015 +hgt:70cm ecl:grt hcl:9d58a1 iyr:1926 pid:6290928420 + +pid:620857794 eyr:2022 +byr:1950 +hgt:159cm +hcl:#ceb3a1 ecl:amb iyr:2015 + +eyr:1954 ecl:#ab2ce4 pid:#14eedd +iyr:2009 +hcl:29e484 +byr:2022 hgt:73cm + +hgt:59cm byr:2026 cid:245 iyr:2020 +eyr:2029 pid:073943129 ecl:hzl +hcl:#b6652a + +iyr:2014 byr:2015 hcl:#a97842 eyr:2029 +pid:#132098 +hgt:150 ecl:oth + +hgt:151in ecl:#967d49 eyr:2026 hcl:#18171d +pid:384230726 byr:1934 +iyr:2018 + +iyr:2020 eyr:2021 byr:1937 pid:735047371 cid:159 ecl:blu hgt:177cm hcl:#22b774 + +ecl:brn hcl:#6b5442 pid:117807698 cid:105 iyr:2016 byr:1977 hgt:183cm + +ecl:hzl hcl:#6b5442 byr:1933 +iyr:2019 pid:348486702 +eyr:2020 hgt:193cm + +byr:1928 +ecl:gry +eyr:2028 hcl:#fffffd pid:571149069 +iyr:2012 hgt:175cm + +pid:359108298 +eyr:2027 hgt:158cm ecl:amb iyr:2016 +hcl:#602927 + +iyr:2027 byr:2015 +hgt:191in pid:102033301 ecl:xry +eyr:2031 hcl:#602927 + +ecl:oth cid:163 hcl:z iyr:2014 +byr:1944 hgt:173cm +eyr:2027 pid:#0524c1 + +ecl:brn +byr:2030 hgt:71cm eyr:1931 cid:165 iyr:2010 hcl:#cfa07d +pid:509642098 + +hgt:166 iyr:2020 cid:308 +eyr:2022 pid:950463527 +byr:2017 +hcl:z + +ecl:amb +eyr:2023 byr:1924 +pid:901038027 hgt:70in +iyr:2010 hcl:z + +byr:1972 +iyr:2013 +hcl:d669ad hgt:64cm cid:247 ecl:#19aa26 eyr:2023 + +hgt:71 hcl:#fffffd +byr:1976 cid:108 eyr:2038 +ecl:grt iyr:2018 pid:190cm + +iyr:2017 +byr:1963 ecl:grn hgt:175cm +pid:160915270 eyr:2028 hcl:#cfa07d + +pid:569740130 hgt:171cm hcl:#733820 +ecl:gry eyr:2024 iyr:2020 byr:1973 + +byr:1937 +iyr:2016 ecl:gry hgt:181cm pid:521705827 hcl:#b6652a eyr:2027 cid:295 + +hgt:156cm ecl:blu iyr:2019 hcl:#866857 +pid:662418718 byr:2000 eyr:2024 + +byr:1971 pid:693616099 +hcl:#efcc98 +hgt:175cm iyr:2016 ecl:gry +eyr:2023 + +iyr:2013 +eyr:2024 +ecl:gry +pid:414295491 byr:1986 +hgt:188cm hcl:#b6652a + +eyr:2022 byr:1975 iyr:2020 +ecl:grn cid:68 hcl:#a97842 +hgt:151cm pid:229803943 + +cid:258 iyr:2012 +ecl:hzl +byr:2001 +eyr:2021 +hcl:#866857 pid:990590217 hgt:172cm + +cid:339 byr:1957 hcl:#866857 pid:343480061 eyr:2039 +hgt:191cm +iyr:2021 +ecl:utc + +cid:281 hcl:z ecl:blu +byr:2020 pid:132694306 eyr:2020 iyr:1953 + +hcl:#602927 +byr:1933 eyr:2028 +hgt:165cm ecl:gry iyr:2018 pid:658484617 + +ecl:oth +hgt:188cm cid:110 pid:056975690 iyr:2016 byr:1950 eyr:2023 hcl:#cfa07d + +cid:342 hcl:#fffffd eyr:2024 +pid:153555359 byr:1974 +ecl:gry hgt:191cm iyr:2020 + +byr:2019 ecl:#160ed3 eyr:1999 hcl:z +cid:146 pid:195693972 hgt:159cm + +iyr:2015 eyr:2030 hgt:191cm byr:1979 +ecl:#ec4873 pid:994113786 hcl:#cfa07d + +pid:552331609 +ecl:grn +hgt:171cm eyr:2022 hcl:#b6652a +iyr:2020 byr:1931 + +hgt:177cm iyr:2010 pid:934058099 +eyr:2020 +ecl:blu +byr:1967 +cid:112 hcl:#7d3b0c + +iyr:2028 +hgt:138 +cid:180 hcl:z +eyr:2022 pid:3286566621 byr:2002 + +eyr:2020 +iyr:2019 +hcl:#a97842 pid:149148750 ecl:brn hgt:159cm +byr:1981 cid:339 + +cid:344 +eyr:2021 byr:1968 pid:777786047 +ecl:grn hgt:192cm hcl:#888785 +iyr:2015 + +hgt:173cm +eyr:2030 +hcl:#733820 pid:610226642 byr:1954 cid:80 +iyr:2013 ecl:blu + +byr:1999 eyr:2023 +ecl:amb pid:912145128 +hgt:181cm +iyr:2015 hcl:#a97842 + +eyr:2027 hgt:188cm +pid:080715145 hcl:#341e13 iyr:2013 +ecl:oth +byr:1965 + +hgt:170cm byr:1950 iyr:2013 +pid:010541784 +eyr:2027 ecl:zzz +hcl:a3bae8 + +hgt:190cm eyr:2024 ecl:#6dcedc pid:909319684 +iyr:2011 byr:1959 hcl:z cid:182 + +eyr:2028 +iyr:2016 hcl:#623a2f pid:208417572 byr:1929 cid:137 ecl:hzl +hgt:167cm + +hcl:#6b5442 +ecl:grn +byr:1938 +eyr:2023 cid:307 +hgt:59in iyr:2014 pid:205268145 + +pid:047489285 eyr:2026 +hcl:#b6652a byr:1920 +iyr:2015 +hgt:183cm ecl:gry + +ecl:blu hcl:#508e8b iyr:2016 eyr:1954 hgt:151cm pid:086752750 byr:1920 + +iyr:2011 byr:1981 hgt:186cm +cid:117 hcl:#6b5442 ecl:amb +pid:756830713 eyr:2026 + +eyr:2037 pid:364464758 hcl:z ecl:grn +hgt:112 iyr:2013 byr:2022 + +ecl:hzl +cid:65 pid:679487194 +byr:1986 hgt:169cm hcl:#cfa07d eyr:2025 iyr:2013 + +cid:192 +byr:1921 pid:#5fe831 ecl:#fbb2b9 hgt:62cm eyr:1971 iyr:2024 +hcl:z + +hcl:#cfa07d eyr:2026 +hgt:74in +iyr:2019 +ecl:xry +pid:622690982 byr:1982 + +eyr:2026 pid:523515724 iyr:2013 byr:1973 hgt:167cm +ecl:grn hcl:#866857 + +byr:2009 +eyr:1985 pid:484497014 ecl:#0bfcf2 iyr:1992 cid:131 hcl:39d6b0 hgt:177in + +eyr:2020 iyr:2016 ecl:brn hcl:#ceb3a1 byr:1966 pid:696621560 cid:62 +hgt:59in + +hgt:166cm hcl:#7d3b0c +iyr:2016 +ecl:brn pid:190cm +eyr:2020 +byr:2001 + +eyr:2021 +iyr:2012 hcl:#6b5442 +ecl:amb hgt:169cm +pid:969150085 +byr:1925 + +ecl:brn hgt:175cm byr:1992 iyr:2016 pid:415209726 eyr:2027 +cid:72 hcl:#866857 + +iyr:2017 +hcl:#733820 byr:1938 eyr:2020 pid:274486958 hgt:163cm + +hcl:4f5dd1 cid:336 ecl:grn iyr:1931 pid:6212280197 +byr:2016 eyr:2037 +hgt:187in + +iyr:2017 byr:1940 eyr:2025 pid:115098205 hgt:151cm +ecl:grn +cid:122 +hcl:#6b5442 + +hcl:#efcc98 +iyr:2020 pid:709548547 hgt:179cm +eyr:2030 ecl:gry byr:1975 + +cid:217 hcl:#888785 eyr:2029 +ecl:hzl iyr:2013 pid:160053490 +hgt:166cm byr:1992 + +eyr:2024 cid:188 iyr:2016 hcl:ff3a59 ecl:xry pid:296357512 byr:2026 + +hgt:154cm iyr:2010 +ecl:blu pid:717041634 byr:1928 cid:123 +eyr:2027 +hcl:#a97842 + +pid:391011205 ecl:hzl hgt:191cm iyr:2016 eyr:2028 cid:281 byr:1934 + +byr:1937 hgt:65in +pid:667975382 ecl:gry cid:270 eyr:2024 +iyr:2012 + +hgt:179cm pid:065528723 +hcl:#888785 byr:1937 eyr:2028 +iyr:2013 ecl:hzl + +iyr:2027 cid:261 eyr:2037 ecl:#ced7d5 pid:157cm +hcl:3a80c1 byr:2029 hgt:187in + +eyr:2028 +hgt:157cm hcl:#733820 +iyr:2012 ecl:blu byr:1952 pid:915063263 cid:335 + +eyr:2023 hcl:#efcc98 pid:490625944 byr:1961 ecl:grn hgt:155cm iyr:2018 + +cid:247 pid:2807544665 eyr:2021 +ecl:oth +hgt:191cm +byr:1928 +iyr:2013 hcl:#623a2f + +eyr:2015 +byr:2021 +hcl:40d2fc hgt:69cm pid:159cm ecl:gmt + +hgt:175cm eyr:1992 cid:328 pid:263110997 ecl:#e53989 byr:2014 hcl:#a97842 iyr:2026 + +pid:491396731 eyr:2027 hgt:172cm hcl:#623a2f cid:92 iyr:2017 byr:1983 ecl:grn + +hcl:#fffffd +iyr:2018 byr:1983 pid:714591144 ecl:grn eyr:2021 +hgt:160cm + +eyr:2027 +hgt:63in ecl:blu byr:1987 pid:397963077 iyr:2018 hcl:#ceb3a1 + +eyr:2027 +hgt:184cm +hcl:#6b5442 iyr:2012 byr:1984 ecl:blu pid:196287205 + +iyr:1998 +ecl:hzl +pid:7872103596 byr:1991 +cid:275 eyr:2039 +hgt:174cm hcl:0d2ad6 + +iyr:2010 hcl:#efcc98 +byr:1992 hgt:65cm eyr:2038 pid:383236012 cid:68 ecl:lzr + +hgt:190in cid:127 +byr:1947 pid:515728209 hcl:#733820 iyr:2014 ecl:amb eyr:2020 + +iyr:2017 eyr:2028 +hcl:#623a2f +byr:1964 ecl:grn pid:198467794 hgt:169cm + +ecl:utc +hgt:59cm byr:2007 iyr:2030 +hcl:7ac4db eyr:2038 pid:#7206c6 + +iyr:2010 +hcl:z eyr:2021 ecl:brn +hgt:173 cid:86 +pid:194240791 byr:1975 + +pid:9347286034 +hgt:63cm +iyr:1992 eyr:2034 hcl:66031b ecl:grt byr:1929 + +pid:593398904 byr:1939 iyr:2019 hcl:#b6652a ecl:gry eyr:2023 +hgt:70cm + +byr:1991 +iyr:2019 hgt:164cm pid:282852411 cid:340 ecl:amb +hcl:#341e13 eyr:2027 + +eyr:2020 +iyr:2014 ecl:grn hcl:#866857 hgt:158cm +byr:1931 pid:321748597 + +cid:98 byr:2023 iyr:2019 pid:#48f79f +hcl:73c882 eyr:1973 hgt:151in +ecl:utc + +iyr:2023 +hcl:#18171d +pid:52221892 eyr:2039 +byr:2008 hgt:72cm ecl:#db8d14 + +iyr:1966 cid:274 +eyr:2034 pid:12256322 +byr:2006 ecl:dne +hcl:985c2d + +hcl:#fd033b +eyr:2026 ecl:blu +iyr:2016 +byr:1953 hgt:157cm +pid:502619036 + +byr:2015 pid:159cm iyr:2025 +hgt:158cm eyr:1943 hcl:z ecl:grn + +ecl:blu iyr:2016 +pid:842400950 +hcl:#733820 +cid:266 +eyr:2027 byr:1931 +hgt:161cm + +iyr:2017 hgt:190cm byr:1994 pid:706570967 +ecl:hzl hcl:#18171d +cid:180 + +cid:197 pid:204952666 ecl:amb +hgt:70in iyr:2016 byr:1936 hcl:#98cbe3 eyr:2025 + +pid:555499128 +byr:1971 hgt:71in +cid:83 ecl:blu +hcl:#cfa07d eyr:2027 + +ecl:hzl iyr:2014 +pid:30428184 cid:237 +hgt:171cm byr:1942 hcl:#888785 eyr:1986 + +eyr:2025 +pid:579385370 hgt:193cm +hcl:#c0946f byr:1979 iyr:2016 +ecl:amb cid:284 + +eyr:2029 byr:1946 pid:278271295 +ecl:grn +hcl:#cfa07d cid:271 +hgt:172cm +iyr:2020 + +pid:731752614 eyr:2020 byr:1983 +cid:248 ecl:oth hgt:179cm +iyr:2017 hcl:#fffffd + +hcl:z +cid:203 eyr:2032 ecl:#3f9d3d hgt:65cm pid:4042846885 byr:2019 +iyr:1946 + +hgt:171cm ecl:gry eyr:2027 +iyr:2013 +hcl:#7d3b0c pid:92288579 +byr:1955 + +ecl:brn hgt:164cm byr:1969 hcl:#cbf9c9 pid:022724981 eyr:2030 iyr:2013 cid:244 + +hgt:162cm byr:1974 iyr:2015 pid:927525094 hcl:#3d3011 ecl:blu +eyr:2023 + +hgt:157cm +eyr:2020 +pid:221286943 hcl:#fffffd ecl:amb iyr:2018 byr:1945 + +iyr:2019 +eyr:2025 byr:1997 pid:341544323 hgt:174cm cid:113 +ecl:hzl + +pid:138492032 hcl:e35302 ecl:#caaede +eyr:1931 +byr:2001 hgt:156 iyr:1998 + +pid:912182030 cid:189 hgt:162 hcl:#277b39 +iyr:2013 eyr:2023 byr:2023 ecl:blu + +eyr:2027 hcl:#fffffd +ecl:brn +cid:304 iyr:2016 byr:1969 +pid:866607511 hgt:192cm + +hgt:64in +ecl:amb +byr:1958 +pid:720439412 +iyr:2015 eyr:2022 hcl:#ceb3a1 + +eyr:2024 hgt:159cm +pid:187867283 iyr:2016 +ecl:oth hcl:#fffffd +byr:1988 + +ecl:#910bf2 byr:1969 iyr:2011 hcl:z eyr:2024 pid:579502502 +cid:103 hgt:174cm + +pid:718692455 +eyr:2028 +iyr:2016 +hcl:#602927 +ecl:blu byr:1954 +cid:251 hgt:182cm + +eyr:2021 hcl:#341e13 ecl:amb +byr:1933 hgt:179cm iyr:2011 pid:083172316 + +iyr:1998 hcl:z eyr:1944 +byr:2006 pid:453368738 +hgt:160 ecl:#9da5f1 cid:261 + +hcl:#7d3b0c +iyr:2018 +hgt:164cm eyr:2020 byr:1940 ecl:blu + +pid:993701676 eyr:2028 ecl:gry +byr:1951 hcl:#888785 cid:116 +iyr:2020 +hgt:192cm + +hcl:z eyr:2033 +ecl:lzr iyr:2029 cid:326 hgt:68cm byr:2026 +pid:96742419 + +hcl:#a97842 ecl:brn +byr:1920 +hgt:173cm iyr:2015 +eyr:2024 pid:176967666 + +byr:1930 eyr:2025 pid:792694131 +hgt:179cm ecl:brn +hcl:#a97842 +iyr:2015 + +hgt:167cm byr:1960 eyr:2022 hcl:#efcc98 +cid:87 ecl:blu iyr:2012 +pid:431515059 + +hcl:#cfa07d +eyr:2023 +hgt:188cm ecl:grn pid:081575957 byr:1938 iyr:2012 + +iyr:2010 byr:1973 +cid:108 +eyr:2026 +pid:880191154 hcl:#888785 hgt:181cm +ecl:brn + +eyr:2021 iyr:2010 byr:1942 hcl:#7d3b0c ecl:hzl pid:886241926 hgt:171cm + +cid:53 byr:1993 +pid:150cm eyr:2035 +hcl:#888785 hgt:153cm ecl:#128262 iyr:2021 + +ecl:gry +pid:555911148 +hcl:#733820 eyr:2022 hgt:154cm iyr:2012 +byr:1935 cid:338 + +hcl:#b6652a +pid:833873846 iyr:2012 +hgt:167cm eyr:2023 byr:1984 + +eyr:2024 +ecl:blu byr:1955 +hcl:#b6652a pid:517975316 iyr:2010 hgt:166cm + +pid:133785752 +ecl:blu +eyr:2024 +byr:1973 +iyr:2019 hcl:#fffffd +cid:236 hgt:173cm + +cid:222 +byr:2013 hcl:z eyr:2036 pid:7443967478 ecl:brn +iyr:2030 hgt:62cm + +hgt:193cm cid:259 +hcl:#18171d +ecl:grn +byr:1995 pid:727880050 eyr:2030 iyr:2010 + +hcl:#c0946f cid:275 eyr:1954 pid:772184635 ecl:#76add7 byr:2009 iyr:2018 hgt:151cm + +ecl:#52ed0f eyr:2033 hcl:#18171d pid:475397948 +byr:1946 iyr:2028 hgt:178cm + +iyr:2012 hgt:152cm +eyr:2027 byr:1923 ecl:brn +hcl:#18171d pid:513722888 cid:171 + +iyr:2029 +hgt:111 hcl:z ecl:#33e3bc eyr:1930 +byr:1934 pid:94036732 + +hgt:154cm eyr:2024 hcl:#6b5442 iyr:2017 +byr:1974 +ecl:amb pid:470968353 cid:345 + +hgt:184cm hcl:#617375 eyr:2028 +byr:1975 ecl:oth +iyr:2018 pid:735589126 + +cid:261 +hcl:#cfa07d pid:213013397 +hgt:187cm +ecl:gry iyr:2016 + +hcl:#623a2f +ecl:#34964b eyr:2009 pid:169cm byr:2028 hgt:169cm +iyr:2028 + +eyr:2029 iyr:2016 +byr:1985 +hgt:192cm hcl:#602927 cid:167 +ecl:blu pid:620818510 + +eyr:2029 +byr:1968 +ecl:blu +hgt:183cm iyr:2011 pid:952376140 hcl:#efcc98 + +iyr:2020 +byr:1981 pid:850136149 eyr:2028 hgt:159cm hcl:#7d3b0c +ecl:brn + +ecl:brn pid:480452858 hgt:65in cid:340 eyr:2022 +byr:1946 +hcl:#602927 iyr:2015 + +hgt:172 hcl:z eyr:1958 iyr:1941 byr:2019 pid:389995951 ecl:dne + +byr:2025 hcl:4c8dcd +hgt:177in +ecl:#55d635 +cid:197 pid:91192572 +iyr:1921 eyr:2038 + +iyr:2027 pid:154cm +hgt:185in byr:2012 +eyr:2036 hcl:efd47d +ecl:#64f98d +cid:86 + +eyr:2029 pid:837224515 ecl:grn cid:231 hcl:#733820 iyr:2019 +hgt:159cm +byr:1977 + +pid:974518338 byr:1964 hcl:#cfa07d ecl:grn eyr:2030 +hgt:61in +iyr:2019 + +iyr:2019 +hgt:192in cid:94 +eyr:1922 +byr:1925 hcl:z ecl:utc pid:#081266 + +eyr:2027 iyr:2019 cid:328 byr:1961 hcl:#6b5442 ecl:blu hgt:177cm pid:235426720 + +byr:1959 +eyr:2025 +pid:890034625 ecl:oth +hgt:62in cid:348 hcl:#733820 + +hgt:161cm iyr:2018 pid:916160791 ecl:grn +byr:1951 hcl:#44d03a eyr:2025 + +hgt:158cm byr:1942 iyr:2012 hcl:#602927 +eyr:2026 ecl:gry pid:651231060 + +ecl:hzl cid:340 pid:086942161 byr:1986 hcl:#a97842 iyr:2018 +eyr:2028 +hgt:181cm + +ecl:blu +pid:278922687 cid:238 iyr:2018 hgt:153cm eyr:2027 +byr:1965 +hcl:#733820 + +eyr:2023 cid:208 hgt:178cm hcl:#341e13 byr:1937 pid:290981079 iyr:2010 ecl:grn + +hcl:#888785 +ecl:amb +byr:1943 pid:559804716 eyr:2026 hgt:166cm +iyr:2019 + +pid:947831563 +ecl:gry +byr:1960 hcl:#341e13 +iyr:2016 hgt:173cm eyr:2029 + +ecl:blu iyr:2016 pid:724632073 hcl:#623a2f +eyr:2028 hgt:192cm byr:1958 + +byr:2021 +eyr:2016 hcl:z iyr:1988 pid:65353943 +ecl:#bb553b +hgt:125 + +hcl:#efcc98 byr:1963 pid:290433211 eyr:2023 ecl:hzl +hgt:172cm iyr:2013 + +iyr:2015 ecl:brn +byr:2023 hcl:#18171d +pid:325330679 +hgt:190in eyr:2023 + +pid:745674970 hgt:160cm eyr:2021 byr:1925 ecl:gry hcl:#341e13 iyr:2015 +cid:297 + +eyr:2021 +pid:596411633 +byr:1947 ecl:blu cid:191 hcl:#341e13 hgt:168cm iyr:2019 + +eyr:2030 pid:#902a6b iyr:1997 hcl:11f396 hgt:188cm byr:2025 +ecl:dne + +eyr:2025 +byr:2006 +hcl:#888785 ecl:hzl hgt:187cm +iyr:2012 pid:017702828 + +byr:1988 hcl:#18171d iyr:2019 +pid:110591871 +ecl:hzl +hgt:160cm +eyr:2029 + +ecl:brn +hcl:#c0946f iyr:2030 pid:264404022 byr:1984 hgt:59cm eyr:2040 + +pid:5973803069 +hcl:#cfa07d ecl:grt +hgt:153cm eyr:2039 byr:1970 +iyr:2025 + +hcl:#fffffd +iyr:2022 byr:2026 +hgt:180 pid:82035145 eyr:2034 cid:118 ecl:utc + +hgt:186cm eyr:2026 +ecl:brn +iyr:2013 hcl:#8f4c9b pid:010260339 byr:1948 + +ecl:amb hcl:#18171d iyr:2020 pid:259501214 byr:1978 hgt:193cm +cid:263 eyr:2022 + +hgt:161cm iyr:2015 byr:2014 eyr:2003 +pid:708958872 ecl:grt +hcl:f4a430 + +hgt:170cm eyr:2021 pid:911638274 cid:110 byr:1963 ecl:blu +iyr:2015 hcl:1eda64 + +ecl:oth byr:1949 hgt:174cm hcl:#18171d eyr:2022 iyr:2019 +pid:305857230 + +ecl:gry hcl:#a97842 pid:971971076 byr:2002 iyr:2019 +hgt:188cm +eyr:2022 cid:238 + +eyr:2027 pid:221315043 iyr:2010 hgt:159cm ecl:blu byr:1998 hcl:#6b5442 + +hcl:#888785 +byr:1926 eyr:2022 pid:433807814 ecl:grn +iyr:2010 +hgt:181cm + +ecl:grn hgt:164cm byr:1951 hcl:#18171d cid:75 pid:845508281 eyr:2021 iyr:2017 + +pid:#f59bc7 +eyr:1987 hgt:191cm hcl:z byr:2024 +iyr:1985 + +hcl:#623a2f pid:497429747 +hgt:189cm +byr:1987 +eyr:2027 iyr:2012 cid:95 ecl:hzl + +byr:2000 +hgt:165cm +iyr:2017 pid:519443292 eyr:2029 cid:240 hcl:#a97842 +ecl:blu + +cid:67 pid:038299774 +eyr:2023 iyr:2015 hgt:179cm byr:1941 hcl:#18171d ecl:amb + +byr:2000 +eyr:2025 ecl:oth iyr:2017 +pid:334154607 +hcl:#fffffd hgt:173cm + +hcl:#888785 ecl:amb +cid:131 iyr:2018 byr:1996 eyr:2026 +hgt:180cm pid:709543988 + +iyr:1988 +pid:263277424 +hcl:ee8912 byr:1942 ecl:gry eyr:2040 hgt:161cm + +eyr:2020 byr:1966 iyr:2020 hgt:169cm pid:611918000 +hcl:#7d3b0c ecl:hzl + +hgt:164cm ecl:brn +iyr:2015 pid:192054454 hcl:#6b5442 byr:1987 eyr:2022 + +byr:1952 +ecl:zzz +pid:215953654 +eyr:2021 hcl:#efcc98 hgt:153cm iyr:2026 + +hgt:167cm +hcl:#b6652a pid:847614726 +eyr:2022 ecl:gry byr:1990 iyr:2015 + +hgt:185cm ecl:oth iyr:2012 +byr:1933 +cid:250 +pid:038674023 +hcl:#c0946f + +pid:613273980 hcl:#a97842 +ecl:oth byr:1924 hgt:179cm +eyr:2027 iyr:1950 + +hcl:#cfa07d byr:2018 hgt:190cm pid:64530329 +ecl:brn +iyr:2024 + +hcl:z hgt:70cm pid:18807747 +cid:284 byr:2023 +eyr:2035 ecl:#4a1501 +iyr:1954 + +iyr:2016 hgt:152cm pid:886247173 byr:1940 hcl:#c0946f eyr:2027 ecl:oth cid:150 + +hgt:152cm hcl:#48cfdf eyr:2025 cid:277 +ecl:oth pid:246230621 byr:1932 +iyr:2020 + +ecl:amb pid:871180042 +cid:117 hcl:#602927 iyr:2011 hgt:152cm +eyr:2030 byr:1999 + +eyr:2024 ecl:hzl hgt:171cm +byr:1934 pid:356408125 iyr:2019 hcl:#b6652a +cid:169 + +eyr:2023 +hcl:#7d3b0c +byr:1934 hgt:67in ecl:oth pid:191785527 +cid:117 iyr:2016 + +iyr:2029 +hcl:#602927 eyr:2022 byr:1931 ecl:oth hgt:192cm +pid:231475143 + +ecl:grn iyr:2014 cid:250 hcl:#b6652a byr:1970 pid:675238417 hgt:162cm +eyr:2026 + +ecl:brn +hcl:#623a2f eyr:2021 pid:293293433 hgt:158 byr:1977 iyr:2019 + +ecl:oth hcl:#ceb3a1 pid:013111996 eyr:2023 hgt:180cm byr:1976 cid:224 + +hgt:61cm +eyr:2027 ecl:amb pid:181cm iyr:1932 +byr:1974 +hcl:#18171d + +byr:1968 hgt:167cm +hcl:#a97842 eyr:2022 iyr:2018 ecl:hzl pid:940968694 + +iyr:1943 +hgt:96 +cid:229 +hcl:z eyr:1990 byr:2007 pid:#25aa73 +ecl:#74592e + +hgt:182cm iyr:2018 ecl:hzl eyr:2029 byr:1946 pid:602345030 +hcl:#ceb3a1 + +pid:750306036 eyr:2020 hgt:181in ecl:xry +iyr:2011 hcl:z byr:1971 cid:71 + +pid:183825747 iyr:2019 hcl:#6b5442 +byr:1974 +hgt:180cm eyr:2028 +ecl:amb + +ecl:brn cid:200 pid:576495225 +byr:1924 +hcl:#efcc98 eyr:2022 iyr:2017 hgt:185cm + +iyr:2020 hgt:167cm byr:1965 ecl:brn hcl:#888785 +eyr:2028 pid:752062953 + +byr:2026 +hcl:z +eyr:2020 +ecl:#b4ec74 pid:187cm iyr:1974 +cid:326 hgt:150cm + +byr:1996 pid:507323629 +iyr:2015 cid:347 eyr:2026 hcl:#efcc98 +ecl:amb hgt:157cm + +byr:2017 pid:456780590 hcl:#888785 eyr:1966 ecl:amb iyr:2023 cid:187 hgt:62cm + +ecl:hzl iyr:2015 hcl:#6b5442 hgt:152cm eyr:2028 byr:1982 pid:003269467 + +iyr:2017 eyr:2026 +ecl:blu cid:70 hcl:#7d3b0c +byr:1966 pid:160330947 hgt:189cm + +iyr:2010 ecl:amb +hgt:164cm eyr:2029 byr:1963 +pid:596606374 hcl:#efcc98 + +hcl:#fffffd cid:277 pid:102326370 hgt:154cm eyr:2026 iyr:2012 byr:1968 +ecl:hzl + +ecl:oth pid:477189554 hcl:#6b5442 eyr:2022 byr:1948 hgt:74in cid:181 +iyr:2016 + +hgt:169cm hcl:#d7bc93 +cid:344 ecl:oth +pid:#09c55d iyr:2017 +eyr:2030 byr:1928 + +hcl:5d02ff ecl:#ca7901 iyr:1959 byr:2006 eyr:2022 +hgt:164in +pid:#d6cdfd + +ecl:amb pid:5739190196 eyr:2021 hgt:157in hcl:#efcc98 byr:2018 iyr:2028 + +byr:1995 ecl:hzl +iyr:2017 +hcl:#a97842 pid:917039291 eyr:2026 hgt:175cm + +iyr:2017 pid:756519868 +hcl:#623a2f +eyr:2028 +hgt:158cm +ecl:amb byr:1957 + +iyr:2012 +hgt:158cm +byr:2014 pid:973021666 hcl:f04766 eyr:2035 ecl:utc + +ecl:blu +byr:1989 eyr:2022 +pid:520765501 +cid:200 hgt:193cm hcl:#a97842 iyr:2011 + +byr:1959 +ecl:blu hcl:#733820 cid:284 hgt:162cm +eyr:2022 pid:751629408 iyr:2016 + +byr:1978 cid:301 +ecl:oth hgt:67cm hcl:#888785 +eyr:2040 iyr:2025 pid:26038514 + +iyr:2020 byr:1974 hgt:163cm ecl:blu hcl:#7d3b0c eyr:2028 cid:99 + +hcl:#a97842 +hgt:186cm +ecl:grn byr:1969 pid:460360492 iyr:2011 eyr:2028 + +byr:2009 +pid:489490924 eyr:2031 +hcl:cb5351 ecl:#083a25 hgt:164cm + +iyr:2019 +hcl:3463cc ecl:amb pid:4089063078 eyr:2022 hgt:150cm +byr:2007 + +eyr:2028 hcl:#ceb3a1 +hgt:191cm iyr:2019 pid:737842199 ecl:blu cid:268 byr:1925 + +pid:868397851 +hcl:#efcc98 ecl:grn iyr:2017 eyr:2021 byr:1943 +hgt:179cm + +hcl:#623a2f byr:1987 eyr:2023 iyr:2019 hgt:152cm +pid:473569020 +ecl:grn + +pid:953968630 +hgt:175cm +byr:1971 ecl:blu hcl:#623a2f iyr:2017 cid:336 eyr:2030 + +ecl:grt hgt:74cm byr:2022 eyr:2024 pid:39114027 +iyr:2026 hcl:4b5675 + +pid:#492988 +eyr:2032 hgt:63cm iyr:2006 +ecl:#817211 byr:2019 + +pid:800367032 hcl:#341e13 +ecl:#765111 iyr:2012 byr:2006 hgt:166cm cid:291 eyr:2027 + +eyr:2021 iyr:2012 pid:876581393 ecl:amb hcl:#866857 +hgt:64in byr:1993 + +iyr:2017 byr:1996 ecl:hzl pid:038990744 +eyr:2028 +hgt:177cm +hcl:#c0946f + +hcl:#4214a6 +eyr:2021 +iyr:2019 cid:72 byr:1939 +ecl:hzl pid:783071912 hgt:187cm + +eyr:2020 hgt:158cm +pid:274060737 cid:277 +iyr:2015 hcl:#bf9b5e byr:1950 ecl:brn + +byr:1921 hcl:#7d3b0c cid:329 hgt:155cm eyr:2030 pid:718399669 iyr:2011 ecl:brn + +cid:147 eyr:2021 hgt:167cm iyr:2010 ecl:grn byr:1975 hcl:#6b5442 +pid:285479783 + +hgt:187cm +byr:2004 eyr:2025 hcl:bb331b +pid:851189955 iyr:2016 +ecl:amb + +hcl:#94007d pid:361561551 byr:1927 eyr:2026 iyr:2020 +ecl:gry hgt:158cm + +byr:1993 pid:#24c4af iyr:2023 hgt:175cm eyr:2028 +hcl:z ecl:hzl cid:308 + +byr:1985 hcl:#c0946f eyr:2034 hgt:172cm +cid:300 iyr:2013 ecl:gry pid:389455676 + +eyr:2030 iyr:2017 byr:1956 hgt:178cm +pid:864401853 hcl:#6b5442 + +pid:836559549 +iyr:2011 +hgt:167cm +ecl:amb hcl:#c0946f +eyr:2026 byr:1981 + +pid:111085991 iyr:2011 +ecl:blu eyr:2026 cid:311 +byr:1920 hgt:182cm hcl:#602927 + +ecl:oth pid:284436132 +byr:1929 cid:121 +eyr:2027 +iyr:2010 +hgt:75in +hcl:#6b5442 + +byr:1987 +hcl:#7d3b0c iyr:2018 hgt:180cm +ecl:blu eyr:2029 pid:878348021 + +hgt:183cm cid:98 +byr:1953 hcl:#866857 eyr:2021 iyr:2012 pid:158898193 + +eyr:2030 pid:039638764 ecl:hzl hgt:190cm byr:1926 +cid:294 hcl:#b6652a iyr:2017 \ No newline at end of file diff --git a/day04/solution.spec.ts b/day04/solution.spec.ts new file mode 100644 index 0000000..314b9b7 --- /dev/null +++ b/day04/solution.spec.ts @@ -0,0 +1,20 @@ +import { loader } from '../lib/loader' +import { parsePassportList } from './parsePassportList' +import { validatePassport } from './validatePassport' + +const load = loader(4) +const sample = load('sample') +const input = load('input') + +describe('Day 4: Passport Processing', () => { + describe('Part 1', () => { + it('should solve the sample', () => { + expect(parsePassportList(sample).filter(validatePassport)).toHaveLength(2) + }) + it('should solve', () => { + expect(parsePassportList(input).filter(validatePassport)).toHaveLength( + 250, + ) + }) + }) +}) From 0e0ece4e945e8b5ea745ce56cc3e875d3dd4901a Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Fri, 4 Dec 2020 09:37:12 +0100 Subject: [PATCH 16/60] feat(day04): part 2 sample --- day04/parsePassportList.ts | 13 ++++++------ day04/solution.spec.ts | 43 ++++++++++++++++++++++++++++++++++++-- day04/validatePassport.ts | 30 ++++++++++++++++++++++++++ lib/loader.ts | 16 ++++++++------ 4 files changed, 88 insertions(+), 14 deletions(-) diff --git a/day04/parsePassportList.ts b/day04/parsePassportList.ts index ef7d95e..0e68b88 100644 --- a/day04/parsePassportList.ts +++ b/day04/parsePassportList.ts @@ -4,13 +4,14 @@ export const parsePassportList = (input: string[]): Record[] => if (line.length === 0) list.push({}) list[list.length - 1] = { ...list[list.length - 1], - ...line.split(' ').reduce( - (props, entry) => ({ + ...line.split(' ').reduce((props, entry) => { + const [k, v] = entry.split(':') + if (v === undefined) return props + return { ...props, - [entry.split(':')[0]]: entry.split(':')[1], - }), - {}, - ), + [k]: v, + } + }, {}), } return list }, diff --git a/day04/solution.spec.ts b/day04/solution.spec.ts index 314b9b7..6aade91 100644 --- a/day04/solution.spec.ts +++ b/day04/solution.spec.ts @@ -1,6 +1,6 @@ -import { loader } from '../lib/loader' +import { loader, loadString } from '../lib/loader' import { parsePassportList } from './parsePassportList' -import { validatePassport } from './validatePassport' +import { validatePassport, validatePassportStrict } from './validatePassport' const load = loader(4) const sample = load('sample') @@ -17,4 +17,43 @@ describe('Day 4: Passport Processing', () => { ) }) }) + describe('Part 2', () => { + it('should solve the invalid passports sample', () => { + expect( + parsePassportList( + loadString(`eyr:1972 cid:100 + hcl:#18171d ecl:amb hgt:170 pid:186cm iyr:2018 byr:1926 + + iyr:2019 + hcl:#602927 eyr:1967 hgt:170cm + ecl:grn pid:012533040 byr:1946 + + hcl:dab227 iyr:2012 + ecl:brn hgt:182cm pid:021572410 eyr:2020 byr:1992 cid:277 + + hgt:59cm ecl:zzz + eyr:2038 hcl:74454a iyr:2023 + pid:3556412378 byr:2007`), + ).filter(validatePassportStrict), + ).toHaveLength(0) + }) + it('should solve the valid passports sample', () => { + expect( + parsePassportList( + loadString(`pid:087499704 hgt:74in ecl:grn iyr:2012 eyr:2030 byr:1980 + hcl:#623a2f + + eyr:2029 ecl:blu cid:129 byr:1989 + iyr:2014 pid:896056539 hcl:#a97842 hgt:165cm + + hcl:#888785 + hgt:164cm byr:2001 iyr:2015 cid:88 + pid:545766238 ecl:hzl + eyr:2022 + + iyr:2010 hgt:158cm hcl:#b6652a ecl:blu byr:1944 eyr:2021 pid:093154719`), + ).filter(validatePassportStrict), + ).toHaveLength(4) + }) + }) }) diff --git a/day04/validatePassport.ts b/day04/validatePassport.ts index 9c185c3..fd0f927 100644 --- a/day04/validatePassport.ts +++ b/day04/validatePassport.ts @@ -13,3 +13,33 @@ export const validatePassport = (p: Record): boolean => { if (!('hgt' in p)) return false return true } + +export const validatePassportStrict = (p: Record): boolean => { + if (!validatePassport(p)) return false + // byr (Birth Year) - four digits; at least 1920 and at most 2002. + const byr = parseInt(p.byr, 10) + if (byr < 1920 || byr > 2002) return false + // iyr (Issue Year) - four digits; at least 2010 and at most 2020. + const iyr = parseInt(p.iyr, 10) + if (iyr < 2010 || iyr > 2020) return false + // eyr (Expiration Year) - four digits; at least 2020 and at most 2030. + const eyr = parseInt(p.eyr, 10) + if (eyr < 2020 || eyr > 2030) return false + // hgt (Height) - a number followed by either cm or in: + const hgt = /^([0-9]+)(cm|in)$/.exec(p.hgt) + if (hgt === null) return false + const hgtValue = parseInt(hgt[0], 10) + // If cm, the number must be at least 150 and at most 193. + if (hgt[1] === 'cm' && (hgtValue < 150 || hgtValue > 193)) return false + // If in, the number must be at least 59 and at most 76. + if (hgt[1] === 'in' && (hgtValue < 59 || hgtValue > 76)) return false + // hcl (Hair Color) - a # followed by exactly six characters 0-9 or a-f. + if (!/^#[0-9a-f]{6}$/.test(p.hcl)) return false + // ecl (Eye Color) - exactly one of: amb blu brn gry grn hzl oth. + if (!['amb', 'blu', 'brn', 'gry', 'grn', 'hzl', 'oth'].includes(p.ecl)) + return false + // pid (Passport ID) - a nine-digit number, including leading zeroes. + if (!/^[0-9]{9}$/.test(p.pid)) return false + // cid (Country ID) - ignored, missing or not. + return true +} diff --git a/lib/loader.ts b/lib/loader.ts index f2142ce..5378c92 100644 --- a/lib/loader.ts +++ b/lib/loader.ts @@ -1,16 +1,20 @@ import * as fs from 'fs' import * as path from 'path' +export const loadString = (s: string): string[] => + s + .trim() + .split('\n') + .map((s) => s.trim()) + export const loader = (day: number) => (file: string): string[] => - fs - .readFileSync( + loadString( + fs.readFileSync( path.resolve( process.cwd(), `day${day.toString().padStart(2, '0')}`, `${file}.txt`, ), 'utf-8', - ) - .trim() - .split('\n') - .map((s) => s.trim()) + ), + ) From e43c23fc26ef20209c4e68476bba7a90e8b159fb Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Fri, 4 Dec 2020 10:17:19 +0100 Subject: [PATCH 17/60] feat(day04): part 2 --- day04/input.txt | 2 +- day04/solution.spec.ts | 90 +++++++++++++++++++++++++++------------ day04/validatePassport.ts | 6 +-- 3 files changed, 66 insertions(+), 32 deletions(-) diff --git a/day04/input.txt b/day04/input.txt index 9b04221..127dae0 100644 --- a/day04/input.txt +++ b/day04/input.txt @@ -1118,4 +1118,4 @@ hgt:183cm cid:98 byr:1953 hcl:#866857 eyr:2021 iyr:2012 pid:158898193 eyr:2030 pid:039638764 ecl:hzl hgt:190cm byr:1926 -cid:294 hcl:#b6652a iyr:2017 \ No newline at end of file +cid:294 hcl:#b6652a iyr:2017 diff --git a/day04/solution.spec.ts b/day04/solution.spec.ts index 6aade91..eb376db 100644 --- a/day04/solution.spec.ts +++ b/day04/solution.spec.ts @@ -18,42 +18,76 @@ describe('Day 4: Passport Processing', () => { }) }) describe('Part 2', () => { - it('should solve the invalid passports sample', () => { + it('should solve the sample', () => { expect( parsePassportList( loadString(`eyr:1972 cid:100 - hcl:#18171d ecl:amb hgt:170 pid:186cm iyr:2018 byr:1926 - - iyr:2019 - hcl:#602927 eyr:1967 hgt:170cm - ecl:grn pid:012533040 byr:1946 - - hcl:dab227 iyr:2012 - ecl:brn hgt:182cm pid:021572410 eyr:2020 byr:1992 cid:277 - - hgt:59cm ecl:zzz - eyr:2038 hcl:74454a iyr:2023 - pid:3556412378 byr:2007`), - ).filter(validatePassportStrict), - ).toHaveLength(0) - }) - it('should solve the valid passports sample', () => { - expect( - parsePassportList( - loadString(`pid:087499704 hgt:74in ecl:grn iyr:2012 eyr:2030 byr:1980 - hcl:#623a2f + hcl:#18171d ecl:amb hgt:170 pid:186cm iyr:2018 byr:1926 + + iyr:2019 + hcl:#602927 eyr:1967 hgt:170cm + ecl:grn pid:012533040 byr:1946 + + hcl:dab227 iyr:2012 + ecl:brn hgt:182cm pid:021572410 eyr:2020 byr:1992 cid:277 + + hgt:59cm ecl:zzz + eyr:2038 hcl:74454a iyr:2023 + pid:3556412378 byr:2007 + + pid:087499704 hgt:74in ecl:grn iyr:2012 eyr:2030 byr:1980 + hcl:#623a2f - eyr:2029 ecl:blu cid:129 byr:1989 - iyr:2014 pid:896056539 hcl:#a97842 hgt:165cm + eyr:2029 ecl:blu cid:129 byr:1989 + iyr:2014 pid:896056539 hcl:#a97842 hgt:165cm - hcl:#888785 - hgt:164cm byr:2001 iyr:2015 cid:88 - pid:545766238 ecl:hzl - eyr:2022 + hcl:#888785 + hgt:164cm byr:2001 iyr:2015 cid:88 + pid:545766238 ecl:hzl + eyr:2022 - iyr:2010 hgt:158cm hcl:#b6652a ecl:blu byr:1944 eyr:2021 pid:093154719`), + iyr:2010 hgt:158cm hcl:#b6652a ecl:blu byr:1944 eyr:2021 pid:093154719`), ).filter(validatePassportStrict), ).toHaveLength(4) }) + + it.each([ + [{ byr: '2002' }, true], + [{ byr: '2003' }, false], + [{ hgt: '60in' }, true], + [{ hgt: '190cm' }, true], + [{ hgt: '190in' }, false], + [{ hgt: '190' }, false], + [{ hcl: '#123abc' }, true], + [{ hcl: '#123abz' }, false], + [{ hcl: '123abc' }, false], + [{ ecl: 'brn' }, true], + [{ ecl: 'wat' }, false], + [{ pid: '000000001' }, true], + [{ pid: '0123456789' }, false], + ])(`should pass sample properties %s %s`, (props, isValid) => { + const valid = { + eyr: '2024', + pid: '662406624', + hcl: '#cfa07d', + byr: '1947', + iyr: '2015', + ecl: 'amb', + hgt: '150cm', + } + + expect(validatePassportStrict(valid)).toEqual(true) + expect( + validatePassportStrict({ + ...valid, + ...props, + }), + ).toEqual(isValid) + }) + + it('should solve', () => { + const v = parsePassportList(input).filter(validatePassportStrict) + expect(v).toHaveLength(158) + }) }) }) diff --git a/day04/validatePassport.ts b/day04/validatePassport.ts index fd0f927..4447133 100644 --- a/day04/validatePassport.ts +++ b/day04/validatePassport.ts @@ -28,11 +28,11 @@ export const validatePassportStrict = (p: Record): boolean => { // hgt (Height) - a number followed by either cm or in: const hgt = /^([0-9]+)(cm|in)$/.exec(p.hgt) if (hgt === null) return false - const hgtValue = parseInt(hgt[0], 10) + const hgtValue = parseInt(hgt[1], 10) // If cm, the number must be at least 150 and at most 193. - if (hgt[1] === 'cm' && (hgtValue < 150 || hgtValue > 193)) return false + if (hgt[2] === 'cm' && (hgtValue < 150 || hgtValue > 193)) return false // If in, the number must be at least 59 and at most 76. - if (hgt[1] === 'in' && (hgtValue < 59 || hgtValue > 76)) return false + if (hgt[2] === 'in' && (hgtValue < 59 || hgtValue > 76)) return false // hcl (Hair Color) - a # followed by exactly six characters 0-9 or a-f. if (!/^#[0-9a-f]{6}$/.test(p.hcl)) return false // ecl (Eye Color) - exactly one of: amb blu brn gry grn hzl oth. From dd5d08672ea1aec93623eb6004011275f183d417 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Fri, 4 Dec 2020 10:44:09 +0100 Subject: [PATCH 18/60] refactor(day04): improve naming --- day04/validatePassport.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/day04/validatePassport.ts b/day04/validatePassport.ts index 4447133..02e141f 100644 --- a/day04/validatePassport.ts +++ b/day04/validatePassport.ts @@ -29,10 +29,11 @@ export const validatePassportStrict = (p: Record): boolean => { const hgt = /^([0-9]+)(cm|in)$/.exec(p.hgt) if (hgt === null) return false const hgtValue = parseInt(hgt[1], 10) + const hgtUnit = hgt[2] // If cm, the number must be at least 150 and at most 193. - if (hgt[2] === 'cm' && (hgtValue < 150 || hgtValue > 193)) return false + if (hgtUnit === 'cm' && (hgtValue < 150 || hgtValue > 193)) return false // If in, the number must be at least 59 and at most 76. - if (hgt[2] === 'in' && (hgtValue < 59 || hgtValue > 76)) return false + if (hgtUnit === 'in' && (hgtValue < 59 || hgtValue > 76)) return false // hcl (Hair Color) - a # followed by exactly six characters 0-9 or a-f. if (!/^#[0-9a-f]{6}$/.test(p.hcl)) return false // ecl (Eye Color) - exactly one of: amb blu brn gry grn hzl oth. From c62fcc12940c188cb43c87b1b520d91a53597c90 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Fri, 4 Dec 2020 14:38:52 +0100 Subject: [PATCH 19/60] refactor(day04): move strict tests --- day04/solution.spec.ts | 34 ------------------------------ day04/validatePassport.spec.ts | 38 +++++++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 35 deletions(-) diff --git a/day04/solution.spec.ts b/day04/solution.spec.ts index eb376db..fd1774f 100644 --- a/day04/solution.spec.ts +++ b/day04/solution.spec.ts @@ -51,40 +51,6 @@ describe('Day 4: Passport Processing', () => { ).toHaveLength(4) }) - it.each([ - [{ byr: '2002' }, true], - [{ byr: '2003' }, false], - [{ hgt: '60in' }, true], - [{ hgt: '190cm' }, true], - [{ hgt: '190in' }, false], - [{ hgt: '190' }, false], - [{ hcl: '#123abc' }, true], - [{ hcl: '#123abz' }, false], - [{ hcl: '123abc' }, false], - [{ ecl: 'brn' }, true], - [{ ecl: 'wat' }, false], - [{ pid: '000000001' }, true], - [{ pid: '0123456789' }, false], - ])(`should pass sample properties %s %s`, (props, isValid) => { - const valid = { - eyr: '2024', - pid: '662406624', - hcl: '#cfa07d', - byr: '1947', - iyr: '2015', - ecl: 'amb', - hgt: '150cm', - } - - expect(validatePassportStrict(valid)).toEqual(true) - expect( - validatePassportStrict({ - ...valid, - ...props, - }), - ).toEqual(isValid) - }) - it('should solve', () => { const v = parsePassportList(input).filter(validatePassportStrict) expect(v).toHaveLength(158) diff --git a/day04/validatePassport.spec.ts b/day04/validatePassport.spec.ts index 9861ee0..3254311 100644 --- a/day04/validatePassport.spec.ts +++ b/day04/validatePassport.spec.ts @@ -1,4 +1,4 @@ -import { validatePassport } from './validatePassport' +import { validatePassport, validatePassportStrict } from './validatePassport' describe('validatePassport', () => { it.each([ @@ -54,3 +54,39 @@ describe('validatePassport', () => { expect(validatePassport(passport)).toEqual(valid), ) }) + +describe('validatePassportStrict', () => { + it.each([ + [{ byr: '2002' }, true], + [{ byr: '2003' }, false], + [{ hgt: '60in' }, true], + [{ hgt: '190cm' }, true], + [{ hgt: '190in' }, false], + [{ hgt: '190' }, false], + [{ hcl: '#123abc' }, true], + [{ hcl: '#123abz' }, false], + [{ hcl: '123abc' }, false], + [{ ecl: 'brn' }, true], + [{ ecl: 'wat' }, false], + [{ pid: '000000001' }, true], + [{ pid: '0123456789' }, false], + ])(`should pass sample properties %s %s`, (props, isValid) => { + const valid = { + eyr: '2024', + pid: '662406624', + hcl: '#cfa07d', + byr: '1947', + iyr: '2015', + ecl: 'amb', + hgt: '150cm', + } + + expect(validatePassportStrict(valid)).toEqual(true) + expect( + validatePassportStrict({ + ...valid, + ...props, + }), + ).toEqual(isValid) + }) +}) From a7fd716c872af6cff4db41b43430e29400e94721 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Sat, 5 Dec 2020 11:22:49 +0100 Subject: [PATCH 20/60] feat(day05): part 1 --- day05/input.txt | 945 +++++++++++++++++++++++++++++++++++++++++ day05/locateSeat.ts | 45 ++ day05/solution.spec.ts | 31 ++ 3 files changed, 1021 insertions(+) create mode 100644 day05/input.txt create mode 100644 day05/locateSeat.ts create mode 100644 day05/solution.spec.ts diff --git a/day05/input.txt b/day05/input.txt new file mode 100644 index 0000000..d789b79 --- /dev/null +++ b/day05/input.txt @@ -0,0 +1,945 @@ +FFBFFBBLRL +FBFBBFBLRR +FBFFBBBRLL +FFBBFBFRRR +BFBBBBFLRR +BBFBBBFRRL +BFBBBBBLLR +FBFFBFBRRR +BBFFBBBLRL +BBBFFFFLLR +FFFFBFFRLL +FFBFFFFRLL +FFFBFBBLRR +BFBFBBBRLR +FBBFBBBLRR +BBFFFFBRRR +FBBFFFBRRR +BFFFBFFLLR +FBBBBFFLRL +BFBFFFBRRL +FFBFBBFRRL +BBFBFFFRRR +FFBFFBFLRR +FFBFFBBLLR +FBFBFFFLRR +FFFBFFFRRL +FFFFFBFRRL +BBBFFFFRLL +FBBFBFFLLL +FBBBBFBLRL +BBBFBBFRRR +BBBFBFBLLL +FBBFFBBLLL +FBBBFBFLRL +FBBBFBFRLL +BFFFFFFLRR +FFFFBBBRRR +FBFBBBFLLL +FBFBFBFRLL +FBBBFBFLLR +FBBFFFFLRR +FFBBBBFRRL +FFBBBBFRLR +FBFBBBBLRL +BFFFFFFRRL +FBBBFFBLLL +FBFFFFFRLL +BFFFFBFRRL +FFBBBFBLRL +FBFFBFFRLR +FBFFBBFLRL +BFFFBFBRLL +BFFFFFFLLL +FFFBBFBLRR +FBFBFBBRLR +BBFFBFFLRR +BBFFFBBLRR +BFBFBBFRLR +FBBFBBBLLR +FFFFBBFLLL +BBFBBBFLRL +BFFBBBFRLR +FBFFFFBLLR +FFFFBFFLRL +BBFBFBFLRR +BFFBFFBLLR +BBFBBBFLRR +FFFFBBFRLR +FBBFFBBLRL +FBBBBBBRLL +FBBFBFBRLR +FFBBFBFRLL +FFBFBFFLRR +BFFBBBBLLR +FBFBFBFRRL +BBBFBBFLLL +FFBBFFBLRR +BBFBBFBLRR +BFFFBBBLLL +BBBFFBFRRL +FBBBFBFLLL +FBFBFBBRRL +BFBFFBBLLR +FFBFFBBRRR +BBFFFFFLLL +BFFBFFBLLL +BBBFBFFRRL +FBFFBFBRLR +BFFBBFFLRR +BFBFBBFLRR +FBBBBFBRLR +BFBBBBBRLL +BFBBBFBLRR +BFFFFFBLLR +BBBFFFBLRL +BFFFBFBLRL +BFFFBBBLRR +BBFBBBBRLL +FFBBFBFLLL +BFFBFBBRRL +BFFBBFBRRR +BBFBBBBRRR +FFBBBBBLLL +FBBBFFBLRL +FFBFFBFLRL +FFBBBBFRLL +FFFFBBFLRR +BBFFFFBRRL +BFFFFBBRRR +FFFBFBFRLR +FBBBBBFLRR +FFFFBBBRRL +BFBFBFBRRR +BFFBBBFRRR +FFFFFFBLLL +FFFBBFBLLL +FBFFFBFLRL +BFFFBBFLRR +FBBBBBFRLL +FBFFFFBRLL +FBFBBBFRLL +FFBFBBBLRL +BFBFBFFLLL +BBBFBFBLLR +FBBBBFFRRR +FBBFBFFRLR +FBFFBFFRRR +BFBFBFFLRR +BBFFFBFLRL +BBFFFBBRRL +BFFBBFFLLL +BFBBFFFRLL +FFFBFFBRLR +BBFBBFBLLR +BBBFFFFRLR +BFBBFBBRRR +FBBBFBFRRL +BBFBBBBLLR +BFFBBBBRRR +FFFFFBFLLL +BBBFBFFLRL +FBFFFFBLLL +BFFBBBFRRL +FBFBBFBLRL +FFBFBBBRLR +FFFBBBBLLL +BBFBBFFRLL +BBFBFBBRLL +BBFBFBBRRL +BFBBBFBRLR +FBFBFFFRLL +BFFFBFFRRL +BFFFFBFLRR +BFBBFFBRRL +BBFFBBFRRL +BBBFFFFLLL +FBFFBFBRRL +FFFBBFBRRL +FBFFBFFLLL +FFFBFBBLRL +BBFFBFBLLL +FFBBBFBLLL +BFBBBFFLRL +BFBFBBBRRL +FFBBBBFLRR +FBBFFBFRRR +FFBFBFBRLL +BFBBFFBLLR +BFFBFBFRRL +FBFFFFFLRR +FBFBBBBRLR +BFFFFFBLRR +BBFBFFFRLL +FFBFBBFLRR +BBFFFFFRLL +BFFBBFBRLR +FFBBFBBRLR +BFBBFFFLRL +FFFFFFFRRL +FFBBBBBLRL +FFFBBBBLLR +FFFBBFFLLR +FFFBFFFRLL +BFBFFBBRRL +BBFBBFFRRL +FFBFFBBRRL +FFBFFFFRRL +FFFBFFBRLL +FBFBFFFRLR +FFFBFBFRRR +BFBBBBFRRR +BBBFBFFRLL +FBBFFFFRLR +BFFBBBBLRR +FFBBBBBRLL +FFBBFBFLRL +BBBFFBBRLL +BBFBBBFRLL +BFBBFBFRRR +FBFBBFBRRL +FBBFBBBRRL +FFBFFBBRLR +FFFFFBFLRL +FBFBFFFLLL +FBFFBBFRLL +FBBBFFFRRR +BFFBFBBRLL +BFBFFFFRLL +BBFFFBBLLR +FFBBFBBLLL +BBBFFFBLLR +FFFBBBBRLL +BFBBBBFRLL +BFBBBFFLRR +BFFFFFFLLR +BFBBBBFLLL +FBBBFFFLRL +FBBBBFBLLL +BFFFBBFRRL +FBBBBFFRLR +BBFBFBFRLR +BFFBFBFLRR +BBFBFFBRRL +FFFFFFBRRL +FBFBFBBLRL +BFBFFBBLRR +FFBBFBFRRL +FBFFFBFLLR +FBBBBBBRRR +BBBFBFFLRR +FBBFBBBRLL +FFBFFBBLLL +BBFFBFBRRR +BFFBBBFLRR +FFFBFFFLLR +FBBFBFFRLL +BBFFFFBLLL +BFBFBFFLRL +BBFBBFBRRR +BBFFFBBRLL +BFFBBFBRLL +FFFFFFBRLL +BFFBFFBRLL +BFFBBFBLRR +BFBBBBFLRL +BBFFFFBLRL +FFFBBBFLRR +BFBBFBBLRL +FBBBFBBRLL +BBFBBFBRLR +BFFBBFBLLL +FBBBBBFRRL +BFFBBBFLRL +FFFBBFFRLR +FBBFFFFRLL +BFFFFBFRLL +FFBBBFBRLL +FFFBFFFRLR +BFBBFFFRRL +BFBFFBBRRR +FFBBFBFLRR +FFFBFFBLLR +BBFBBFFRLR +BFFBBFFRRL +FBBFFFFLRL +FBFBBFFRLL +BBFBFBBLLR +FFFFFBBLRR +BFBBBFFLLR +BFBFFBFLRR +BFBBFBFRRL +FBBFBBFRLR +BBFBBBFLLR +BFFFBBBRLR +FBFFBFFRLL +BFBBFFFRLR +BBFFBBFRLR +BBFBFFBLRL +BBBFBFBRLL +FFFFBFFLRR +BFBFBBBLLL +BFFFFBFLRL +BFBBBFBRLL +FFFBFFBLRR +FFFBBFBRLR +BBFFFBBLLL +FFFBBBBRRL +FFBFBFFRLR +BBBFFBBLRL +FFBFFBFLLL +FFFBFBBLLR +FFBFFFFLRL +FFBBFFFLLL +FBFFFBBRRL +BFFFFBBLLR +BFBFFFFRRR +FBFBFBBRLL +BFBBBFFRLL +BFFBBFFLRL +FFBBFFBLLL +FBBBBFBRRL +BBFFFBFRRL +FFFBBFBLRL +BBBFFFBRLR +BFBBFFFRRR +FFBFBBBRRR +BFFFBFBRRL +FBBFFBFRLL +BBBFFBBLLL +FBBFBBBRLR +BBBFBBFLRR +BBFFFFBRLR +BFFFBFBRLR +FBBBFBFRLR +BFBBFFFLLL +FBBBBBBRRL +BBFFBBBRLR +BFFFFFFRRR +BBFFFBBRLR +FBFBBFBLLL +BFBFBBBLLR +FBBBFBBLRL +FFBFFFBRRR +BFFFFBBRLL +BBFBBFFLRR +FBBBFBFLRR +BFFBFFFLLR +BBBFFFFLRR +BFFBFBFRRR +FFFFFFBRRR +BFBFFFFLRR +BFFFBBBLRL +FBBBFFBLRR +FFFFBFFLLL +FFBBFFFLLR +BFBBFFBRLR +FBFFBBFLLL +FFFBBBFRLL +BFBBFFBLRR +BFFBFFBRRR +FBFBBFFLRR +BFFBFBFLLR +FBFFFFBLRR +FBFFFBBLRR +BFBFFBFRRL +FFBFBFBLRL +FBFBBBBRRL +BBFFFFFRLR +FFBFFBFRRL +FFBBFFBRRR +BBFFBFFRRL +FFFFFBBRLR +BFBBFFFLLR +FFFBBFFLRR +BFFBFBBRLR +FBFFBFBLLL +FFBBFBFLLR +FFBBFFFRLR +BFBFFFFRRL +FBBFBBBRRR +BFFFFBFRRR +BFBFBFBLLR +BBBFBFFRLR +BFFFBFBRRR +FBFBFFBLRR +BBFFBBFRLL +BFBFBBFLRL +BFBFFFFLRL +BBBFBFBRLR +FFBBBBFLLL +FBBBFFBRLL +FFBFFFBRLR +FFBBBFFRRL +FFBBBBBLLR +FFFFBFBLRL +FFFBFFFLRL +FBBBBBBLLR +BFFFBBFLRL +FBBFBFFLRL +FFBFFBFLLR +FFBBBBBRRR +FFFBFBFRRL +BFFBFFFRLR +FFBFFBBLRR +BBFFFFFLRR +BBBFBBFRRL +BBFFFBFRLL +FBFBFBBLRR +BBFFFBBRRR +BBBFBFBLRL +FBBBFFFRLR +BFFFBBFLLL +FBBBBFFLRR +FFBBFFBRLR +FFBFFFFRRR +FBFBFBFLRR +BBBFFFFRRR +FBFFFBFRRL +FFBFFFFLLL +BBFBBBBRRL +FBFFBBFLRR +FBFBBFFRRR +BFFFBBBLLR +FFBBBFFLRR +BFFFFBBRRL +FFBFFFFLRR +BFFBFBFLRL +BFFBBBBRLR +BFFBFBBLLL +BFBBBBBRRR +FFBBFBBLRL +BFBFFBFLRL +BBFBBBFRLR +FBBFBBFRLL +BFBFFBBRLL +FBFBBBBRLL +FFBBFBBLRR +BFBFFBBLLL +FFBFFFBLLR +BFBBBFBRRL +BBFFFBFLRR +BBFFBBFLRL +FBBFBFBLLR +BBBFBBFRLR +FBBBBBFRLR +BFBBFBFLLL +FBFFFFBLRL +FBBFFBBLLR +FBBFFBBRLR +FFFFBFBRRR +FBBFFBFLRL +FBFBBBBRRR +FBBFFFFRRL +FFFBBBBLRL +BFFBFBFRLL +FFBFBFFRRR +FFFBBFFRRR +BBFFBBBLRR +FFBFFFBLRR +FFBBFBBRLL +FFBBFFFRLL +FBBBFBBLLL +BBFFBFFRLL +FBBFBFBLRR +BBBFFFBLLL +FBFBFBFLRL +BFFBBFBLLR +BFBFBBFLLR +BFBBBFFRRR +FBFFFBFRRR +FFBFFFBRRL +BBFFBBFRRR +BFBBFBBLLL +FFFFFBBRLL +FBFFBFFLRL +FFBFBFBLLR +FFBBBBFLLR +BFBFFBFRRR +BFFFFFBRRL +BFFFFBFLLR +FFFBBBFLLR +BFBFBFBLRR +FFFFBBFLLR +BBBFFBBRRR +FFBFBFBRRR +FBFBBBFLRR +BFFFFBBRLR +BFFBFFBRLR +BFBBFBBRRL +FFBBFBBRRR +FBBFBBFLRR +BBFFBBBRRL +FBBBBBBLRR +FFFBFFFRRR +FFFFBFBRRL +FBFFBFFLRR +BFFBFFFLRR +FFBFFBBRLL +FBFBBFFLLR +BFBFFBFRLR +BBFBFFFLRL +BFFFFFFLRL +FBFFFBFRLR +FBFBBFBLLR +FBBBBFFLLL +BFBFBBFLLL +BBFFFBFRLR +BFBBBBFLLR +FFFFBBBRLR +BFBFFBFLLR +BBBFBFFLLL +BFFFFFBRLL +FFBBFBBLLR +FBBBBFFRRL +FFBBFFBLRL +FBFBBBFLLR +FBFFBFBLRL +FBBBFFFLRR +FFBFBFFRRL +FBBBBBBRLR +FFFBBFBRLL +FBFBFFBRLR +BBBFBFBRRR +FBBBBBBLLL +FFFFBBBLLL +BBFBFBFLRL +BBFFFFFRRL +FBBBFFBRLR +FFFFBFFLLR +BFFBBFFRLL +FBFFBBFRRL +BFBFFFBRRR +FBFFBFFRRL +FFFFFBBLLR +BBFFFFBRLL +FFFBFBFLLL +BFBBFBFRLR +BFBFBBBLRR +BFFFBBBRRR +FFFFFFBLRL +FFFFFFBLRR +BFBFFBBRLR +BBBFFBFLLR +FBFFFBBLLL +BBBFFBFLLL +BBFFBBFLRR +BFFBFFFRRL +FFBFBBBRLL +FBBBBBFLLL +BBFBFFBRRR +BBFFFFFLRL +BFFBFBBLRL +BFBBBFFLLL +BFBFBFFRRR +FFBBFBBRRL +FBFBBFFLLL +BBFFBFFRRR +FBBFFFBRRL +BBBFBBFRLL +FFFFBBFRLL +BBBFFBBRRL +BBFBBBFRRR +FBBFFBBRRL +BFBBBBFRLR +BFBFBBFRLL +FFBFBFBLRR +BFFBFBBLLR +FBFBBBFRRR +FFFBBBBLRR +FBFFFBBRLL +BBFFFBFRRR +FBFFFFBRRL +FBBFFFBRLL +FBFFFFFLLL +FBBBBBFLRL +BBFFBFFLRL +BBBFBBFLLR +FBFFBFFLLR +FFBBFFFRRR +BFFFFFBRRR +FFBFBFBLLL +FFFFBFBRLL +BBFBFFBRLR +BBFFBFBRLL +FBBFFBFRLR +FBBBFFBRRL +FFFBBBBRRR +BBFFFFBLRR +FFBFBBFRRR +BFFFFFBLRL +FFBFBFBRRL +FFBBFBFRLR +FFBFBBBRRL +BFFFFBBLRL +FBBFBFBRRR +BFFFFFFRLR +FFFFBFFRLR +BFBFFBFRLL +BFFBBFFRRR +BFFBFFBLRR +FBFBFFFLLR +BFBFBFBRLL +BBFFFBFLLL +BFBFFFBRLL +BFBFBFFRLL +FBFBBBFLRL +FBFFFFFLRL +BBFBBFBRRL +FFBFFFBRLL +FBBFFFBLLR +FFBBBFFLRL +BFFBFBFRLR +FBFFFBBLLR +FFFBFFFLLL +FBBBBBFRRR +BFBFBFBLRL +BBBFFBFLRR +BBBFBBFLRL +BBFBFFFLLR +FBBFFFBLLL +BFBFFFBLRL +FBFBFBBRRR +FBBBFBBRRL +FFFFFFBRLR +FBBFBBFRRL +BBFBFBFLLL +BBFBBBBRLR +BFBBBBBLRL +FBBBBFBRLL +BFFBFFFLRL +BFBBBFFRRL +FFBBBFBLLR +FBFFBBBLLL +FFFFFFBLLR +FFFBFFBLRL +FFFBFFFLRR +FFBBFFFLRL +FBFBFFFRRR +FBFBFBBLLR +FFFFBBBLLR +FFBBBBBRLR +BFBBBBBLRR +BBFBFBFRLL +BFBFFFBLLL +FBBBFBFRRR +FBBFBBFLRL +FFFBBFFLRL +FFFBFBFLRL +FBFBBBBLRR +FFFBBFBRRR +FFFBBFFRLL +FFBBFFBLLR +FBBBBBFLLR +BFBFBFFRRL +BBFBBFBRLL +FBBBFFBRRR +FBFBBFBRLR +FBBFBBBLRL +BFFFFBFRLR +BBFBBBBLRR +BFFBBFFLLR +FBBFFFFLLL +FBFFFFBRLR +FFFFBBFRRL +BFFFBFFLLL +FFFFBBBLRR +FBFFBBBLRL +FFBFFFFRLR +BBBFFBFLRL +BFFBBBBLLL +FFFFFBBRRL +BFBBFFBLLL +BFBBFBFLRR +BFFBBBFLLL +FBFFFBFLLL +FBBFFFBLRL +FFBBBBFLRL +FBFFFBFRLL +FBBFFFBRLR +FBFBBFFLRL +FBBBBFBRRR +FBBBBFBLRR +BBFFBFBLLR +FFBFBBBLLL +FFFFFFFRRR +FFFFFBFRLR +FFBFFFBLRL +BBBFFFBLRR +FBBBBFFRLL +FFBFBBFLLL +BFFFFFFRLL +FFBBBFBRRL +FBFFBFBLRR +BFFBFBBLRR +BFFFBBFRRR +FBBFBBFLLL +BFBBFBBLRR +BBFBBFFLRL +FBBBFBBRLR +BFBBBFFRLR +FFFFFBBRRR +BBFFFBFLLR +BFFFFFBLLL +FBFBFFBRRR +BBFFBFBRLR +BFBBFBFLLR +FBFBFBFLLR +FBBBFFFRLL +BBFBFFBLRR +BBFBFFFRLR +BFBFFFBLRR +BFFBFFBRRL +FFFBFFBLLL +FFBFBFFRLL +BBFBFFBLLL +FBFFFFBRRR +BFBBBFBLLR +FBFBFFBRLL +BFBFBFBRRL +BFFBFFBLRL +FFBFFBFRLR +FBBBFFFLLL +FBFFFFFRRR +FFBFFFFLLR +FBBFFFFRRR +BFFFBFFRLR +BBBFFBBRLR +FFBFBFFLRL +FFFBFBBLLL +BBFBFBBRLR +FFFFFBBLRL +BFBFFBBLRL +FBBFFFFLLR +BBFBBFBLLL +BFFBBBBRRL +FBFFBBBRLR +BBBFBFFLLR +FFFFFBFRRR +FFFBBBBRLR +FFBBBFFLLL +FFFBBFFRRL +BFFFBFFLRR +FBBFFFBLRR +BFFBBFBRRL +FBFBBBFRLR +FBFFFBBRLR +FBFBFBBLLL +FFBFBBFLRL +FFBBBFFRLR +BBFBFBFRRL +FBBBFBBLRR +BFBBBFBLLL +FFFFBFBRLR +FFBBFFBRRL +FBFFBBBLRR +FFBFFFBLLL +FBBFFBFLLL +FFBBBFFRLL +FBFBFBFLLL +BBFFBFFRLR +BFFBFFFLLL +BBFBFBFRRR +FBFFFFFRLR +FBBFBFFRRR +BBFFFFFLLR +BFFFFBBLLL +FFBFBBBLRR +BFFBBBBLRL +BFBFBBBRRR +BFFBFBBRRR +FBBBFFBLLR +BBFBFFFRRL +FFFBBFBLLR +FBFBFFFLRL +FBFBBFBRLL +FFFBBBFRLR +BBFFBBBLLR +FBFBBFBRRR +BFBBFFBRLL +FBBFBFFRRL +FBFFFFFRRL +FFFFFBFLRR +FBBBFFFLLR +FBBBFFFRRL +BBFBFBBLRL +BFFFBFFLRL +FFFBBFFLLL +BBFFBBBRLL +FBFFBBFLLR +BFFBFFFRLL +FBFBBFFRRL +BFFBBFFRLR +FFFBBBFLLL +FBFFFFFLLR +BFBFBBFRRR +BFBBFFFLRR +FFBFBBFRLL +FBBFBFBLRL +FFFFBFFRRR +FFFBFBFLLR +FFBBFFFRRL +FBBFBBFLLR +BFBBBBBRRL +FFFFBFFRRL +FBFBBBBLLR +BBFBBBBLRL +BFBBBBFRRL +BBBFFBBLLR +BFFFBBBRLL +FBBBFBBLLR +FFFFBBBLRL +FBBFBFFLLR +FFBBBBFRRR +FFFFFBBLLL +FFFBFBBRLR +BFBBFBFRLL +FFFBBBFLRL +FBBFBFBRRL +FFFFBBFLRL +BFFBBBBRLL +FFFBFFBRRL +BFFFBBFRLR +FFFBFBBRRR +BFBBFBFLRL +BFBBBBBRLR +BBFBFBFLLR +FFFBBBFRRL +FBBFFBFRRL +FBBBBBBLRL +FFFBFBFLRR +BFFFBBFLLR +BFFBBBFRLL +BBFFBFBLRL +FFBBBBBLRR +FBFBFBFRRR +BFBBFFBLRL +BFFBBBFLLR +FFBFBBFLLR +BFFFBBFRLL +FFBFBFFLLR +FBBFBFFLRR +BFBBBFBRRR +BBBFFFBRRL +BFFFBFFRLL +FFBFBFFLLL +BBBFBFBRRL +FFFBFBBRRL +BFFBFFFRRR +BFFFBFFRRR +BFBFBFFLLR +BBFFFBBLRL +BFFFBFBLLR +BFBBBBBLLL +BFBFFFFRLR +FBFFFBBRRR +BBBFFBFRLL +FFFBBBFRRR +BFBFBFFRLR +FFBFBBBLLR +FBBFFBBRLL +BBBFFBBLRR +BBBFBFFRRR +FFFFBBFRRR +FBFFBBBRRR +BBBFFBFRLR +BBFBFFFLRR +FBFBFFFRRL +BBFBFBBLRR +FBBFBBBLLL +BFFFBFBLRR +FBBBBFFLLR +FBBBBFBLLR +FBBFFBBRRR +BBBFFFFRRL +BFFFBFBLLL +FBBBFBBRRR +FFBFBFBRLR +FFFFBBBRLL +BFBBBFBLRL +BBFBFFBLLR +FBFFBBBLLR +FFBBBFFRRR +FBBFBFBRLL +BBFFFFBLLR +FFBBFFFLRR +FBFFFBFLRR +BBBFFFFLRL +FFFFBFBLLR +FFFFFBFLLR +FFFFBFBLLL +FBFFBBFRLR +BBFFBBFLLR +FBFFFBBLRL +BBFBBFFLLR +BFBBFBBRLL +BFFFFFBRLR +FBBFBBFRRR +FFFBFBFRLL +BBFBBBBLLL +FFFFBFBLRR +BBBFFFBRLL +BBFFBFFLLR +FFBBBBBRRL +BFBFBBBLRL +FFBBBFBRLR +BFBFBBFRRL +FFBBBFBRRR +FFFBFBBRLL +BBFFBBBRRR +BFFBFBFLLL +BFFBBFBLRL +BFBFFFFLLR +FFBBFFBRLL +BBFBFFBRLL +BBFBFBBLLL +FBFBBBBLLL +FBFBBBFRRL +BFBFFFBLLR +BBFFBBBLLL +FBFFBFBRLL +BFBBFBBRLR +FFFBFFBRRR +BBFBFBBRRR +FBFFBBFRRR +FFBFFBFRLL +FBBFFBFLRR +BBBFBFBLRR +BBBFFBFRRR +FBBFBFBLLL +BFFFFBBLRR +FBFBFBFRLR +FBFBBFFRLR +FBFBFFBRRL +BFBBFFBRRR +FBFFBFBLLR +BFBFBFBLLL +BBFFFFFRRR +FBFBFFBLRL +BBFFBBFLLL +BFBFFFFLLL +FFBFBBFRLR +BBFFBFFLLL +BFBBFBBLLR +FFFFFBFRLL +BBFBBFFRRR +BFFFBBBRRL +BBFBBFFLLL +FBBFFBFLLR +FFBBBFBLRR +BFBFBFBRLR +BBBFFFBRRR +FBBFFBBLRR +FFBBBFFLLR +BFFFFBFLLL +BFBFFBFLLL +BBFBFFFLLL +FBFBFFBLLL +BBFFBFBRRL +BBFBBFBLRL +FBFBFFBLLR +BBFFBFBLRR +FBFFBBBRRL +FFBFFBFRRR +BBFBBBFLLL +BFBFBBBRLL diff --git a/day05/locateSeat.ts b/day05/locateSeat.ts new file mode 100644 index 0000000..f733de7 --- /dev/null +++ b/day05/locateSeat.ts @@ -0,0 +1,45 @@ +enum Instruction { + LOWER_HALF = 'LOWER_HALF', + UPPER_HALF = 'UPPER_HALF', +} + +const findNumber = ( + instructions: Instruction[], + start: number, + end: number, +): number => { + if (start === end) return start + const [instruction, ...rest] = instructions + if (rest.length === 0) { + return instruction === Instruction.LOWER_HALF ? start : end + } + if (instruction === Instruction.LOWER_HALF) { + return findNumber(rest, start, start + Math.floor((end - start) / 2)) + } + return findNumber(rest, start + Math.ceil((end - start) / 2), end) +} + +export const locateSeat = ({ rows, cols }: { rows: number; cols: number }) => ( + passId: string, +): { row: number; col: number } => ({ + row: findNumber( + passId + .split('') + .filter((s) => ['F', 'B'].includes(s)) + .map((s) => + s === 'F' ? Instruction.LOWER_HALF : Instruction.UPPER_HALF, + ), + 0, + rows - 1, + ), + col: findNumber( + passId + .split('') + .filter((s) => ['L', 'R'].includes(s)) + .map((s) => + s === 'L' ? Instruction.LOWER_HALF : Instruction.UPPER_HALF, + ), + 0, + cols - 1, + ), +}) diff --git a/day05/solution.spec.ts b/day05/solution.spec.ts new file mode 100644 index 0000000..f08daac --- /dev/null +++ b/day05/solution.spec.ts @@ -0,0 +1,31 @@ +import { loader } from '../lib/loader' +import { locateSeat } from './locateSeat' + +const load = loader(5) +const input = load('input') + +describe('Day 5: Binary Boarding', () => { + describe('Part 1', () => { + it.each([ + ['FBFBBFFRLR', 44, 5], + ['BFFFBBFRRR', 70, 7], + ['FFFBBBFRRR', 14, 7], + ['BBFFBBFRLL', 102, 4], + ])('should solve the sample: %s is row %d, col %d', (passId, row, col) => { + expect(locateSeat({ rows: 128, cols: 8 })(passId)).toEqual({ + row, + col, + }) + }) + it('should solve', () => { + const l = locateSeat({ rows: 128, cols: 8 }) + expect( + input + .map((passId) => l(passId)) + .map(({ row, col }) => row * 8 + col) + .sort((a, b) => a - b) + .pop(), + ).toEqual(951) + }) + }) +}) From 8d73865acbdf4b58f0495d7f7daccd8c162d330d Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Sat, 5 Dec 2020 12:02:07 +0100 Subject: [PATCH 21/60] feat(day05): part 2 --- day05/solution.spec.ts | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/day05/solution.spec.ts b/day05/solution.spec.ts index f08daac..a4d659e 100644 --- a/day05/solution.spec.ts +++ b/day05/solution.spec.ts @@ -4,6 +4,8 @@ import { locateSeat } from './locateSeat' const load = loader(5) const input = load('input') +const l = locateSeat({ rows: 128, cols: 8 }) + describe('Day 5: Binary Boarding', () => { describe('Part 1', () => { it.each([ @@ -12,7 +14,7 @@ describe('Day 5: Binary Boarding', () => { ['FFFBBBFRRR', 14, 7], ['BBFFBBFRLL', 102, 4], ])('should solve the sample: %s is row %d, col %d', (passId, row, col) => { - expect(locateSeat({ rows: 128, cols: 8 })(passId)).toEqual({ + expect(l(passId)).toEqual({ row, col, }) @@ -28,4 +30,18 @@ describe('Day 5: Binary Boarding', () => { ).toEqual(951) }) }) + describe('Part 2', () => { + expect( + input + .map((passId) => l(passId)) + .map(({ row, col }) => row * 8 + col) + .sort((a, b) => a - b) + .find((id, k, arr) => { + if (arr[k - 1] === undefined) return false + if (arr[k + 1] === undefined) return false + if (id - arr[k - 1] > 1) return true + return false + }) - 1, + ).toEqual(653) + }) }) From b572946b9551b35ebc43e6ccd870fd8b300aaba9 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Sat, 5 Dec 2020 12:02:54 +0100 Subject: [PATCH 22/60] feat(day05): part 2 --- day05/solution.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/day05/solution.spec.ts b/day05/solution.spec.ts index a4d659e..9c588ce 100644 --- a/day05/solution.spec.ts +++ b/day05/solution.spec.ts @@ -39,7 +39,7 @@ describe('Day 5: Binary Boarding', () => { .find((id, k, arr) => { if (arr[k - 1] === undefined) return false if (arr[k + 1] === undefined) return false - if (id - arr[k - 1] > 1) return true + if (id - arr[k - 1] == 2) return true return false }) - 1, ).toEqual(653) From 3d5302b2becd85aa85a150a00700cd3c2b11c8e9 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Sat, 5 Dec 2020 12:24:01 +0100 Subject: [PATCH 23/60] refactor(day05): improve readability --- day05/locateSeat.ts | 48 +++++++++++++++++++++++------------------- day05/solution.spec.ts | 12 +++++------ 2 files changed, 32 insertions(+), 28 deletions(-) diff --git a/day05/locateSeat.ts b/day05/locateSeat.ts index f733de7..a981be5 100644 --- a/day05/locateSeat.ts +++ b/day05/locateSeat.ts @@ -1,44 +1,48 @@ -enum Instruction { - LOWER_HALF = 'LOWER_HALF', - UPPER_HALF = 'UPPER_HALF', -} - +/** + * Recursively follow the instructions which determine whether to use the + * upper half (true) or lower half (false) of the number range + */ const findNumber = ( - instructions: Instruction[], + instructions: boolean[], start: number, end: number, ): number => { if (start === end) return start - const [instruction, ...rest] = instructions + const [upperHalf, ...rest] = instructions if (rest.length === 0) { - return instruction === Instruction.LOWER_HALF ? start : end + // No more instructions left, decide between the two + return upperHalf === false ? start : end } - if (instruction === Instruction.LOWER_HALF) { + if (upperHalf === false) { return findNumber(rest, start, start + Math.floor((end - start) / 2)) } return findNumber(rest, start + Math.ceil((end - start) / 2), end) } +type Instruction = 'L' | 'R' | 'F' | 'B' +export type Instructions = ('L' | 'R' | 'F' | 'B')[] + +const filterInstructions = (instructions: Instructions) => (i: Instruction) => + instructions.includes(i) + +const isUpperIf = (upperInstruction: Instruction) => (i: Instruction) => + i === upperInstruction + +/** + * Implements a recursive aproach to finding the seat based on the given instructions + */ export const locateSeat = ({ rows, cols }: { rows: number; cols: number }) => ( - passId: string, + passId: Instructions, ): { row: number; col: number } => ({ row: findNumber( - passId - .split('') - .filter((s) => ['F', 'B'].includes(s)) - .map((s) => - s === 'F' ? Instruction.LOWER_HALF : Instruction.UPPER_HALF, - ), + // This converts the boarding pass instructions sequence of true/false for only the front/back operation + passId.filter(filterInstructions(['F', 'B'])).map(isUpperIf('B')), 0, rows - 1, ), col: findNumber( - passId - .split('') - .filter((s) => ['L', 'R'].includes(s)) - .map((s) => - s === 'L' ? Instruction.LOWER_HALF : Instruction.UPPER_HALF, - ), + // This converts the boarding pass instructions sequence of true/false for only the left/right operation + passId.filter(filterInstructions(['L', 'R'])).map(isUpperIf('R')), 0, cols - 1, ), diff --git a/day05/solution.spec.ts b/day05/solution.spec.ts index 9c588ce..4a29a0f 100644 --- a/day05/solution.spec.ts +++ b/day05/solution.spec.ts @@ -1,5 +1,5 @@ import { loader } from '../lib/loader' -import { locateSeat } from './locateSeat' +import { Instructions, locateSeat } from './locateSeat' const load = loader(5) const input = load('input') @@ -14,7 +14,7 @@ describe('Day 5: Binary Boarding', () => { ['FFFBBBFRRR', 14, 7], ['BBFFBBFRLL', 102, 4], ])('should solve the sample: %s is row %d, col %d', (passId, row, col) => { - expect(l(passId)).toEqual({ + expect(l(passId.split('') as Instructions)).toEqual({ row, col, }) @@ -23,7 +23,7 @@ describe('Day 5: Binary Boarding', () => { const l = locateSeat({ rows: 128, cols: 8 }) expect( input - .map((passId) => l(passId)) + .map((passId) => l(passId.split('') as Instructions)) .map(({ row, col }) => row * 8 + col) .sort((a, b) => a - b) .pop(), @@ -32,8 +32,8 @@ describe('Day 5: Binary Boarding', () => { }) describe('Part 2', () => { expect( - input - .map((passId) => l(passId)) + (input + .map((passId) => l(passId.split('') as Instructions)) .map(({ row, col }) => row * 8 + col) .sort((a, b) => a - b) .find((id, k, arr) => { @@ -41,7 +41,7 @@ describe('Day 5: Binary Boarding', () => { if (arr[k + 1] === undefined) return false if (id - arr[k - 1] == 2) return true return false - }) - 1, + }) ?? 0) - 1, ).toEqual(653) }) }) From 5a7fd52be5df6a93d01f2e8c4403b230e0151e1e Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Sun, 6 Dec 2020 11:40:54 +0100 Subject: [PATCH 24/60] feat(day06): part 1 --- day06/collectAnswers.spec.ts | 8 + day06/collectAnswers.ts | 12 + day06/input.txt | 2211 ++++++++++++++++++++++++++++++++++ day06/parseGroupList.spec.ts | 32 + day06/parseGroupList.ts | 12 + day06/solution.spec.ts | 43 + 6 files changed, 2318 insertions(+) create mode 100644 day06/collectAnswers.spec.ts create mode 100644 day06/collectAnswers.ts create mode 100644 day06/input.txt create mode 100644 day06/parseGroupList.spec.ts create mode 100644 day06/parseGroupList.ts create mode 100644 day06/solution.spec.ts diff --git a/day06/collectAnswers.spec.ts b/day06/collectAnswers.spec.ts new file mode 100644 index 0000000..dde50ae --- /dev/null +++ b/day06/collectAnswers.spec.ts @@ -0,0 +1,8 @@ +import { collectAnswers } from './collectAnswers' + +describe('collectAnswers', () => { + it(`should collect all answers`, () => + expect(Object.keys(collectAnswers(['abcx', 'abcy', 'abcz']))).toHaveLength( + 6, + )) +}) diff --git a/day06/collectAnswers.ts b/day06/collectAnswers.ts new file mode 100644 index 0000000..c90b206 --- /dev/null +++ b/day06/collectAnswers.ts @@ -0,0 +1,12 @@ +export const collectAnswers = (forms: string[]): Record => + forms.reduce( + (answered, form) => + form.split('').reduce( + (answered, a) => ({ + ...answered, + [a]: (answered?.[a] ?? 0) + 1, + }), + answered, + ), + {} as Record, + ) diff --git a/day06/input.txt b/day06/input.txt new file mode 100644 index 0000000..3d0415a --- /dev/null +++ b/day06/input.txt @@ -0,0 +1,2211 @@ +ymw +w +wm +vsw +wm + +vs +lqn +ti +uvl + +fryuv +pngtvuhfr +fcbrulv + +pr +rp + +tdvcspxnujak +vektaowjncs +ifybztmhlasqrjkgc + +exvbqomlucjfi +cufeiomgvl +uolcfvmie +eoculrifnmv +fvclmdnoeiu + +iyomzvhpdjtrw +rpnovdhwzmityj + +emplyqxzfjrwb +xrezwjlsqpb +prdvzbhljqxaw + +wtuolk +kwtluj + +kixnqubme +adjgfwvl + +lkzqupo +nsfhbc +rki + +gkmqehib +ngiemuh + +m +s +s +w + +tu +arudi +gukp +u + +hkfs +hpfjk + +yzkuhrncx +dqasvifwne + +x +x +x +x +x + +zabmrcequtghsnlvdpkfij +drbelmtjasiupnhqgfvkc +hdvlprtebgamqfknijycsu +pcirvatkgmhndefulbqjs +hinfqkldbzcretsuvamjpg + +eoc +omvqig +aglo + +qgnjkcirewz +vmwhuafoxpt + +zinoybesugqjhr +fzgeasrhynq +myzngtrwqvl + +gdma +dq + +haugzib +xeghuf + +fsl +fsg +fs +fts +sf + +bysucwlra +ucwylrbas +sbkuarlcwy + +skmphtzonuydfxi +xpidmolthzywfusg +hxtysznfimdpou + +gonabqykhrzmpsl +pyrblhznoswkgqam +pgbohakrqzslmny +ogbqmyprlnkahzs + +hdcl +cdlh +hdcl +hldc +ldhc + +fiwztpbcxreqodunljvyh +fsrmnugobhydpkc + +fcloanbrm +dnkaglrxot +swvylepanjhqzoui + +upali +kyilvspz +rlejqntbmoxi +iklfdw + +tdxwaqsybovjgm +bmxjznqdt +ujtmehxqpldb +qbltpkrxjmd +qjxdzmbit + +avnituwozrgcjmsd +rwsaocnugzjmdtv +zanrotwdusjgcvm + +duqy +iu + +rnatpelzuiv +eaizntulvr +fntbrilvaezu + +vwprtg +nfrwluaodtphg +gtrszpw +writqgmp + +ayxievonwmtchp +aytxowvcpmihe +xtehvomypcwifa +hwmoytcvipjxae +yvawtmeiocxfhp + +dnrpaivezcktfwy +vdpnyfzrmcktwi +icfnyrtpzdkwv + +gejt +getj +ejgto +jtge + +btmwidzrun +mtunzdrbi +oiebudtxkrmyz +ztmbdrui +dmzbrtui + +rasxhidbgw +klxwvhbeacidsg +dhxlacgusirbn +sqabjmhtifxodg + +utpkgqjiycexosvanwl +grjfvnbuscwadmihxzk + +ktnhpvqxzfuwosmgl +fwxmtvzohnrlkgsup +hvlzfroxucmgpksnt +pslyfovbigtukzxnmh + +zde +zed +zed + +v +v + +calfotjxbg +etagbc +brackuvtzpgi +mdhapbtygcv + +hkdb +eahrxg +pohs +hujbq +dchbt + +nw +ewgr +amyh +pquwn + +o +o +o +o +ou + +oakzcxnp +xoclan +oxazcknp +hwcomfxna + +iymzjovgkdrqpalehubc +ptcgyqhrboazuv +vxyohunafqcswzgprb + +azwb +zabw +bzaw +zabw + +zu +zxi +fldo +u +p + +ejhtlbm +etblhm +mtbelh +hbltme +thbelm + +tnqxahufm +bhftnxumaq +ufbahtqnxm +amnhfxtuq +qfxumwanht + +vgdtjm +tdga + +wkzbx +tksxbwz + +niasv +cirenka + +pvbjswzixkcug +bxvjwsiugck +xcwjbkisugv +bgikucvdsjxlw +aswuxibjgcpvk + +vrjcpfuhetkd +mjbhzwctpeyk +qhwepmtljksc + +mkdb +bkmd +omkdb +kmdub +dmkb + +tmharzskfycvnio +abdmulpwjyxeqgc + +skmacnpgzho +ghsnpaczkmo +haposzmgnkc + +mrngvewdsqca +tfjyqhkxes + +ampi +m +mt + +kcduvyaqgtpfmij +vxgfiqcdlajypuk +gcyoeufqkpdijmav +cvfuqpiyeadjkg + +tblyemri +teburlymi +tneidylbrmfc + +jtmkxgehipfuasqrbwvcdyn +azwkvfhsbynrjpgmutdcqex +uobjpcgzstharyvkxefmnwdq + +etgikbzjd +zdybhkwteqig +ouitdbrfgeznvkxs +bekipadqgtzlc + +v +ale +c +h + +neqvowybzx +nybezqwxvo +zbenxwvoyq +vqbxwznyeo + +kwdm +k + +eahrozxdj +aopndezjx +emjaonxyzd +jxeaufdosz +yaoedxjz + +hzwc +s + +bnemwzv +mbzwnve +envbamzw +ebnwmvz +ezvntwbm + +djkqnrcvpseohazmflb +jyzftduhbnparmlscqovk +zksbneljmxcfdprwaovgqh + +zxfgtveb +xfbetvgz +txevgfbz +tfxbvegz + +mfcr +cfmr +mfcr +frmc +rfcm + +qsdvzyixl +zvdlqy +znydvqlku +lvndzyq + +vpok +hoyb + +lucohageisvdtfqnbrxk +naekdgslcqoftxrhbvui +oxgrunehtafkbidqclvs +vrdsfanugtihkxqlcobe + +poayngfzwb +mzyi +clxuesdvqythrjk + +vtsxloimpq +sqvxulbiomtp + +xlo +xol +lox +lxo +lox + +mqtafugsj +wahiptqjbe + +nuosc +usocn +cnuso +socaun + +rwchjlkmidbtxupfvg +jkudgvprhalcfbnymtw + +uptazbcdxywqf +buqywadtfhcx +klbduawtqyx + +klfyrxdzn +lsnrcyvzokhx +eafrzqkxly +xzlqryk +xwriykmljzugp + +gfvxdi +vtwigxdj +xdnvgyi + +vs +sepvngak +vs + +dqzfx +xqdfz +qfdzx +qxzfd + +lfdksujt +ijcdtslkf + +rxqevdwishmjfluy +lwshvauecgrfiqxyjm +txisrubqelyfwvmhj + +ijlvuenzdsykfwc +qkxacuydnehzbglsrfm + +purkflqgovscyedzhtinxa +ensuvzrftpdgcxykhqilo + +f +p +jkxa +p + +rwqcyxtbvn +rtbwcxqnyv +ytwvnbxqrc +vwxcrqtnyb + +takohlgzesf +katgsozeflh +aolgtesfhkz + +jakvrlxipqgwn +xwjhigvkqarlpn +vrlitwjqcagnkxp +ngcljqvpkrwiax + +csg +sgc +sgc +gsc +sgc + +xftrpzkynwjcils +tyzjfncspxwilrk +clxjtnsriykzpwf +rcflzkwpxjynsti +ntwxsapejzkcrilfy + +gmabr +mrbag + +idrvzjbafosemw +fvewdrjazsmibo +woisjrtdvxezkabmuf +aifmbdjowzvres +jzesabwvmdiofr + +cvsr +scvr +srvc +zcrsv +rscv + +ldjs +sdjl +sdjgl +ldjs +jlds + +vf +vf +vf +vf + +nqi +gmiywb +il + +bsvamr +qkvrab +abrqv +ktabvhr +rvbhax + +cpgsqnorkay +yproncgkqsa +okapcgqsnyr + +fhcrk +wjaxbchs +flunch +khorczi + +uyj +jyau +yuj +yju +ykjiu + +yuqwkzf +jaocfzyxpw + +ayqun +vwpzfoj + +ftkx +nftjkr + +saupfiylrhckzdmq +idwlp +ldip +wlidjp + +qhiu +suqni +iuxnq +qui +iumqzg + +xvoqnda +dloqvnxa +donvqax +vqdnoax + +ctblovfpygsmwqrjai +ivfwqgrpsjtacm +pmvqtjfragcwis + +m +ms +m +m + +v +vxcjl +tvgn + +agcvutldfnwpoqhe +panwfvugetxqo +tusfwgmoaeyvnjkpq +wvutgfoeraqmzpn + +pfelnjvha +qmzexonlv +rbyiugdswk + +spmzxl +nhbuvqcagdi + +vpfmjgitk +vefgrdkpit +gfitvkbp +pftjvgik + +eiczmbkfargtosjdlyhwuxqn +uiqdwkptonjzxlfsrgemahycb +mnfzskoytqlbhuidjagwexrc + +ylcroxz +azolxycr +rcxoylz + +ipjvbtacrsuklozxqg +gkczovaibqptulxsjr +zsuctpolbxjikqrgva +aglbcjqsvzxokrupti +tlpurqvxgazoibjsck + +chjtiyplzb +rzcplthisq +lcwgmnzvhei + +uvbqnetmkdsg +tcgizb + +anet +tnea + +b +lbm +b +b + +rjsgkvxnoctybf +onhbkjryzvtcfag +rvtbyfgxsonkjc +fcgoktjnbryv +cvgpjdnyrotfixbk + +woyzins +vml +l +ekh + +imurfjexb +iufxme +midneuxf +ztudmxife +kymfxieuod + +fjevlykwshit +jfpwistkglev +ljidewskvtf +orqwblzsevtcikjfu +xayemltwksfjivn + +jmfbqzsu +jsxbiumfv + +kuytgfqzwolpxdcnjhrsme +xwzjpqsgfmdklhytocuren + +tswk +ztqw +mdrpthif +t +tw + +rnskdcauhe +rukeyndhasc +ahsrknuecd + +mxsaerbdhgqcy +xvqybdmahreos +qyxbmgjsradhe +bqxheasyirmd +rdqehysabmx + +bkzxw +xzkwb +xkwbz +wxjzkb +bwzxk + +avlwfyqrp +jkozmedhgubsxnct + +ie +gkec +epx + +xvbisfp +zxprafsim +pwiqhkfucsx +sflxmjbivyp + +mkhg +dpnflvzhesrt +bmhu + +mpl +pml +pml +pml +pml + +hdrtnziabqscwxp +btdczqxhuwranspi +prwatsxhzbdnicq +hxrnzawpcsqbitd + +gxzafpjvciywskn +wnzvjifscrxykapog +ncsjiapyzkgvxwf +jkexzingwpvscayf +iyjzfwnckavpxsg + +xtdblwyqfsjak +uwtsncvjlm +switjlm + +j +je + +ce +c +cy + +semxdiqw +lbnmaq + +n +n +n +n + +rq +rqes +qr +rq +qr + +ibndxgtuawhokzc +wkxhgdcznjtoaiubp +uxzwtdnblapkchogi +zhtidxwvecobkgyuna +cgabuhrpioxkwdztn + +ekcrfujsopgvbwxtya +jeykusfvpxbowacrztg +frkjsygapcowxubetv +shjoyanumqkertxgbdfwpvc + +mfw +pfwm +mwfi + +ocyhq +chqye + +nzsxagpfuhmqkcy +flyqunphxm +qmpnhxufy +mjurwfpqhnyxe + +pxqf +pqx +xpq +qgpx + +bzhprgot +rzhpaoug +rmhygacqxvkpjzo + +tlzpvdgkafqw +clqvpgtkafd +lgetfbksxivdprqah +kuptalqgjfdnv + +rfkwoalbjdi +bkilwjfro +orwjlkibf +okbdflrjiaw +nrwjzoibflk + +n +n +n +n + +vznusdgkmcrxfpwojtleqhy +rveftohngkxzdljq +lefikohvbxqrjtdzng +xqtnjzvdglfkrheao + +xohambwtulqnpgf +ruxmopbjwtfncdgal +bnsptuwyvlmxzogif + +azbsgpwihlcfmuk +ahfgulbckzsm +gslafkcombuzhj +hujmklzgbafcs + +nzdqthy +wjeagzcxyiq +qzfycp + +hudclx +quczdxhl +chudlx +hlcxdu + +nrmypdbzvolxga +ykgtvfcasz +yagwvqze +zfvygja +iyzgauvht + +eitov +aizw +qjai + +ruptmgzobxa +hjvsdwylieqnkf + +njsgbwltpyeohf +gxsojntpyfwlehb +fontbepsjwgyh +mdfhypjeobsriktqanwug + +pcunvqdgxjfzokwm +awighqdejvnflp +iqdnvfpjwlgs + +upqz +zhyxjdtlv + +nq +qpns +nqfu +qnps + +lve +pi +ipf + +uafxbjp +lfpjcw +rjfp + +obh +h +h +h +h + +ezx +xze +xze +efxz +zxe + +yshdxqelnzmuipowr +oqsedljrinmytwuphx +ljnbcirxshyouqdzewp +wbiqxtrducehoylspn +rvshygoewlqunidpxfak + +e +e +e +e + +hyuwjlgxoa +chajowynxlf +wyfhlnjaox +aztohyxlwj + +eqldmuxigyhktfwbczapnrvjso +vpxflgohmqijwadnbykrecustz +kswxetzualphigncdoqjmfrybv +znilqdpkgratwjvuybxhemfocs +izjbnyvastgdchfeoxmrwqpklu + +qwjzem +ewzmcqj +cqzwejm +mwqejz +qbmkjdzew + +rvuoscwqldtnjfpyk +dstluofwkrqcjnyp +ujnytlcqwsdaokprf + +cbhwotxiglrm +iwlhgcbtrom +ibvrotmjscgwh +gkcltbmrhoxwi +tzrgowmcbihx + +dc +cd +cd +dc +cd + +pnsjqghf +ntqjfhgp +nfphezrjmgv + +gotlaypnhj +ylonphtgja +gahjotynlp +lpajtyonhg +lynopgtajh + +uqkwycrbd +dubvkqrcywm +uqdkybcrw + +hvwialzjfqecpukxdobr +fhkeaczluqwbpvrxdoji +qkabjohpwcurvxlidezf + +zjrqhwbkcdv +cvxjhbqkpwdz +omdzlwkbqgcajhv +rjcvqwzhtdkbp + +olmvrwtagfuyjbzi +mfrtbuvjizaylgow +vafmjgyubzliorwt +orbmjpvigztwafuyl + +rgmodkbs +mogs +suogdrm +togm +mogv + +hf +fha +tfh + +bcazwpirygekfoxjdtnlmuqhvs +fzkrwyuslvmajxqdienot + +xdanjtygfrwhkzblpq +jamxfwzklchngrby +hyvlbzfjrwkonga + +shaxbk +rztkmls +nwjvucedk +okt + +rpvukdoaqfywlciehjnt +qxwhtregcnilvapskuodf +ltacrhfwquvnizkdjpoey +vtqekcpnwauflhiord +hvqlkurptfaiwnemodc + +huqwrpfsilxotcazvygdnj +navdfwistcpzljgruqxoyh +lhdipqtczywaxunbfojvrsg +wotlyvzfjdqgcuarhnxpsi +qfgyonxuzavspjrdhlciwt + +qdzjxfhpnmbwtuskyceg +sxyaqfwcjehkprodzvg +iykjhqscdzfpwxoevg +qsveyhjxczwgdolfkp + +jf +xn +gpw +k +n + +nc +c +c + +iyfavqodmwgzspceblxuhk +favzwqtgkyspuixdcbhr + +hdcazlv +wtqbg +seu +krbju + +myldhzr +wutkednmhla +yidhlvcmr +omhrdgfqblpc +jlsmdxh + +omnhyavdercx +qzncxyamro +wmxynozpbauric +kcnwomxyrba +pnocxymrka + +bj +ybjk +bj + +lgqkmsndwhx +knxsqdmhlgw +msxdqwnghlk +nyxcmgwkseqhldtv + +th +qzxyw +a +m +ohu + +sujpydikhnv +vnjyhuitksp +ajenhpviskuy + +gnjvqlwfxor +fithnsacxjbkmez + +rf +uwklarfc +xrf +vrfd +fjr + +gtoxeicdfqm +gtiqmeochpdx +tedlycbxqmigao + +muxsonhgp +yudpsohm +shpmou +rmpohus +ojmhups + +cjsgzxr +axclosqg +cgxs +cgxsj +ixscg + +v +v +srgbv +vo + +doaphkmvec +adrwme +wytmaesdbun +ieqgzdxfjyam + +lcgmfa +agflc +alcfg +faolgk + +i +ibe + +jemfp +mp +pms +mp + +u +u +rda +u + +hzdl +xrgdz +vjfgdzr +zknswaeuidcmq +zd + +rjwpoqyvzcxektf +xqzwjvetofrcypk +exwjyovkrfzqpct +zctewjxlnorpqakfvy +otxcrkyqfpjewzv + +vyhnmjlgekxobps +prgbyltswioquvfmzex + +q +feq +dqwx +q +q + +i +vbytcon +zksragjq +xdf + +lqtzbjudwhm +etgyxpcvarsnko + +dupshvrnafz +zafnhrpvodus +vzpsufdnrhxa + +ylkzmodvqg +dgmvzqkloy +qkvzgdloym +glqomyzvdk +mldgqkyvoz + +v +o +v + +actqvguieyrf +uvzgaryipqtl +hrlixgyvatu +dsjokyumvirgwt + +q +q + +xqln +lqxnu +xqn +oqxvns + +i +i +xi +i + +cxtnd +dtxcn +vxctdn + +vspoaczketurxdwj +vkjlrwznespouxfcadtg +pwsrxvedktacojzu + +qdis +sud +dnsquvf +bexgrdsj + +mfjcevsywhnuplxiqrzba +ibxrpeunqhzscyfljwmv +yjbqzixfvsupcrhwlenm + +wpvmzkhb +zbvkhpwm +mbhyizvwakp + +bqfzaeoig +fbzixgaoq +foqizgb +dkibvjquszgofy +ogbfizq + +wnz +nwz +nzw + +vthxfdk +hfdkgt +vsfdthxkq + +uzr +rltz +krfqz + +aoshypdlikqfutvebgjnz +qgtdkobisc +rotbdmcwgskqxi + +trbziwe +qlmuxkbyngrt + +nuqdyjmg +nmgqydu +uqmyicgwnvld + +phmc +pd +pd + +slj +usqjl + +q +q +q +q + +zsryajnihfexcguvltk +zvhcanygretxiuk +izcquegtyhxvnakr +nrixgcuaevtyhzk +aeckhzgyqxnvtrui + +bkyhnwitqoflxuz +oqhzbntkuwyxfa +hxbywtkqnzouf +qwgkxntozihyubf +nxkzusfeocbtqwy + +xwloszbpcatn +pwzblgtanoc +abcngtwlozp +lfzabtnwpoc + +paof +paof +aokpf + +yermvpgouhilaxtsf +hiuapfsmvergxl +ulemxsipgvhfar +gfimvphualerxs +pusxveifrmglha + +qwzfjcbxvhaedmu +hczufqwejvmabdx +bvumhayeoxcqdfzjw +awhvdxnfcqzebjmu +xcfwaqubhdzmjve + +p +u + +pabrkst +kptxsb +nofjptbglks + +pwxtihaoryfqjcmk +yrzwjqiokaevmx +ypmdqrkgxubljownai + +wrezth +nbvma + +cxz +xzc + +botydczsvwgikrfa +otkfryqwmgnacisubzxd +zfcdkyaosrbtvigw + +rpestzqxokcb +qrxgimauceftnzkbhdsjw + +msuerxvhajnckb +rcahunbemkljsx +cgmsvxrhjbkuna +zxabprinwjmcshku +rucajnktbmxsh + +infwrgjphdvokebsqzy +eahcnxpljksfqbwdum +ktdpefljwqnabhs + +oilcxdjheuyprna +cpydlhaorjxuie +jzairyhpcouxeldn +hucoibrejxyldap + +jbiglmtowxvkdch +ygmjiwtdlohcxkv +cwtfxlhkmsgnvojid +rakpdiolcvxegjtmhwz +chojlykxmvtgiudw + +vnqoimutgcwyhx +iwqnecovmyg +dsgmiqeyocwnv + +wzjtrynsfqkga +awxkqtnjozdruyg +yngqeajwtzkr + +jrg +jgx +jg +gj +gj + +ryaxghznduqmkve +kxnrfzbye +nzysjlbriexk +rzfxjclenykpw +teyzrkxwno + +mhlaqj +luajh +jhla +jalh + +rdbvoqszekg +ekltghbudosivqarz +qkbgsreovzd + +r +r +r + +il +io +ix +i + +nkyrthauqjb +jyktnabhrgq + +rkjnluewc +ybgmizxto +efwlprvc + +ga +a +a +w +a + +goexmwfchknjbliap +hbxcklgnfipajwmot + +nwzgbjo +njwyclbsk +nhqjirbwv +fwvbnrjo +wjbnud + +thlemzwakn +taylrneqzmh +exsovpcnzitmfua +aetmjzn + +hcozjrtsx +sxrczhtoq +ohxgzirsct + +yojqc +ocqy +oqycd +aycqo +doqcy + +jvuigo +zvujgx + +isolkxcghzvfpajdeuyrb +hutcjnmxgyqvrkeow + +rocqg +g +gcsx +gile +ngu + +jwhoelbgiscfzakmx +wtxkmcoslzigjebafh +fzshoicblxgkemwaj + +mubtlkhjspeynw +lkstuweyjmbhnp + +tdpy +dypt + +set +ts +stol +ts + +tfisjzu +tusfzji +fusjizt +szfitju + +cwlvjiuqkgom +twedofxgvynjqa + +jhuwldvt +twhd +trwdh + +mzlqyv +gzydvqm +mejzytqvb +qmybzv + +qsdpagrf +ybfuikxm +fjdprszch +jdzcofn + +cuemfrdviynwko +ucisbdwftjyxh + +wim +wi +wi +wi + +velqabhypocmxjs +ckvqlnybrughtmapwdzs + +fleghjbtvqrzdpy +njfzrpqyhbkvdlwet +lefdyjvxrhtbqpz + +n +qn +dpn + +hsdxgiartqfczkmeoy +dmothqjezsfyikgx +wsgndtmezoyikqhfx +dfsxqpotemigyknzh + +dhirx +jxbltqdrf +rxnzdyw +xyrdw + +gztrajypuesxmonwlhdbf +opjvelthnqxgfkbdsayrzmwu + +dsqzkpj +kspqjdyz +qszdpljkm +zjpqksdn + +bdvmoeinsw +ldvma +pcytgzqrhufxmjk + +qtvdacproxhyfeig +iqevdchgxtypfr +iqyedcpgxfrvht + +tnkvcfobej +jicwsrbxeamy + +rvqnbulwdgocf +kxgoulzs +mlugyok +kuehijpagtlo + +pnayvm +vmpany +mpvnya +ymapvn +manvpy + +juandk +bqamunz +cnuxt +oshgeinw +nur + +artidpmywzx +bowqmgenkcruj + +ymbgfnv +mynvbfgl +bmfyng +mnfgbiy +nfymgb + +yc +x +y +ksfv +o + +t +gmq +lhrx +zfvb + +rzaokythm +madgkjqyhltz +thaozykm + +jlecfkhazwyqtrsgn +clrwndzstjfqkgeamh +zenxwahslptgrfcjkq + +lhn +qztv +yp + +gv +xqg +cwpierytzuh + +u +tvfy +uo +j + +ywofspubhrgjmcilekv +skejhiorglvbyufw +arezwfukjbgysvhlio + +xpnldkub +wkdnqupx +gkyjduxon + +qubrihmgokzjclvytdfaw +brueisfpazonxcqk + +mykiwzenjtblqasdoux +njuxkbytmwleqridzspa +aubkqjmyinslwdxzte + +kjdn +ts +xw +sypu +c + +iumldrvwogjbs +ujwsemlrvdibgo + +zlknvwbhy +nzms +nitsz +rnzm + +ngde +lge +buatigrcvz +xewgy +jlopdg + +xjnythqakgsruicbld +ezfwpmov + +es +se +nsaer +sxcwplje +gems + +r +s +r +r + +enkqydmrgjvsbhau +hmbgservnjkuyd +dherisgymjvbunk +beyvnhjxgumsrikd + +a +aex +oa +oa + +ibedyc +ondfctsjy +cdykvga +ywacdbvuq + +mlowux +wqplxc +lhxkwp +pwxl +lxws + +truzalwqfpcinjoh +baxwplhjrzvgfynqoic + +fdbshvkcm +dcgzskfwb +iadczkfb +ydfrqcobk + +gpisnoletr +symv +qhmfws + +bjfm +ml +mvcd +mv + +levr +v +qv +vq +v + +j +j +j + +uepmnys +ymgphe + +bvlrqpgj +qbvgrpmlj +vpjgrlqcb + +fmsuteojyqchwrdv +rdyefmqoschwj + +cnudzpksyvbeoxrijqa +iuokqscnjyvpzedarxb +sxijkqybuoavpdrzcen +zckabxsoerjduvpqiyn + +qdwinxo +cxabnqgmiwo +ienqflorpxy + +tsbxdevwi +evbtwidx +vbextiwd +dvtwixeb + +pedufvxjgarqzwy +zvgpfyqrtu +lfzybuscgmvonpr + +pgmqjt +ulaib + +jefg +vb + +ltqevp +grik +qelv + +jh +xh +h + +diaukxtvohzwnbecsgjr +znyrixahutkgbsopvewjcd +zxsbcivunhqojegrtfakwd +dwuzeagjhtcvrbnikoxs + +qnasfbreph +bpka +lpbao +paylb + +flmoxzuakb +dhtnicpys + +vsnxozukyfqmj +ritpgwelahdbc + +ndripfaw +fry +rf +rfy +rf + +dqpouiscz +dfouc +wocdlmuneb + +coiwvtezuf +tvzofcwui +cfoiwutvz +uvtocwfiz +ntvuoczifpw + +aycwonkebidt +vbekioyctad +ckmafdbiyroet + +bne +ben +ebny +nheb + +bcnvuf +fvubqnc +fuvnbc +bcevnuf + +catnl +anclt +catnl +tngcal +nlzcato + +pcohyrgfwitkjzxa +pswmtxigkzhlrjafy +rfahwkxzgtjynspi +vhfgpjtinwxakyzr +jebyraqiwfzkgtuhxdp + +ifzpyvnrxscqmealb +ypnrofazxsbelqvmci +mzxfpgroayqnbscvlie +cesyrfqvixkbhznpalm +pqsenbmxzrfyvidcal + +zyrnivgqhjxsopftadmk +humogbldxfecrpqjwa + +lgwkuxemhaifprosq +rgfsxaiwuqhkpmeol +axgfepmsukroliqhw +aiwqlusgfokmehxrp + +wmanq +owqpagm +abctmxq + +azsnmugchqfv +cqvsmfzebuhagn +qlwafvnxusgmczihd +ekzfcusqhypangvm + +jdfau +ufa +auf +ufna +fua + +jrvyckoizf +bmka + +rvmoylsthqca +ohsriqxyaczt + +gkajpilzfeodcunwsvbrhmqtyx +jdqgenacxzrhotlwbvumfkpyis + +xewygnkia +xyinagekw +nkayewgix +anyxegkiw + +qlykxzcthnprfbej +rlckniyjtzpqbefxh +cxgbtephmkryzjfswqln +hpjtfkcebzyvxlrdnq +ftkyrxblchneqpijz + +p +b + +vc +t +t +t + +vagutfpbqhielzn +bpnligtvqhaefuz +fpevuihnqbatlzg +efvzlhigupqabtn +lufiztepnqghabv + +rfbsmiknjogvhyq +mqpikvjrtfonycsbdh +svyfkbhnpmiqrojz +whnsijavbuyqkrfom +kiyjxoqvblmhfrsn + +gaxwn +pgmeaw +bfxagw +gwlsa +gkawyc + +cxqozuawvliptyjhfs +ahvuqityolspfjwzxc +xifpthoyclaqzvsjwu + +syfbj +ysjfeb +fsbj +jbgsfwk + +rquip +pjiq +pqi +piq +dqpfikv + +p +kiwh +z +fyvmrc + +yh +hygs +haye + +uqxvaojkbw +jqawxuokvb +vuxbqkjawo + +pvzba +bymav +xbyavn +abv + +nfasjxqwrgimztvcludob +ldsxumwtircqvzbynofjga +uchrlvstdmixzkjanqgowbf + +xbsdla +hupjrknzficy +tveoa + +cafoqgjdemsnk +fjivltcdmg +fgdwphcumjb +vyfxjcrgzmid + +orciqajldy +ohdqiylacm + +y +y +yu +y + +li +ilh + +lta +avle + +wnkha +awnkh +nahw +vhanlwd + +cfmurandsiexvwq +vzidurtyboemj + +gosh +hoesg +hgotel +gobhj + +wransfipukq +riflauznhqbpt +rtvaiunfqocpl + +vdajgmsqrpefytzil +txdrisplvafzujk + +elwgstkh + +epwji +jpfe +hmsryxap + +za +abokz +tazefsl +apz +zbar + +wxtufcbpdlesrzkvhgmnyjaqo +oeflsvhjwmrznckxdaqgytu + +wxydrbvmokunatqpe +xoeawvpqtdbmskrun +ovwxrkuqatdpenbm +wreubavpxmtqdnko +xwpkontbvueaqdrm + +npjrtougxm +ptojgmrnx +ngmxpjtfr +jgzxmtrnkp + +c +sc +jg + +vszrmkhqjpgayc +otswxfuibdl + +snwpgtufhaqoxberyjmkdi +tsmbkenrfdujayhwpogqi +fkgsmebvjyanocwurhdqzi + +w +s +w +w +ciy + +ydxstgncopql +umfrvjawnekibhz + +xjw +jwx +xwj +jwx +wjx + +kwgxylvafh +fyvhxklawg +klhygafwv +wyfktslgahv +wkxlmyahfgv + +git +igt +gti +otgi +git + +vnih +vionh +invh + +pstycrxzeg +yrcgtzpe +ctpzyrgs +tkyvpcbgzmri +gzpytrc + +hvlq +hzj +hz + +knrgyxumlio +dyirljutgnv +zagpinwuyhr + +mzlvrsgpid +pftrocn +awqprfnhux + +wvlpjegodb +dvbegwjpol +lzdwjkfgpobveth + +slwmnda +swmdl +sqwdlm + +iahz +hzai +iazh +izha + +ozaq +zoq +zweqo +zoq + +a +qo + +vbylpk +gferiaouxwntc +qjk +hqmks + +kmtqnhjuorx +gjmutoxqdnr +uomnjxqt +omvpxuytqnj + +mdjgyzhnrbqlkixwup +umbnjkwsdolhizgrqpx + +estfmkocwlzua +wertfzuslakm +zsxntkfewylm + +ewozvybutrlc +pcmtlz +ctflzx +zsamtckl + +rcnabkwmljygzdhpos +rpadmzhwgbolknsycj +ojhgrczpwsymklbdan +hmrwybldcskaojgznp + +vuyj +rjuy +ugyvjz + +gtbvkoi +otkbvg + +wzmshqxk +uafswryemj +cvhskzwm +xwohmgqzcs + +fezyavinmdjxwqthp +uhmydqjoewfzaxt + +ytobegs +rebynogpaw +cgyboueh + +hqmen +okqwimt + +n +n +n +n +n + +mtgye +mezq + +njpgvcwbxzqhauds +nghbqsjawpvuxdzc +zsqdahuxwpvbgnjc +vhdaqbspzwgnucxj + +sfebtowpijhcl +xtokqyecmwphlid +urtighewvpoza +tbpofwinehd + +xmlctywhong +rliwocgutxaeyvn +ptydglnfjzxbso +nogqtlxmywauvh + +rjecz +aehocvg +pyufxqbmsltw + +wquytmaroexfgzkclvb +umtzxhavjsqgwrckpb + +cgvbhlyxtifkzsewjru +rhsftpjgmwabzlcvqkuxone + +ndgizukav +zuinkavdg +udzgkvai +wgudikvza + +kfvpnot +nvpotkf +ktpvfon +pokfnvt +vfoktpn + +kqrd +rdkq +krqd +vfrqkd +qkdr + +zyqijxlfdu +zdjfixyq +zihxyfjdq +xoyikqjdbfezg + +rq +qur + +bozhntm +oeprf + +ltx +ij +s +fyvhcdqkm + +cqivpm +vmcpqi + +ntb +tbfn +nbt +pbtn +cbnpt + +a +b +yexo +f +t + +tqfazuimjbxgsvedkp +exczvifmsqwakpjtbug +xijzfqcgsvkbpteamy +esorqhmlpnbaijvtgzfxk +evsjiztqmpafgxkb + +vhljf +iknboam + +kg +jbovgtl +g +gw +iugx + +j +j +j +j +j + +omsul +ucsim + +zykn +aisxbtez +lmzc +zl + +a +a +c +a + +pkso +noku + +rpo +opr + +jh +j +j + +akqpzhoyrjwitlcxvbdume +mwyrjqzavueokiphxlbtc +yxbrckaepwiomvzqltuhj +voithcspxmwlkyaujbeqrz + +naqe +efnq +qne +qenk + +chwluymniztgrxafdb +tghnclypeiufsbkwrxam +iynhrfluwgcmadtobx + +icgwkoretxmyuzaljdvq +qxgfkuicowleaszyvrdmj +gukrvdczaqojyliewmx +rzosixlycukgdmwejavq +qmuleoaygkrjdicxvzw + +erqbuao +peoaiqnf +axoqegwm + +ikaydnx +ykja +yksae + +jmwfaqxrztivlknscghbu +zkruqhclxainsgtjvfm + +mykilgzq +gqzmlki +kwlbiqrzpdgsxj +mgqkuaiznl +cloikfzgyuq + +euba +auewb +leabfu + +zoqb +boqz +obzq +qbzo +ozqb + +lrjvtqf +jrzqltvfha +tlqfjrv + +xosvzaq +qsoa +atqso +asolq +aoqs + +ckilsdrut +ldrsjtgenqiu + +etvizsnywkjobh +jskwoevzltyibnqh + +ctkpmiyohjgbuldarn +hoyfbkvdt +zwthxsoykbd + +dciagsvnmzyruephk +aslrwitjvenxgcd +vebdqnarctisgl + +nlzs +zobwxsln +zsnl +rsiucynlz + +gziwqfy +lodmh +knarujextpscbv + +uhmobwlgj +obhmwugl +hmabwuglo +oawblgumh +owlbughm + +ucsfwbizqdenro +npsrtkmeobfdg + +rvhcidqaysukjxbpgzoe +vauhokjrsybiqcdepzgx +cjibvqsxzoyrkeufphagd +cyzpukrhxdsebogajqvi + +zcojuprtbhg +pdwbauchjtsgkn +gprtulcfhjyba +xbecghvmjtpiu + +qclaiywnujprxdotf +fiuqtwlxocrnayjdp +wdfoacnjipyqtluxr +ejdyblqnihcftpwroavux +nqiayfgucrdjlwxopt + +xhzrepycnwsm +iaxfykeblwp + +eaqkisdgcojhzw +ckhbasd +ckdhpasb +hcpydabks +sckdha + +kn +nk +nuk \ No newline at end of file diff --git a/day06/parseGroupList.spec.ts b/day06/parseGroupList.spec.ts new file mode 100644 index 0000000..522d25f --- /dev/null +++ b/day06/parseGroupList.spec.ts @@ -0,0 +1,32 @@ +import { loadString } from '../lib/loader' +import { parseGroupList } from './parseGroupList' + +describe('parseGroupList', () => { + it('should parse a list of group answers', () => { + expect( + parseGroupList( + loadString(`abc + + a + b + c + + ab + ac + + a + a + a + a + + b`), + ), + ).toEqual([ + ['abc'], + ['a', 'b', 'c'], + ['ab', 'ac'], + ['a', 'a', 'a', 'a'], + ['b'], + ]) + }) +}) diff --git a/day06/parseGroupList.ts b/day06/parseGroupList.ts new file mode 100644 index 0000000..bd81b06 --- /dev/null +++ b/day06/parseGroupList.ts @@ -0,0 +1,12 @@ +export const parseGroupList = (input: string[]): string[][] => + input.reduce( + (list, line) => { + if (line.length === 0) { + list.push([]) + return list + } + list[list.length - 1].push(line) + return list + }, + [[]] as string[][], + ) diff --git a/day06/solution.spec.ts b/day06/solution.spec.ts new file mode 100644 index 0000000..82cda6b --- /dev/null +++ b/day06/solution.spec.ts @@ -0,0 +1,43 @@ +import { loader, loadString } from '../lib/loader' +import { collectAnswers } from './collectAnswers' +import { parseGroupList } from './parseGroupList' + +const load = loader(6) + +const sumAnswers = (answers: Record[]) => + answers + .map(Object.keys) + .map((a) => a.length) + .reduce((total, i) => total + i, 0) + +describe('Day 6: Custom Customs', () => { + describe('Part 1', () => { + it('should solve the sample', () => { + expect( + sumAnswers( + parseGroupList( + loadString(`abc + + a + b + c + + ab + ac + + a + a + a + a + + b`), + ).map(collectAnswers), + ), + ).toEqual(11) + }) + it('should solve', () => + expect( + sumAnswers(parseGroupList(load('input')).map(collectAnswers)), + ).toEqual(6735)) + }) +}) From 36a618cc7d07459039a1d9d348b004981e97f417 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Sun, 6 Dec 2020 11:58:16 +0100 Subject: [PATCH 25/60] feat(day06): part 2 --- day06/collectAnswers.spec.ts | 8 ++-- day06/collectAnswers.ts | 14 +++++-- day06/solution.spec.ts | 71 +++++++++++++++++++++++++++--------- 3 files changed, 69 insertions(+), 24 deletions(-) diff --git a/day06/collectAnswers.spec.ts b/day06/collectAnswers.spec.ts index dde50ae..09797b5 100644 --- a/day06/collectAnswers.spec.ts +++ b/day06/collectAnswers.spec.ts @@ -2,7 +2,9 @@ import { collectAnswers } from './collectAnswers' describe('collectAnswers', () => { it(`should collect all answers`, () => - expect(Object.keys(collectAnswers(['abcx', 'abcy', 'abcz']))).toHaveLength( - 6, - )) + expect( + Object.keys(collectAnswers(['abcx', 'abcy', 'abcz']).answers), + ).toHaveLength(6)) + it(`should count forms`, () => + expect(collectAnswers(['abcx', 'abcy', 'abcz']).n).toEqual(3)) }) diff --git a/day06/collectAnswers.ts b/day06/collectAnswers.ts index c90b206..b26564a 100644 --- a/day06/collectAnswers.ts +++ b/day06/collectAnswers.ts @@ -1,12 +1,20 @@ -export const collectAnswers = (forms: string[]): Record => +export const collectAnswers = ( + forms: string[], +): { answers: Record; n: number } => forms.reduce( (answered, form) => form.split('').reduce( (answered, a) => ({ ...answered, - [a]: (answered?.[a] ?? 0) + 1, + answers: { + ...answered.answers, + [a]: (answered.answers?.[a] ?? 0) + 1, + }, }), answered, ), - {} as Record, + { + n: forms.length, + answers: {} as Record, + }, ) diff --git a/day06/solution.spec.ts b/day06/solution.spec.ts index 82cda6b..3544b53 100644 --- a/day06/solution.spec.ts +++ b/day06/solution.spec.ts @@ -3,41 +3,76 @@ import { collectAnswers } from './collectAnswers' import { parseGroupList } from './parseGroupList' const load = loader(6) +const sample = `abc +a +b +c + +ab +ac + +a +a +a +a + +b` +const input = load('input') + +/** + * Count the questions to which anyone answered "yes" + */ const sumAnswers = (answers: Record[]) => answers .map(Object.keys) .map((a) => a.length) .reduce((total, i) => total + i, 0) +/** + * Count the questions to which everyone answered "yes" + */ +const sumAnswersByAll = ( + answers: { + answers: Record + n: number + }[], +) => + answers.reduce( + (total, { answers, n }) => + total + Object.values(answers).filter((v) => v === n).length, + 0, + ) + describe('Day 6: Custom Customs', () => { describe('Part 1', () => { it('should solve the sample', () => { expect( sumAnswers( - parseGroupList( - loadString(`abc - - a - b - c - - ab - ac - - a - a - a - a - - b`), - ).map(collectAnswers), + parseGroupList(loadString(sample)) + .map(collectAnswers) + .map(({ answers }) => answers), ), ).toEqual(11) }) it('should solve', () => expect( - sumAnswers(parseGroupList(load('input')).map(collectAnswers)), + sumAnswers( + parseGroupList(input) + .map(collectAnswers) + .map(({ answers }) => answers), + ), ).toEqual(6735)) }) + describe('Part 2', () => { + it('should solve the sample', () => { + expect( + sumAnswersByAll(parseGroupList(loadString(sample)).map(collectAnswers)), + ).toEqual(6) + }) + it('should solve', () => + expect( + sumAnswersByAll(parseGroupList(input).map(collectAnswers)), + ).toEqual(3221)) + }) }) From 21320380d175c3fdf9f828a9a9c3023b48dc3450 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Sun, 6 Dec 2020 12:05:27 +0100 Subject: [PATCH 26/60] refactor: improve readability --- day06/collectAnswers.ts | 10 ++++++++-- day06/parseGroupList.ts | 3 +++ day06/solution.spec.ts | 16 ++++++++++++---- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/day06/collectAnswers.ts b/day06/collectAnswers.ts index b26564a..cb7ea69 100644 --- a/day06/collectAnswers.ts +++ b/day06/collectAnswers.ts @@ -1,6 +1,12 @@ +export type Answers = Record + +/** + * Creates a record that counts how often a specific answer has been given + * in a list of forms (AKA a group's answers) + */ export const collectAnswers = ( forms: string[], -): { answers: Record; n: number } => +): { answers: Answers; n: number } => forms.reduce( (answered, form) => form.split('').reduce( @@ -15,6 +21,6 @@ export const collectAnswers = ( ), { n: forms.length, - answers: {} as Record, + answers: {} as Answers, }, ) diff --git a/day06/parseGroupList.ts b/day06/parseGroupList.ts index bd81b06..ea25dc5 100644 --- a/day06/parseGroupList.ts +++ b/day06/parseGroupList.ts @@ -1,3 +1,6 @@ +/** + * Group the list of answers. A blank line denotes a new group. + */ export const parseGroupList = (input: string[]): string[][] => input.reduce( (list, line) => { diff --git a/day06/solution.spec.ts b/day06/solution.spec.ts index 3544b53..11d86c7 100644 --- a/day06/solution.spec.ts +++ b/day06/solution.spec.ts @@ -1,5 +1,5 @@ import { loader, loadString } from '../lib/loader' -import { collectAnswers } from './collectAnswers' +import { Answers, collectAnswers } from './collectAnswers' import { parseGroupList } from './parseGroupList' const load = loader(6) @@ -23,10 +23,14 @@ const input = load('input') /** * Count the questions to which anyone answered "yes" */ -const sumAnswers = (answers: Record[]) => +const sumAnswers = (answers: Answers[]) => answers + // collectAnswers counts how often answer was given + // in keys to the Answers record .map(Object.keys) + // count how many entries the record has .map((a) => a.length) + // sum it up .reduce((total, i) => total + i, 0) /** @@ -34,13 +38,17 @@ const sumAnswers = (answers: Record[]) => */ const sumAnswersByAll = ( answers: { - answers: Record + answers: Answers n: number }[], ) => answers.reduce( (total, { answers, n }) => - total + Object.values(answers).filter((v) => v === n).length, + // add the number of answers which have been given by all to the total + total + + Object.values(answers) + // filter out those answers which not have been given by everyone + .filter((v) => v === n).length, 0, ) From 9d9cd5a02dd3a2cc46a18e0c448e66f4b3346b26 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Sun, 6 Dec 2020 15:45:04 +0100 Subject: [PATCH 27/60] refactor: move solution methods --- day06/solution.spec.ts | 36 +++--------------------------------- day06/sumAnswers.ts | 14 ++++++++++++++ day06/sumAnswersByAll.ts | 20 ++++++++++++++++++++ 3 files changed, 37 insertions(+), 33 deletions(-) create mode 100644 day06/sumAnswers.ts create mode 100644 day06/sumAnswersByAll.ts diff --git a/day06/solution.spec.ts b/day06/solution.spec.ts index 11d86c7..df92591 100644 --- a/day06/solution.spec.ts +++ b/day06/solution.spec.ts @@ -1,6 +1,8 @@ import { loader, loadString } from '../lib/loader' -import { Answers, collectAnswers } from './collectAnswers' +import { collectAnswers } from './collectAnswers' import { parseGroupList } from './parseGroupList' +import { sumAnswers } from './sumAnswers' +import { sumAnswersByAll } from './sumAnswersByAll' const load = loader(6) const sample = `abc @@ -20,38 +22,6 @@ a b` const input = load('input') -/** - * Count the questions to which anyone answered "yes" - */ -const sumAnswers = (answers: Answers[]) => - answers - // collectAnswers counts how often answer was given - // in keys to the Answers record - .map(Object.keys) - // count how many entries the record has - .map((a) => a.length) - // sum it up - .reduce((total, i) => total + i, 0) - -/** - * Count the questions to which everyone answered "yes" - */ -const sumAnswersByAll = ( - answers: { - answers: Answers - n: number - }[], -) => - answers.reduce( - (total, { answers, n }) => - // add the number of answers which have been given by all to the total - total + - Object.values(answers) - // filter out those answers which not have been given by everyone - .filter((v) => v === n).length, - 0, - ) - describe('Day 6: Custom Customs', () => { describe('Part 1', () => { it('should solve the sample', () => { diff --git a/day06/sumAnswers.ts b/day06/sumAnswers.ts new file mode 100644 index 0000000..cf2d091 --- /dev/null +++ b/day06/sumAnswers.ts @@ -0,0 +1,14 @@ +import { Answers } from './collectAnswers' + +/** + * Count the questions to which anyone answered "yes" + */ +export const sumAnswers = (answers: Answers[]): number => + answers + // collectAnswers counts how often answer was given + // in keys to the Answers record + .map(Object.keys) + // count how many entries the record has + .map((a) => a.length) + // sum it up + .reduce((total, i) => total + i, 0) diff --git a/day06/sumAnswersByAll.ts b/day06/sumAnswersByAll.ts new file mode 100644 index 0000000..d661f94 --- /dev/null +++ b/day06/sumAnswersByAll.ts @@ -0,0 +1,20 @@ +import { Answers } from './collectAnswers' + +/** + * Count the questions to which everyone answered "yes" + */ +export const sumAnswersByAll = ( + answers: { + answers: Answers + n: number + }[], +): number => + answers.reduce( + (total, { answers, n }) => + // add the number of answers which have been given by all to the total + total + + Object.values(answers) + // filter out those answers which not have been given by everyone + .filter((v) => v === n).length, + 0, + ) From 1c98ce9526f9c0f4542dc8095ac93b815c41bac5 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Mon, 7 Dec 2020 08:29:50 +0100 Subject: [PATCH 28/60] feat(day07): parse rules --- day07/packBag.spec.ts | 44 +++++++++++++++++++++++++++ day07/parseRules.spec.ts | 65 ++++++++++++++++++++++++++++++++++++++++ day07/parseRules.ts | 39 ++++++++++++++++++++++++ 3 files changed, 148 insertions(+) create mode 100644 day07/packBag.spec.ts create mode 100644 day07/parseRules.spec.ts create mode 100644 day07/parseRules.ts diff --git a/day07/packBag.spec.ts b/day07/packBag.spec.ts new file mode 100644 index 0000000..62ec841 --- /dev/null +++ b/day07/packBag.spec.ts @@ -0,0 +1,44 @@ +import { loadString } from '../lib/loader' +import { parseRules } from './parseRules' +/** + * These rules specify the required contents for 9 bag types. In this example, + * every faded blue bag is empty, every vibrant plum bag contains 11 bags + * (5 faded blue and 6 dotted black), and so on. + */ +const sample = `light red bags contain 1 bright white bag, 2 muted yellow bags. +dark orange bags contain 3 bright white bags, 4 muted yellow bags. +bright white bags contain 1 shiny gold bag. +muted yellow bags contain 2 shiny gold bags, 9 faded blue bags. +shiny gold bags contain 1 dark olive bag, 2 vibrant plum bags. +dark olive bags contain 3 faded blue bags, 4 dotted black bags. +vibrant plum bags contain 5 faded blue bags, 6 dotted black bags. +faded blue bags contain no other bags. +dotted black bags contain no other bags.` + +describe('packBag', () => { + /** + * You have a shiny gold bag. If you wanted to carry it in at least one + * other bag, how many different bag colors would be valid for the outermost + * bag? (In other words: how many colors can, eventually, contain at least + * one shiny gold bag?) + * + * In the above rules, the following options would be available to you: + * + * A bright white bag, which can hold your shiny gold bag directly. + * A muted yellow bag, which can hold your shiny gold bag directly, plus some other bags. + * A dark orange bag, which can hold bright white and muted yellow bags, either of which could then hold your shiny gold bag. + * A light red bag, which can hold bright white and muted yellow bags, either of which could then hold your shiny gold bag. + * So, in this example, the number of bag colors that can eventually contain at least one shiny gold bag is 4. + */ + it('should pack a shiny gold bag', () => { + const rules = parseRules(loadString(sample)) + const packager = packBag(rules) + const colors = Object.keys(packager('shiny gold')) + expect(colors).toEqual([ + 'bright white', + 'muted yellow', + 'dark orange', + 'light red', + ]) + }) +}) diff --git a/day07/parseRules.spec.ts b/day07/parseRules.spec.ts new file mode 100644 index 0000000..8a0196b --- /dev/null +++ b/day07/parseRules.spec.ts @@ -0,0 +1,65 @@ +import { loadString } from '../lib/loader' +import { parseRules, parseRuleLine } from './parseRules' + +const sample = `light red bags contain 1 bright white bag, 2 muted yellow bags. +dark orange bags contain 3 bright white bags, 4 muted yellow bags. +bright white bags contain 1 shiny gold bag. +muted yellow bags contain 2 shiny gold bags, 9 faded blue bags. +shiny gold bags contain 1 dark olive bag, 2 vibrant plum bags. +dark olive bags contain 3 faded blue bags, 4 dotted black bags. +vibrant plum bags contain 5 faded blue bags, 6 dotted black bags. +faded blue bags contain no other bags. +dotted black bags contain no other bags.` + +describe('parseRule', () => { + it.each([ + [ + 'light red bags contain 1 bright white bag, 2 muted yellow bags.', + { + color: 'light red', + children: { 'bright white': 1, 'muted yellow': 2 }, + }, + ], + [ + 'bright white bags contain 1 shiny gold bag.', + { + color: 'bright white', + children: { 'shiny gold': 1 }, + }, + ], + [ + 'faded blue bags contain no other bags.', + { + color: 'faded blue', + }, + ], + ])(`should parse %s into %s`, (rule, expected) => { + expect(parseRuleLine(rule)).toEqual(expected) + }) +}) + +describe('parseRules', () => { + it('should parse the rules', () => { + /* + Test that it parses the rules into trees: + + light red + / \ + 1 2 + / \ + white muted yellow + + */ + const rules = parseRules(loadString(sample)) + expect(Object.keys(rules)).toHaveLength(9) + // top level bag is light red + const lightRed = rules['light red'] + expect(lightRed.color).toEqual('light red') + // It does not have parents + expect(lightRed.children?.['bright white']).toEqual(1) + expect(lightRed.children?.['muted yellow']).toEqual(2) + // Bottom level is faded blue + const fadedBlue = rules['faded blue'] + expect(fadedBlue.children).toBeUndefined() + }) +}) diff --git a/day07/parseRules.ts b/day07/parseRules.ts new file mode 100644 index 0000000..ce565e0 --- /dev/null +++ b/day07/parseRules.ts @@ -0,0 +1,39 @@ +export type Bag = { + color: string + children?: Record +} + +const ruleDef = /^(?[a-z ]+) bags contain (?.+)/ +const contentsRuleDef = /^(?[0-9]+) (?[a-z ]+) bags?/ + +export const parseRuleLine = (rule: string): Bag | undefined => { + const match = ruleDef.exec(rule) + if (match === null) return + const children = match.groups.contents + .split(',') + .map((s) => s.trim()) + .filter((s) => s !== undefined) + .filter((s) => !/no other bags/.test(s)) + .map((s) => contentsRuleDef.exec(s)) + .reduce( + (children, child) => ({ + ...children, + [child?.groups.color]: parseInt(child?.groups.amount, 10), + }), + {}, + ) + return { + color: match.groups.color as string, + children: Object.keys(children).length === 0 ? undefined : children, + } +} + +export const parseRules = (rules: string[]): Record => + rules.reduce((bags, rule) => { + const bag = parseRuleLine(rule) + if (bag === undefined) return bags + return { + ...bags, + [bag.color]: bag, + } + }, {}) From 25a2f8ef1721ca779c442762e893e51d236e9230 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Mon, 7 Dec 2020 09:08:04 +0100 Subject: [PATCH 29/60] feat(day07): part 1 --- day07/input.txt | 594 +++++++++++++++++++++++++++++++++++++++++ day07/packBag.spec.ts | 44 --- day07/packBag.ts | 22 ++ day07/parseRules.ts | 20 +- day07/solution.spec.ts | 41 +++ 5 files changed, 668 insertions(+), 53 deletions(-) create mode 100644 day07/input.txt delete mode 100644 day07/packBag.spec.ts create mode 100644 day07/packBag.ts create mode 100644 day07/solution.spec.ts diff --git a/day07/input.txt b/day07/input.txt new file mode 100644 index 0000000..cf4a371 --- /dev/null +++ b/day07/input.txt @@ -0,0 +1,594 @@ +dotted blue bags contain 5 wavy green bags, 3 pale beige bags. +dull lime bags contain 1 dotted olive bag, 3 dim brown bags. +mirrored magenta bags contain 3 mirrored gray bags, 2 plaid beige bags, 4 dull brown bags, 3 pale plum bags. +posh coral bags contain 2 light blue bags, 2 dotted purple bags, 1 pale fuchsia bag, 2 light cyan bags. +bright orange bags contain 2 shiny chartreuse bags. +plaid salmon bags contain 1 faded coral bag, 4 clear lavender bags, 5 wavy tan bags. +wavy lavender bags contain 2 drab purple bags, 2 light brown bags, 2 wavy tomato bags, 1 mirrored plum bag. +clear indigo bags contain 4 dark magenta bags, 2 shiny brown bags. +posh salmon bags contain 4 dull tomato bags, 3 drab black bags, 5 mirrored chartreuse bags, 4 shiny blue bags. +mirrored coral bags contain 4 faded aqua bags, 2 plaid plum bags, 5 striped tan bags, 5 wavy tomato bags. +dotted purple bags contain 1 faded gold bag. +bright purple bags contain 2 muted indigo bags, 3 pale maroon bags, 4 dim coral bags, 2 dark blue bags. +drab olive bags contain 2 shiny coral bags. +dim orange bags contain 1 faded turquoise bag. +drab aqua bags contain 1 faded black bag, 4 clear lavender bags. +bright salmon bags contain 2 bright aqua bags. +dim brown bags contain 1 bright yellow bag, 3 faded cyan bags, 4 dotted chartreuse bags. +clear tan bags contain 2 posh tomato bags, 4 bright tan bags, 1 mirrored gray bag. +faded beige bags contain 2 mirrored olive bags, 5 dark chartreuse bags. +drab chartreuse bags contain 1 shiny white bag. +faded coral bags contain 4 dotted green bags, 2 dim violet bags, 3 striped magenta bags. +vibrant crimson bags contain 5 shiny gray bags, 2 muted black bags, 2 posh brown bags. +mirrored aqua bags contain 5 bright brown bags, 3 mirrored tomato bags, 3 bright bronze bags, 1 shiny magenta bag. +dotted salmon bags contain 2 muted tan bags, 4 light bronze bags. +vibrant salmon bags contain 5 dull yellow bags, 5 wavy tan bags, 3 light fuchsia bags, 1 drab tan bag. +vibrant olive bags contain 2 pale white bags, 2 dull coral bags, 1 mirrored magenta bag, 2 clear crimson bags. +shiny plum bags contain 3 dotted chartreuse bags, 1 striped tomato bag, 4 clear indigo bags. +pale fuchsia bags contain 1 mirrored indigo bag, 2 plaid aqua bags, 1 striped teal bag, 4 drab salmon bags. +wavy beige bags contain 1 mirrored coral bag, 1 bright plum bag, 2 dark lavender bags. +drab silver bags contain 5 vibrant gold bags, 5 pale gray bags. +light salmon bags contain 2 drab chartreuse bags, 3 faded gray bags, 3 pale gray bags, 1 clear olive bag. +faded red bags contain 5 dull chartreuse bags, 2 plaid aqua bags. +clear maroon bags contain 2 muted lavender bags. +dull green bags contain 3 pale olive bags, 5 vibrant gold bags, 2 clear teal bags, 5 dotted plum bags. +striped white bags contain 1 dim cyan bag. +pale coral bags contain 5 dim purple bags, 3 faded silver bags, 3 dim blue bags, 3 dotted brown bags. +drab green bags contain 5 pale teal bags. +posh tomato bags contain 4 drab fuchsia bags, 5 dark brown bags. +shiny chartreuse bags contain 5 dim maroon bags, 5 dull indigo bags, 5 pale purple bags, 3 vibrant gold bags. +dark plum bags contain 4 muted tan bags. +faded green bags contain 4 drab lavender bags. +pale tomato bags contain 3 bright maroon bags, 4 pale turquoise bags, 4 dark gold bags, 3 dull indigo bags. +striped aqua bags contain 1 dull gray bag, 5 dim blue bags, 5 wavy cyan bags. +dotted lavender bags contain 4 pale plum bags, 2 bright coral bags. +light gold bags contain 3 light tan bags, 4 clear indigo bags, 3 shiny tan bags. +striped maroon bags contain 5 drab tan bags, 1 pale black bag. +plaid black bags contain 3 dull fuchsia bags. +dim beige bags contain 1 dim teal bag, 1 muted salmon bag. +mirrored teal bags contain 2 bright coral bags, 4 dotted brown bags, 5 vibrant white bags, 3 clear magenta bags. +faded gold bags contain no other bags. +faded yellow bags contain 1 faded brown bag, 3 clear tomato bags. +bright violet bags contain 1 faded lime bag, 5 dark chartreuse bags, 1 shiny black bag, 3 vibrant yellow bags. +shiny fuchsia bags contain 2 dotted plum bags. +dim aqua bags contain 1 dim cyan bag. +dotted fuchsia bags contain 5 muted blue bags, 1 pale brown bag, 2 shiny salmon bags. +dim fuchsia bags contain 3 muted tomato bags, 2 striped lime bags, 2 clear white bags, 2 striped blue bags. +faded teal bags contain 1 wavy gold bag, 1 clear coral bag, 3 pale crimson bags. +dull plum bags contain 1 bright tan bag, 5 light violet bags, 5 shiny black bags. +light cyan bags contain 1 mirrored turquoise bag, 1 dim gray bag, 5 faded white bags. +vibrant cyan bags contain 1 dotted gold bag, 1 mirrored indigo bag. +bright coral bags contain 1 pale lavender bag, 3 mirrored olive bags, 3 muted tan bags. +dim chartreuse bags contain 3 pale white bags, 5 faded white bags, 3 mirrored magenta bags, 5 faded black bags. +pale green bags contain 3 faded white bags, 5 dotted lavender bags. +wavy gray bags contain 3 wavy tomato bags, 4 dull gray bags, 4 shiny teal bags, 5 pale beige bags. +dotted cyan bags contain 4 bright white bags. +shiny olive bags contain 2 wavy chartreuse bags, 5 dim chartreuse bags, 4 pale gold bags, 1 posh crimson bag. +drab maroon bags contain 3 clear olive bags, 4 dotted blue bags, 4 dim magenta bags. +striped purple bags contain 4 wavy beige bags, 1 pale orange bag, 1 pale brown bag. +dull olive bags contain 2 vibrant yellow bags. +faded tomato bags contain 4 light turquoise bags. +dotted maroon bags contain 2 faded cyan bags, 3 muted tomato bags, 1 shiny aqua bag, 3 bright orange bags. +wavy turquoise bags contain 1 drab magenta bag. +plaid green bags contain 1 light blue bag, 1 mirrored silver bag, 5 striped gold bags. +drab indigo bags contain 5 dull aqua bags. +plaid crimson bags contain 1 posh yellow bag, 5 shiny cyan bags. +drab salmon bags contain 3 bright lavender bags, 4 bright violet bags, 1 mirrored brown bag, 4 shiny gold bags. +dim turquoise bags contain 5 wavy brown bags, 4 mirrored yellow bags. +pale bronze bags contain 2 dotted bronze bags, 5 dim purple bags, 1 plaid red bag. +striped blue bags contain 5 drab fuchsia bags. +wavy aqua bags contain 5 posh plum bags, 1 striped bronze bag, 4 dark magenta bags. +posh beige bags contain 1 faded lime bag, 3 wavy white bags, 2 mirrored gray bags. +plaid magenta bags contain 4 light olive bags, 3 faded salmon bags. +plaid gray bags contain 1 light indigo bag, 5 muted indigo bags. +mirrored white bags contain 3 muted gray bags, 4 dotted beige bags, 5 dotted salmon bags, 5 muted gold bags. +dull chartreuse bags contain 3 muted gray bags. +faded cyan bags contain 4 light violet bags, 4 faded lime bags, 2 bright silver bags, 3 pale olive bags. +mirrored red bags contain 1 dotted violet bag, 5 bright plum bags, 2 pale violet bags, 4 pale plum bags. +shiny purple bags contain 2 pale magenta bags, 2 shiny fuchsia bags. +vibrant plum bags contain 5 light bronze bags, 3 plaid lavender bags, 1 shiny coral bag, 2 vibrant yellow bags. +shiny lime bags contain 1 posh black bag. +mirrored salmon bags contain 5 dull magenta bags, 2 clear gray bags, 1 dim indigo bag, 4 light brown bags. +dotted violet bags contain 2 pale violet bags. +muted orange bags contain 5 dark coral bags, 3 mirrored tomato bags, 1 dotted green bag. +bright lime bags contain 3 shiny gold bags, 4 plaid lavender bags, 3 dull gold bags. +pale lavender bags contain no other bags. +clear aqua bags contain 2 plaid turquoise bags. +clear white bags contain 4 shiny coral bags, 5 striped gold bags, 2 mirrored magenta bags. +clear chartreuse bags contain 1 posh lime bag. +wavy silver bags contain 3 clear orange bags, 2 clear lavender bags. +posh cyan bags contain 1 shiny crimson bag. +light plum bags contain 1 plaid lavender bag. +dim lime bags contain 5 bright crimson bags, 3 dark green bags, 2 vibrant green bags, 3 pale maroon bags. +dim coral bags contain 4 muted crimson bags, 1 mirrored plum bag. +pale salmon bags contain 5 wavy orange bags, 4 dotted gold bags, 4 posh brown bags. +faded chartreuse bags contain 1 dotted chartreuse bag, 3 wavy orange bags. +faded olive bags contain 5 pale blue bags, 3 dim yellow bags, 1 dotted gray bag, 2 dim crimson bags. +clear lime bags contain 3 dull fuchsia bags, 4 wavy red bags. +bright blue bags contain 3 mirrored violet bags, 3 pale gold bags, 4 drab salmon bags, 5 dull silver bags. +muted maroon bags contain 5 dull salmon bags, 3 dim gray bags. +clear teal bags contain 2 muted tomato bags, 4 faded turquoise bags. +shiny white bags contain 1 posh red bag, 3 dotted red bags. +light magenta bags contain 4 drab olive bags. +vibrant coral bags contain 5 pale lavender bags, 5 plaid red bags. +wavy yellow bags contain 3 vibrant beige bags, 4 muted crimson bags, 4 bright white bags, 1 pale maroon bag. +bright black bags contain 2 striped maroon bags. +plaid lavender bags contain 1 drab turquoise bag. +light crimson bags contain 2 wavy chartreuse bags. +muted salmon bags contain 2 bright orange bags, 3 dotted plum bags, 3 light magenta bags. +striped teal bags contain 4 dark chartreuse bags, 1 dim maroon bag. +dull bronze bags contain no other bags. +dotted bronze bags contain 1 striped orange bag, 5 shiny cyan bags, 2 muted tan bags. +dark gold bags contain 3 pale plum bags, 3 mirrored olive bags. +mirrored lime bags contain 3 dim maroon bags, 3 light violet bags, 2 mirrored turquoise bags, 3 vibrant yellow bags. +clear violet bags contain 2 drab salmon bags, 4 pale gray bags, 4 striped tan bags, 5 mirrored blue bags. +plaid beige bags contain 3 dull gold bags. +shiny salmon bags contain 3 dark chartreuse bags, 4 bright yellow bags, 5 dark gold bags, 2 muted tomato bags. +dull brown bags contain 1 bright silver bag, 4 muted tan bags. +dull orange bags contain 1 dim bronze bag. +vibrant lavender bags contain 4 dotted violet bags, 3 striped lime bags. +light blue bags contain 2 shiny teal bags, 5 striped orange bags, 5 shiny gray bags. +plaid teal bags contain 4 dark turquoise bags, 4 posh indigo bags, 1 mirrored tan bag. +drab black bags contain 4 vibrant chartreuse bags, 4 dim turquoise bags. +light beige bags contain 3 pale aqua bags. +mirrored gray bags contain 5 dark chartreuse bags. +faded black bags contain 4 shiny salmon bags. +light yellow bags contain 1 dotted magenta bag. +bright red bags contain 5 bright bronze bags, 3 dull white bags, 3 dim plum bags, 3 light tan bags. +mirrored lavender bags contain 5 faded chartreuse bags. +shiny coral bags contain 3 plaid chartreuse bags, 1 pale lavender bag. +clear bronze bags contain 4 mirrored silver bags, 1 dim coral bag, 3 posh teal bags. +dotted yellow bags contain 1 bright crimson bag, 5 dotted olive bags. +light bronze bags contain 4 dim maroon bags, 3 shiny crimson bags. +wavy tomato bags contain 5 dull red bags, 3 wavy cyan bags, 4 dark gold bags. +dotted turquoise bags contain 5 muted silver bags. +posh orange bags contain 2 bright beige bags, 5 vibrant chartreuse bags, 3 drab green bags. +wavy bronze bags contain 1 dark coral bag. +plaid tan bags contain 1 vibrant bronze bag. +wavy red bags contain 4 dotted gray bags, 2 pale purple bags, 1 bright tan bag. +dull turquoise bags contain 4 dull crimson bags. +faded brown bags contain 5 muted teal bags. +dark violet bags contain 1 dim gold bag, 1 dim beige bag, 5 dull orange bags. +bright brown bags contain 1 plaid aqua bag, 4 light cyan bags. +dull teal bags contain 4 shiny teal bags. +dotted white bags contain 3 pale black bags, 2 drab black bags, 5 faded fuchsia bags, 1 plaid black bag. +dark magenta bags contain 5 shiny teal bags, 4 pale purple bags. +mirrored maroon bags contain 3 plaid chartreuse bags, 2 muted orange bags, 5 pale gray bags, 4 drab green bags. +faded magenta bags contain 1 bright green bag, 5 pale lavender bags, 4 posh fuchsia bags, 2 pale teal bags. +wavy violet bags contain 4 bright indigo bags. +posh gold bags contain 1 bright green bag, 3 dim cyan bags. +muted silver bags contain 3 light lime bags, 4 wavy indigo bags, 5 striped turquoise bags, 5 clear blue bags. +muted fuchsia bags contain 2 pale olive bags, 1 light maroon bag, 3 plaid blue bags, 1 light blue bag. +posh turquoise bags contain 3 light lime bags, 4 wavy tomato bags, 3 vibrant blue bags, 3 posh fuchsia bags. +dull purple bags contain 1 striped tan bag, 2 vibrant tomato bags, 2 dim brown bags, 2 shiny fuchsia bags. +light fuchsia bags contain 2 mirrored turquoise bags, 4 striped lime bags, 4 faded white bags. +dull gold bags contain 5 plaid tan bags, 2 light bronze bags, 1 striped tan bag. +wavy olive bags contain 4 vibrant maroon bags, 1 drab salmon bag. +pale beige bags contain 1 wavy white bag, 1 dotted orange bag, 4 dim gray bags. +clear crimson bags contain 4 dull blue bags. +dotted tomato bags contain 5 dotted olive bags. +drab purple bags contain 1 striped tan bag, 3 mirrored olive bags, 4 mirrored turquoise bags. +plaid red bags contain 2 bright cyan bags, 5 pale lavender bags, 3 dark chartreuse bags, 1 dotted plum bag. +posh silver bags contain 5 light olive bags, 5 bright white bags, 5 light violet bags, 4 faded orange bags. +muted teal bags contain 2 wavy violet bags. +light red bags contain 2 dull white bags, 4 drab fuchsia bags. +bright crimson bags contain 4 light lavender bags, 2 dotted plum bags. +plaid purple bags contain 5 dull magenta bags, 5 light lavender bags. +dark gray bags contain 4 dull plum bags, 5 muted tomato bags, 3 drab brown bags. +vibrant gray bags contain 4 posh black bags. +plaid fuchsia bags contain 1 posh lime bag. +striped chartreuse bags contain 4 posh teal bags, 1 bright purple bag, 1 clear white bag. +dull fuchsia bags contain 3 bright brown bags, 3 striped olive bags, 2 faded white bags. +muted beige bags contain 4 drab chartreuse bags. +vibrant beige bags contain 4 striped crimson bags. +vibrant indigo bags contain 5 dull plum bags, 1 dull maroon bag, 2 striped white bags. +dull silver bags contain 5 dull white bags, 2 dull gold bags, 4 shiny cyan bags, 4 wavy gold bags. +dim blue bags contain 5 posh yellow bags, 5 dim maroon bags. +posh white bags contain 4 dim teal bags, 4 light brown bags. +mirrored tomato bags contain 1 posh purple bag, 3 striped aqua bags. +light black bags contain 1 mirrored chartreuse bag, 3 muted yellow bags, 4 muted tan bags. +plaid silver bags contain 2 dull beige bags, 5 bright tan bags, 5 posh tomato bags. +shiny violet bags contain 1 plaid beige bag, 3 faded teal bags, 4 dotted tomato bags, 1 shiny orange bag. +dull black bags contain 5 vibrant coral bags, 2 clear orange bags. +dim white bags contain 5 drab brown bags, 2 plaid lavender bags. +wavy salmon bags contain 5 dull white bags, 5 vibrant crimson bags, 2 posh silver bags, 1 dim purple bag. +dark green bags contain 1 dull magenta bag, 3 light tomato bags, 1 pale olive bag, 5 pale brown bags. +light chartreuse bags contain 1 dotted silver bag, 3 bright maroon bags, 4 vibrant silver bags, 5 bright coral bags. +dim green bags contain 3 wavy bronze bags, 3 bright tan bags, 1 dotted magenta bag. +shiny tan bags contain 3 striped turquoise bags, 4 drab brown bags, 2 wavy tan bags, 3 light fuchsia bags. +muted lime bags contain 4 dark yellow bags, 5 vibrant blue bags. +dark coral bags contain 5 plaid chartreuse bags. +striped fuchsia bags contain 4 light lavender bags, 4 dull gray bags, 5 wavy cyan bags, 2 striped orange bags. +shiny maroon bags contain 3 striped olive bags, 5 dull green bags, 4 shiny cyan bags. +dotted red bags contain 5 light violet bags, 4 plaid chartreuse bags. +dim salmon bags contain 1 dim blue bag, 3 dotted indigo bags, 4 pale crimson bags, 3 drab blue bags. +pale magenta bags contain 5 pale violet bags, 1 dark blue bag. +clear coral bags contain 2 faded turquoise bags, 2 shiny cyan bags, 4 dull red bags. +dim black bags contain 4 dim aqua bags, 5 pale blue bags. +clear cyan bags contain 2 light violet bags, 5 drab salmon bags, 4 dark teal bags. +dull gray bags contain 2 bright lavender bags, 3 pale plum bags, 5 dull plum bags. +dull salmon bags contain 4 posh violet bags, 3 mirrored indigo bags, 3 plaid tomato bags. +pale cyan bags contain 2 pale chartreuse bags, 4 light brown bags, 1 plaid beige bag, 3 light maroon bags. +faded indigo bags contain 3 dim maroon bags, 3 mirrored violet bags. +wavy orange bags contain 3 plaid purple bags. +dim plum bags contain 2 wavy tomato bags. +pale turquoise bags contain 2 faded lime bags. +drab orange bags contain 2 mirrored turquoise bags, 5 plaid tomato bags, 3 dotted blue bags, 5 wavy red bags. +mirrored cyan bags contain 5 muted chartreuse bags, 4 dim cyan bags, 5 posh fuchsia bags. +vibrant purple bags contain 5 dotted turquoise bags. +posh red bags contain 4 faded turquoise bags, 2 light violet bags. +muted crimson bags contain 5 shiny fuchsia bags. +drab magenta bags contain 1 dull fuchsia bag. +wavy tan bags contain 1 mirrored plum bag. +vibrant tomato bags contain 3 plaid blue bags, 3 clear fuchsia bags, 5 dark yellow bags. +mirrored gold bags contain 3 muted purple bags, 5 dark indigo bags, 5 dotted brown bags, 1 mirrored olive bag. +mirrored plum bags contain 3 faded turquoise bags. +muted gray bags contain 4 light bronze bags. +light olive bags contain 3 bright lavender bags, 4 wavy orange bags, 3 clear lavender bags. +faded tan bags contain 4 vibrant red bags, 1 drab bronze bag, 5 mirrored plum bags. +posh plum bags contain 4 dotted gold bags, 4 dotted plum bags, 2 vibrant gold bags. +faded maroon bags contain 5 dim red bags. +drab teal bags contain 5 faded chartreuse bags, 2 faded silver bags. +clear black bags contain 2 pale red bags, 3 plaid black bags. +mirrored indigo bags contain 3 dim chartreuse bags, 1 wavy violet bag, 1 dull green bag. +pale teal bags contain 4 wavy indigo bags. +drab cyan bags contain 4 dotted plum bags, 5 dim red bags. +striped salmon bags contain 4 clear olive bags, 4 wavy orange bags. +faded bronze bags contain 5 mirrored olive bags, 2 dark green bags. +muted magenta bags contain 2 mirrored beige bags, 1 wavy orange bag, 3 light salmon bags. +wavy plum bags contain 5 light cyan bags, 2 drab turquoise bags. +dark lavender bags contain 2 dim coral bags. +faded lavender bags contain 4 wavy bronze bags, 3 dim yellow bags. +dark maroon bags contain 5 striped orange bags. +clear fuchsia bags contain 1 dull brown bag, 4 posh red bags, 3 plaid purple bags. +shiny magenta bags contain 2 striped maroon bags, 5 mirrored olive bags, 2 drab lime bags. +wavy coral bags contain 4 posh maroon bags, 5 dim white bags, 5 pale indigo bags, 5 dotted maroon bags. +dark silver bags contain 3 posh plum bags. +shiny blue bags contain 1 wavy indigo bag, 4 dark magenta bags, 4 light turquoise bags. +clear lavender bags contain 1 bright violet bag, 4 wavy cyan bags, 2 dim blue bags, 5 posh violet bags. +shiny orange bags contain 2 pale tomato bags, 1 pale teal bag. +mirrored beige bags contain 5 dotted gold bags, 1 faded violet bag, 4 striped gray bags. +bright cyan bags contain 4 muted tomato bags, 1 drab turquoise bag, 4 bright yellow bags. +vibrant fuchsia bags contain 4 striped tan bags, 1 dark black bag, 4 plaid olive bags, 2 wavy aqua bags. +pale olive bags contain 4 posh yellow bags, 4 pale plum bags. +dotted crimson bags contain 3 dim gray bags, 1 mirrored lime bag. +vibrant orange bags contain 5 striped orange bags, 3 plaid blue bags. +light brown bags contain 4 dotted chartreuse bags. +muted plum bags contain 1 muted indigo bag, 5 plaid yellow bags, 1 vibrant silver bag, 1 drab turquoise bag. +dotted chartreuse bags contain 5 dotted red bags, 5 light lavender bags, 4 pale black bags, 3 muted tomato bags. +bright chartreuse bags contain 5 dim salmon bags, 5 shiny salmon bags, 4 bright plum bags, 2 dark lavender bags. +dim gray bags contain 3 dull indigo bags. +faded fuchsia bags contain 2 muted blue bags, 1 mirrored blue bag, 2 dotted green bags, 5 mirrored olive bags. +striped tomato bags contain 4 dull gray bags, 1 vibrant plum bag, 3 mirrored coral bags. +clear turquoise bags contain 4 light orange bags, 3 faded black bags, 5 mirrored lavender bags, 5 posh white bags. +dotted gray bags contain 4 mirrored turquoise bags, 5 light lavender bags, 1 vibrant yellow bag, 4 dull bronze bags. +shiny beige bags contain 3 plaid silver bags, 2 faded chartreuse bags, 2 vibrant lavender bags, 2 wavy olive bags. +pale red bags contain 4 mirrored olive bags. +mirrored silver bags contain 2 vibrant maroon bags, 5 plaid chartreuse bags, 4 vibrant plum bags, 5 faded white bags. +plaid aqua bags contain 5 faded aqua bags, 4 dotted fuchsia bags. +dull yellow bags contain 5 bright turquoise bags, 3 posh plum bags, 1 pale white bag. +faded orange bags contain 3 dotted bronze bags, 1 mirrored tan bag. +wavy green bags contain 1 wavy turquoise bag. +posh tan bags contain 5 striped lavender bags, 4 posh tomato bags. +wavy crimson bags contain 4 pale lavender bags, 2 mirrored tan bags, 5 plaid beige bags. +striped yellow bags contain 3 shiny green bags, 5 dark gold bags, 4 drab teal bags, 3 drab olive bags. +pale plum bags contain 2 dull indigo bags, 1 dotted plum bag, 1 bright yellow bag. +pale yellow bags contain 2 bright green bags, 5 dull beige bags, 3 light coral bags, 3 dull red bags. +striped silver bags contain 1 clear crimson bag, 4 shiny salmon bags. +bright silver bags contain 2 shiny black bags, 3 faded gold bags, 5 bright yellow bags. +shiny red bags contain 1 pale turquoise bag, 5 shiny beige bags. +posh chartreuse bags contain 5 dotted maroon bags, 5 shiny bronze bags, 1 shiny cyan bag, 3 pale aqua bags. +wavy teal bags contain 4 mirrored plum bags, 4 drab silver bags, 3 pale green bags, 1 mirrored lime bag. +posh olive bags contain 2 dim salmon bags, 1 faded black bag, 1 light lime bag. +dark fuchsia bags contain 3 mirrored indigo bags. +dark cyan bags contain 4 muted indigo bags, 4 shiny crimson bags, 2 drab turquoise bags. +posh magenta bags contain 5 bright blue bags, 1 dull turquoise bag. +muted red bags contain 3 light violet bags, 2 dark cyan bags. +vibrant gold bags contain 2 dotted chartreuse bags, 5 pale brown bags, 1 mirrored brown bag, 5 plaid lavender bags. +muted purple bags contain 3 dim blue bags, 3 wavy red bags, 1 clear lavender bag. +dim magenta bags contain 5 muted tan bags, 4 striped olive bags, 5 vibrant gold bags. +faded plum bags contain 1 faded black bag, 1 muted green bag. +light violet bags contain 3 mirrored turquoise bags, 1 dull bronze bag. +faded salmon bags contain 1 pale salmon bag, 1 light teal bag. +posh black bags contain 2 wavy purple bags. +plaid white bags contain 1 shiny salmon bag, 3 posh purple bags. +mirrored green bags contain 3 bright tan bags, 1 plaid white bag, 3 mirrored plum bags. +dark red bags contain 2 bright purple bags, 2 muted white bags, 5 drab cyan bags, 5 plaid olive bags. +vibrant teal bags contain 5 striped olive bags, 1 pale olive bag. +dotted green bags contain 3 dark cyan bags. +dark indigo bags contain 3 bright brown bags, 3 drab white bags, 2 muted purple bags, 2 plaid silver bags. +drab tan bags contain 3 dotted gray bags, 2 faded black bags, 1 dull brown bag, 2 drab salmon bags. +vibrant chartreuse bags contain 5 pale brown bags. +mirrored olive bags contain 2 dim blue bags, 2 shiny gold bags, 4 light lavender bags. +light silver bags contain 3 drab orange bags, 5 light plum bags, 2 dotted olive bags. +light indigo bags contain 4 pale yellow bags, 1 vibrant violet bag, 4 dull cyan bags, 5 dotted tomato bags. +pale orange bags contain 4 pale silver bags, 4 vibrant tomato bags. +vibrant bronze bags contain 5 dark yellow bags. +dull beige bags contain 4 dotted gray bags, 4 pale lavender bags, 5 light lavender bags, 3 shiny coral bags. +bright gray bags contain 3 bright silver bags. +vibrant green bags contain 4 muted tan bags, 3 light lavender bags, 5 light magenta bags. +plaid violet bags contain 4 bright lime bags, 2 mirrored olive bags, 4 faded blue bags. +striped bronze bags contain 1 plaid chartreuse bag. +dim crimson bags contain 3 bright yellow bags, 1 dull gray bag. +posh purple bags contain 3 light fuchsia bags, 5 pale black bags, 5 wavy orange bags, 3 drab blue bags. +clear beige bags contain 4 plaid black bags. +striped gray bags contain 2 pale green bags, 4 light fuchsia bags. +plaid olive bags contain 2 mirrored gray bags. +muted green bags contain 1 plaid coral bag. +clear salmon bags contain 4 muted black bags, 1 bright white bag, 1 drab tomato bag, 2 shiny orange bags. +dark aqua bags contain 5 light bronze bags, 1 wavy turquoise bag. +drab tomato bags contain 5 dim chartreuse bags. +wavy magenta bags contain 3 posh brown bags. +dull crimson bags contain 1 mirrored tan bag, 4 dotted crimson bags, 5 vibrant indigo bags. +plaid turquoise bags contain 1 dark bronze bag, 4 bright maroon bags. +dim cyan bags contain 4 plaid red bags, 4 bright silver bags, 5 vibrant gold bags. +faded blue bags contain 3 plaid salmon bags, 3 clear cyan bags, 1 wavy aqua bag, 4 mirrored teal bags. +light orange bags contain 4 posh chartreuse bags, 3 shiny maroon bags, 4 dim teal bags, 4 drab chartreuse bags. +bright white bags contain 5 drab chartreuse bags. +clear red bags contain 1 dull magenta bag, 1 light cyan bag. +drab gold bags contain 4 plaid violet bags, 5 muted gold bags. +muted chartreuse bags contain 1 plaid crimson bag, 4 vibrant red bags, 1 drab turquoise bag, 5 posh black bags. +mirrored black bags contain 1 dim white bag, 1 clear gold bag. +bright indigo bags contain 1 vibrant gold bag, 2 pale purple bags. +muted indigo bags contain 2 dull plum bags. +striped tan bags contain 2 dotted chartreuse bags. +dim tan bags contain 2 dim red bags, 4 light violet bags, 1 clear beige bag. +muted tomato bags contain 1 faded gold bag, 2 bright yellow bags, 3 dotted plum bags. +vibrant turquoise bags contain 2 light tan bags, 4 wavy salmon bags, 1 dark tan bag, 1 dull tan bag. +dotted magenta bags contain 4 plaid blue bags, 1 plaid turquoise bag, 5 striped silver bags. +dark orange bags contain 3 faded bronze bags. +light tomato bags contain 2 dull bronze bags, 1 pale brown bag, 4 bright violet bags. +dim teal bags contain 5 dull brown bags. +muted lavender bags contain 4 dark yellow bags, 4 shiny teal bags, 2 faded aqua bags, 5 wavy cyan bags. +bright beige bags contain 3 muted black bags, 4 bright blue bags. +light purple bags contain 1 pale lavender bag, 2 shiny aqua bags. +plaid blue bags contain 4 dull beige bags, 3 dull brown bags, 3 dotted crimson bags. +striped lavender bags contain 3 dotted chartreuse bags. +bright tomato bags contain 1 posh violet bag, 3 shiny aqua bags. +wavy indigo bags contain 4 mirrored olive bags, 1 faded turquoise bag, 1 vibrant coral bag, 4 bright gray bags. +pale black bags contain 5 bright silver bags, 3 mirrored turquoise bags. +mirrored turquoise bags contain no other bags. +bright plum bags contain 2 faded turquoise bags. +shiny yellow bags contain 1 clear gold bag. +plaid bronze bags contain 1 dotted teal bag, 3 faded white bags, 2 shiny green bags. +striped beige bags contain 3 vibrant teal bags. +wavy cyan bags contain 5 posh yellow bags. +light tan bags contain 2 vibrant red bags. +pale brown bags contain 2 bright yellow bags, 4 pale lavender bags, 5 mirrored turquoise bags, 1 drab turquoise bag. +bright teal bags contain 3 dark green bags, 2 dull white bags. +drab yellow bags contain 5 dotted purple bags. +shiny cyan bags contain 4 vibrant yellow bags. +vibrant silver bags contain 5 mirrored yellow bags, 5 dull indigo bags, 3 faded cyan bags, 4 faded turquoise bags. +clear plum bags contain 4 pale lavender bags. +posh teal bags contain 2 muted tan bags. +striped crimson bags contain 1 dull plum bag, 2 shiny fuchsia bags, 4 dim maroon bags, 3 bright yellow bags. +dull lavender bags contain 2 clear fuchsia bags, 5 pale silver bags, 5 dim salmon bags, 4 muted salmon bags. +posh indigo bags contain 5 faded chartreuse bags, 5 dark green bags, 5 dark blue bags. +wavy blue bags contain 5 muted yellow bags. +dull magenta bags contain 5 pale brown bags. +mirrored bronze bags contain 3 posh turquoise bags. +posh aqua bags contain 1 dim white bag, 2 clear tomato bags, 2 pale maroon bags. +pale purple bags contain 2 dotted fuchsia bags. +mirrored chartreuse bags contain 5 plaid yellow bags, 5 posh tan bags, 4 vibrant silver bags, 3 drab green bags. +dotted black bags contain 5 muted aqua bags, 1 wavy lime bag, 2 bright lime bags. +plaid chartreuse bags contain 2 bright yellow bags, 2 faded gold bags, 1 pale lavender bag. +dotted plum bags contain 4 dull bronze bags, 4 dim blue bags. +clear gold bags contain 2 bright tan bags, 5 wavy teal bags. +dark crimson bags contain 4 bright teal bags, 2 wavy gray bags, 1 bright chartreuse bag. +faded gray bags contain 2 mirrored magenta bags. +dim gold bags contain 3 drab white bags. +clear green bags contain 2 pale beige bags. +dotted gold bags contain 3 dull indigo bags. +striped lime bags contain 2 dotted chartreuse bags. +clear brown bags contain 4 dark olive bags, 2 striped yellow bags, 4 dotted red bags, 5 dotted plum bags. +striped gold bags contain 1 wavy white bag, 3 posh tomato bags, 4 light magenta bags. +muted brown bags contain 1 clear gold bag. +plaid tomato bags contain 4 plaid plum bags, 2 pale chartreuse bags. +dark salmon bags contain 5 pale plum bags, 3 striped lime bags, 4 dotted gray bags. +drab brown bags contain 1 wavy orange bag, 4 dark cyan bags, 1 drab white bag. +pale gray bags contain 3 bright crimson bags, 1 bright yellow bag. +plaid maroon bags contain 1 pale coral bag. +dim violet bags contain 5 wavy blue bags, 4 shiny coral bags, 4 pale black bags, 3 posh yellow bags. +faded white bags contain 2 pale plum bags. +mirrored orange bags contain 3 striped maroon bags, 1 dull bronze bag, 2 pale aqua bags. +wavy black bags contain 1 faded violet bag, 1 plaid purple bag, 5 dim coral bags, 2 mirrored plum bags. +dim silver bags contain 2 muted brown bags, 1 posh plum bag. +dark tomato bags contain 5 dull magenta bags, 2 faded aqua bags, 3 vibrant lime bags, 3 drab silver bags. +dotted silver bags contain 2 dotted red bags. +muted yellow bags contain 4 drab purple bags, 3 striped olive bags. +shiny lavender bags contain 5 plaid purple bags, 2 vibrant crimson bags, 4 dull olive bags. +clear tomato bags contain 4 shiny bronze bags. +dark turquoise bags contain 5 dim brown bags. +drab coral bags contain 3 dull orange bags. +dotted beige bags contain 1 wavy lavender bag, 5 dull orange bags, 4 dull lime bags, 3 dull blue bags. +dark teal bags contain 3 muted indigo bags, 5 dark gold bags, 3 dull green bags, 2 plaid tan bags. +light lavender bags contain 2 dim maroon bags, 4 muted tomato bags, 4 dull plum bags. +dim lavender bags contain 4 light magenta bags, 4 shiny fuchsia bags, 5 wavy chartreuse bags, 1 faded chartreuse bag. +vibrant brown bags contain 4 dull bronze bags, 1 clear green bag, 3 posh orange bags, 3 mirrored silver bags. +pale tan bags contain 3 bright tomato bags, 5 pale maroon bags, 3 wavy teal bags. +muted black bags contain 1 light lime bag. +posh lime bags contain 3 bright crimson bags, 4 posh beige bags, 1 bright cyan bag. +light aqua bags contain 4 posh olive bags, 4 light tan bags, 4 wavy tan bags, 2 dotted blue bags. +dotted tan bags contain 3 dark yellow bags, 4 posh silver bags, 3 dark beige bags. +shiny black bags contain no other bags. +mirrored fuchsia bags contain 1 bright purple bag, 3 posh lime bags, 5 dim black bags. +dim purple bags contain 3 muted indigo bags. +wavy white bags contain 2 pale olive bags. +bright magenta bags contain 5 dull aqua bags, 3 dull green bags, 2 shiny turquoise bags. +drab white bags contain 1 plaid yellow bag, 2 shiny green bags, 5 posh beige bags, 5 plaid tan bags. +mirrored crimson bags contain 2 shiny teal bags. +pale white bags contain 2 muted indigo bags. +shiny bronze bags contain 5 mirrored crimson bags, 3 pale brown bags, 4 clear chartreuse bags. +clear blue bags contain 1 drab chartreuse bag, 4 striped turquoise bags, 1 plaid aqua bag, 5 pale aqua bags. +shiny brown bags contain 1 dotted bronze bag, 4 shiny fuchsia bags, 4 drab fuchsia bags, 4 dark lavender bags. +dotted teal bags contain 4 dull olive bags, 4 clear black bags. +posh gray bags contain 1 wavy salmon bag. +dark white bags contain 4 pale lime bags, 4 plaid beige bags, 5 dull fuchsia bags, 1 pale yellow bag. +dull cyan bags contain 4 muted lavender bags, 2 plaid tan bags, 2 dim blue bags. +dark olive bags contain 2 dim indigo bags, 1 dark brown bag, 5 dark yellow bags, 4 dull gray bags. +vibrant tan bags contain 4 bright tan bags, 1 pale tomato bag. +drab beige bags contain 4 muted magenta bags, 2 bright plum bags, 3 pale beige bags. +clear magenta bags contain 2 dull indigo bags, 5 vibrant green bags. +posh yellow bags contain no other bags. +vibrant magenta bags contain 2 dark green bags. +posh blue bags contain 2 muted chartreuse bags, 3 vibrant coral bags. +striped violet bags contain 1 dotted orange bag, 5 striped red bags, 5 dull lime bags. +dark yellow bags contain 2 shiny turquoise bags. +bright turquoise bags contain 2 bright yellow bags, 2 posh violet bags, 4 bright plum bags. +pale silver bags contain 4 vibrant bronze bags, 4 faded purple bags, 1 shiny green bag, 1 plaid lavender bag. +muted white bags contain 3 mirrored olive bags. +light green bags contain 5 shiny plum bags, 4 pale lavender bags, 5 faded gold bags. +drab lime bags contain 2 plaid beige bags. +pale chartreuse bags contain 4 dotted brown bags, 1 dark black bag, 3 mirrored plum bags, 1 faded black bag. +mirrored violet bags contain 5 plaid beige bags. +vibrant white bags contain 5 muted tomato bags. +faded violet bags contain 1 dull brown bag, 1 mirrored brown bag. +drab bronze bags contain 3 dim indigo bags, 1 dim magenta bag, 1 bright gray bag. +posh lavender bags contain 1 wavy black bag, 2 wavy magenta bags. +vibrant aqua bags contain 2 light lavender bags, 1 faded crimson bag, 4 dark green bags, 3 mirrored white bags. +bright green bags contain 1 dark gray bag. +shiny turquoise bags contain 2 bright yellow bags. +pale aqua bags contain 3 shiny gold bags, 2 drab silver bags, 3 drab salmon bags. +faded silver bags contain 3 striped teal bags, 5 mirrored indigo bags. +shiny indigo bags contain 3 wavy olive bags, 3 dim blue bags, 2 faded gold bags, 4 clear fuchsia bags. +vibrant yellow bags contain 5 dark chartreuse bags, 3 dull indigo bags, 1 bright tan bag. +shiny aqua bags contain 3 striped olive bags, 2 shiny teal bags, 5 pale teal bags. +bright maroon bags contain 2 striped lime bags. +dark purple bags contain 5 dotted brown bags, 1 bright olive bag, 3 drab orange bags, 1 mirrored olive bag. +drab lavender bags contain 5 wavy beige bags, 4 bright gold bags, 3 wavy cyan bags. +dull white bags contain 4 posh teal bags, 4 mirrored turquoise bags, 1 muted purple bag. +clear silver bags contain 1 dull lime bag, 2 dim plum bags, 5 wavy maroon bags, 3 striped cyan bags. +bright lavender bags contain 1 muted tomato bag. +pale crimson bags contain 1 striped tan bag, 4 dotted red bags, 3 dotted fuchsia bags, 5 dull brown bags. +posh maroon bags contain 3 dark magenta bags, 3 pale gray bags. +vibrant lime bags contain 1 dull maroon bag, 4 light purple bags, 5 dull orange bags, 1 dull purple bag. +drab turquoise bags contain no other bags. +dark bronze bags contain 2 light tomato bags, 1 vibrant gold bag, 3 posh yellow bags, 5 light lavender bags. +muted cyan bags contain 3 dotted black bags, 1 faded violet bag, 5 bright violet bags. +dim tomato bags contain 3 drab chartreuse bags, 1 striped coral bag, 3 pale tan bags. +light teal bags contain 3 pale gray bags. +muted olive bags contain 1 dull green bag, 3 bright violet bags, 1 dark yellow bag. +mirrored tan bags contain 3 dark salmon bags, 1 vibrant red bag, 1 dull gray bag. +light turquoise bags contain 5 posh red bags, 1 dim chartreuse bag, 3 vibrant beige bags, 2 mirrored lavender bags. +dark brown bags contain 2 clear fuchsia bags, 2 dull bronze bags, 3 striped aqua bags, 1 shiny gold bag. +striped orange bags contain 3 shiny gold bags, 1 bright crimson bag, 3 vibrant gold bags. +bright bronze bags contain 3 faded cyan bags, 3 dim blue bags, 2 faded gold bags, 2 bright tan bags. +dotted orange bags contain 4 dim magenta bags, 1 faded white bag, 1 muted tan bag. +dull red bags contain 3 posh yellow bags, 3 pale plum bags. +clear orange bags contain 5 wavy chartreuse bags, 5 dull aqua bags, 1 faded bronze bag, 5 faded chartreuse bags. +dark blue bags contain 2 striped lime bags. +wavy brown bags contain 4 shiny green bags. +wavy purple bags contain 2 dim maroon bags, 1 vibrant coral bag, 4 posh teal bags, 2 dark teal bags. +muted tan bags contain 5 bright violet bags, 4 dotted red bags, 5 dull beige bags, 1 dim gray bag. +posh crimson bags contain 3 dark bronze bags, 3 pale salmon bags, 2 muted beige bags, 2 bright aqua bags. +pale blue bags contain 3 wavy black bags, 5 dotted brown bags, 5 drab chartreuse bags, 5 bright gray bags. +striped plum bags contain 4 light turquoise bags. +posh green bags contain 5 dull cyan bags, 4 muted tan bags, 1 faded silver bag, 3 vibrant black bags. +mirrored yellow bags contain 5 shiny fuchsia bags, 3 bright tan bags, 4 drab fuchsia bags. +striped brown bags contain 4 wavy turquoise bags. +dim bronze bags contain 4 faded black bags, 1 striped lavender bag. +plaid cyan bags contain 5 posh lime bags, 2 wavy white bags, 3 posh crimson bags. +plaid brown bags contain 2 dark bronze bags. +vibrant blue bags contain 4 wavy orange bags, 4 drab silver bags, 2 muted tan bags. +dull violet bags contain 5 posh black bags, 4 shiny tomato bags. +striped magenta bags contain 3 faded white bags, 1 vibrant bronze bag. +striped coral bags contain 1 dull blue bag, 5 faded lime bags, 4 vibrant coral bags. +plaid lime bags contain 1 shiny black bag, 3 mirrored coral bags. +dim indigo bags contain 4 dim coral bags, 3 wavy indigo bags, 3 vibrant red bags, 3 wavy orange bags. +pale violet bags contain 2 drab purple bags. +striped turquoise bags contain 4 drab teal bags, 5 striped bronze bags. +striped indigo bags contain 3 striped purple bags, 4 shiny beige bags. +light coral bags contain 3 bright coral bags, 5 pale teal bags, 5 dull red bags, 3 mirrored tomato bags. +drab plum bags contain 4 dull white bags, 3 clear crimson bags, 2 wavy lavender bags. +dim maroon bags contain no other bags. +shiny crimson bags contain 2 dull indigo bags, 1 bright cyan bag. +dull aqua bags contain 3 dark yellow bags. +drab violet bags contain 4 striped aqua bags. +shiny gold bags contain 2 pale brown bags, 2 dotted chartreuse bags, 1 vibrant gold bag, 4 dull magenta bags. +plaid indigo bags contain 4 striped purple bags, 3 clear brown bags. +muted gold bags contain 1 shiny cyan bag. +dotted lime bags contain 3 dotted olive bags, 4 light tan bags, 4 bright bronze bags, 3 vibrant plum bags. +vibrant red bags contain 2 wavy red bags, 4 dotted chartreuse bags, 5 dim coral bags. +faded lime bags contain 5 drab turquoise bags, 4 pale lavender bags. +striped black bags contain 2 light white bags, 4 posh lime bags, 3 posh chartreuse bags. +posh brown bags contain 1 muted white bag, 2 striped teal bags, 1 faded chartreuse bag. +dotted aqua bags contain 5 dull orange bags. +clear yellow bags contain 5 pale fuchsia bags, 2 posh cyan bags. +faded crimson bags contain 4 vibrant black bags. +dull tan bags contain 1 plaid crimson bag. +dark chartreuse bags contain 1 mirrored turquoise bag. +clear purple bags contain 1 dotted magenta bag, 2 striped lavender bags. +pale indigo bags contain 2 drab tan bags, 2 shiny indigo bags. +plaid coral bags contain 2 dark olive bags, 1 pale aqua bag, 5 shiny bronze bags. +faded purple bags contain 4 dull aqua bags, 2 drab turquoise bags, 5 wavy crimson bags, 2 faded turquoise bags. +pale gold bags contain 3 plaid blue bags, 3 muted plum bags, 4 wavy tomato bags, 3 clear lavender bags. +plaid plum bags contain 1 plaid lavender bag, 3 wavy purple bags. +vibrant violet bags contain 1 posh teal bag, 4 dull gray bags, 5 dim aqua bags, 5 striped yellow bags. +light maroon bags contain 5 clear blue bags. +clear olive bags contain 4 posh yellow bags, 4 dotted olive bags, 2 faded chartreuse bags. +dotted indigo bags contain 1 muted crimson bag, 5 wavy purple bags, 3 dotted crimson bags, 4 dotted chartreuse bags. +muted coral bags contain 3 faded teal bags, 3 pale crimson bags, 1 posh fuchsia bag. +striped olive bags contain 1 plaid chartreuse bag, 1 dull indigo bag, 1 shiny salmon bag, 1 shiny crimson bag. +dull maroon bags contain 4 dull bronze bags, 1 mirrored brown bag, 5 wavy white bags, 5 clear teal bags. +bright aqua bags contain 2 light bronze bags, 3 bright violet bags, 5 posh fuchsia bags. +drab fuchsia bags contain 1 pale black bag. +plaid orange bags contain 2 muted orange bags. +faded aqua bags contain 4 striped orange bags, 3 striped aqua bags. +dull coral bags contain 2 dull aqua bags, 5 dim white bags, 1 striped tan bag. +muted blue bags contain 1 mirrored turquoise bag, 4 bright lavender bags, 4 dull magenta bags. +striped cyan bags contain 1 shiny tan bag, 5 dark cyan bags, 2 pale chartreuse bags, 3 muted gold bags. +muted violet bags contain 4 muted bronze bags, 5 mirrored tan bags, 5 bright yellow bags. +dull blue bags contain 3 striped fuchsia bags, 2 plaid aqua bags, 1 mirrored lime bag. +bright olive bags contain 1 pale turquoise bag, 2 vibrant gray bags, 5 posh chartreuse bags, 4 shiny lime bags. +drab red bags contain 1 light lime bag, 1 mirrored black bag, 4 pale purple bags, 2 drab purple bags. +mirrored brown bags contain 3 dull bronze bags, 3 bright lavender bags. +dotted brown bags contain 1 plaid turquoise bag, 1 dull plum bag. +shiny gray bags contain 2 pale magenta bags. +posh fuchsia bags contain 1 clear gold bag, 5 muted tomato bags, 4 muted white bags, 1 dark brown bag. +shiny green bags contain 5 posh teal bags, 2 dark brown bags, 1 faded turquoise bag. +shiny teal bags contain 1 bright coral bag, 2 plaid aqua bags, 2 vibrant yellow bags. +pale lime bags contain 5 shiny chartreuse bags, 2 striped gold bags. +bright tan bags contain 5 drab turquoise bags, 2 dotted plum bags. +wavy maroon bags contain 3 striped yellow bags, 2 plaid red bags, 4 pale teal bags. +light gray bags contain 3 wavy teal bags, 1 clear brown bag, 5 striped tan bags, 3 muted magenta bags. +dark tan bags contain 5 posh purple bags. +light lime bags contain 4 light brown bags, 3 faded violet bags, 5 bright plum bags. +bright gold bags contain 1 shiny crimson bag, 4 wavy red bags. +drab crimson bags contain 2 dotted purple bags, 4 plaid purple bags, 4 vibrant black bags. +pale maroon bags contain 1 dim gray bag. +wavy chartreuse bags contain 3 bright lavender bags. +plaid gold bags contain 5 posh lavender bags. +plaid yellow bags contain 3 shiny black bags. +dim red bags contain 2 muted indigo bags, 1 shiny aqua bag, 1 dim gray bag. +faded turquoise bags contain 2 shiny coral bags. +mirrored purple bags contain 3 muted beige bags, 4 faded blue bags. +dark black bags contain 4 bright coral bags. +dull indigo bags contain no other bags. +dark lime bags contain 1 shiny chartreuse bag, 5 drab plum bags, 2 dim yellow bags. +dim yellow bags contain 4 dotted plum bags, 2 dim coral bags, 3 dotted red bags. +shiny silver bags contain 5 drab tan bags, 1 bright cyan bag. +posh bronze bags contain 5 dotted salmon bags, 1 light aqua bag. +dull tomato bags contain 1 clear red bag, 1 dull green bag, 1 dark blue bag, 1 striped maroon bag. +bright fuchsia bags contain 1 dark cyan bag. +striped red bags contain 5 mirrored lime bags, 4 dull magenta bags, 2 vibrant yellow bags. +striped green bags contain 2 dim white bags. +wavy fuchsia bags contain 3 muted fuchsia bags, 3 drab blue bags. +posh violet bags contain 2 plaid red bags, 3 faded turquoise bags, 1 faded white bag. +vibrant maroon bags contain 1 clear fuchsia bag, 5 wavy purple bags, 2 dull gold bags. +dim olive bags contain 2 mirrored yellow bags, 2 muted magenta bags, 3 drab coral bags. +muted turquoise bags contain 1 drab white bag, 4 vibrant crimson bags, 5 dark teal bags, 1 drab bronze bag. +light white bags contain 5 vibrant gold bags, 2 faded silver bags, 1 bright beige bag. +dark beige bags contain 4 shiny white bags, 3 wavy chartreuse bags, 1 dotted red bag, 5 plaid crimson bags. +wavy gold bags contain 3 posh teal bags. +muted bronze bags contain 2 dull bronze bags, 2 muted black bags. +wavy lime bags contain 3 dim violet bags, 5 posh violet bags, 1 light white bag, 2 posh olive bags. +clear gray bags contain 2 pale purple bags. +vibrant black bags contain 5 plaid black bags. +dotted olive bags contain 4 dotted fuchsia bags. +drab gray bags contain 3 shiny chartreuse bags, 1 dim yellow bag. +shiny tomato bags contain 1 bright coral bag, 4 mirrored coral bags. +dotted coral bags contain 2 plaid cyan bags, 3 light crimson bags, 1 light white bag, 3 drab aqua bags. +drab blue bags contain 3 bright coral bags, 3 dim coral bags. +mirrored blue bags contain 5 dotted brown bags, 4 clear chartreuse bags, 2 bright gold bags, 3 striped lavender bags. +muted aqua bags contain 2 bright turquoise bags. +bright yellow bags contain no other bags. \ No newline at end of file diff --git a/day07/packBag.spec.ts b/day07/packBag.spec.ts deleted file mode 100644 index 62ec841..0000000 --- a/day07/packBag.spec.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { loadString } from '../lib/loader' -import { parseRules } from './parseRules' -/** - * These rules specify the required contents for 9 bag types. In this example, - * every faded blue bag is empty, every vibrant plum bag contains 11 bags - * (5 faded blue and 6 dotted black), and so on. - */ -const sample = `light red bags contain 1 bright white bag, 2 muted yellow bags. -dark orange bags contain 3 bright white bags, 4 muted yellow bags. -bright white bags contain 1 shiny gold bag. -muted yellow bags contain 2 shiny gold bags, 9 faded blue bags. -shiny gold bags contain 1 dark olive bag, 2 vibrant plum bags. -dark olive bags contain 3 faded blue bags, 4 dotted black bags. -vibrant plum bags contain 5 faded blue bags, 6 dotted black bags. -faded blue bags contain no other bags. -dotted black bags contain no other bags.` - -describe('packBag', () => { - /** - * You have a shiny gold bag. If you wanted to carry it in at least one - * other bag, how many different bag colors would be valid for the outermost - * bag? (In other words: how many colors can, eventually, contain at least - * one shiny gold bag?) - * - * In the above rules, the following options would be available to you: - * - * A bright white bag, which can hold your shiny gold bag directly. - * A muted yellow bag, which can hold your shiny gold bag directly, plus some other bags. - * A dark orange bag, which can hold bright white and muted yellow bags, either of which could then hold your shiny gold bag. - * A light red bag, which can hold bright white and muted yellow bags, either of which could then hold your shiny gold bag. - * So, in this example, the number of bag colors that can eventually contain at least one shiny gold bag is 4. - */ - it('should pack a shiny gold bag', () => { - const rules = parseRules(loadString(sample)) - const packager = packBag(rules) - const colors = Object.keys(packager('shiny gold')) - expect(colors).toEqual([ - 'bright white', - 'muted yellow', - 'dark orange', - 'light red', - ]) - }) -}) diff --git a/day07/packBag.ts b/day07/packBag.ts new file mode 100644 index 0000000..3b17655 --- /dev/null +++ b/day07/packBag.ts @@ -0,0 +1,22 @@ +import { Bag, Bags } from './parseRules' + +const unique = (value: unknown, index: number, arr: unknown[]) => + arr.indexOf(value) === index + +const findContainingBag = (bags: Bags) => (bag: Bag): string[] => { + // Find the bags that can contain this bag + const parents = Object.values(bags).filter( + ({ children }) => children?.[bag.color] !== undefined, + ) + if (parents.length === 0) return [bag.color] + return [ + ...parents.map(({ color }) => color), + ...parents.map(findContainingBag(bags)).flat(), + ].filter(unique) +} + +/** + * Determine which bags are needed to package a bag with the given color. + */ +export const packBag = (bags: Bags) => (color: string): string[] => + findContainingBag(bags)(bags[color]).flat() diff --git a/day07/parseRules.ts b/day07/parseRules.ts index ce565e0..266df53 100644 --- a/day07/parseRules.ts +++ b/day07/parseRules.ts @@ -3,32 +3,34 @@ export type Bag = { children?: Record } +export type Bags = Record + const ruleDef = /^(?[a-z ]+) bags contain (?.+)/ const contentsRuleDef = /^(?[0-9]+) (?[a-z ]+) bags?/ export const parseRuleLine = (rule: string): Bag | undefined => { const match = ruleDef.exec(rule) - if (match === null) return + if (match?.groups === undefined) return const children = match.groups.contents .split(',') .map((s) => s.trim()) .filter((s) => s !== undefined) - .filter((s) => !/no other bags/.test(s)) + .filter((s) => !s.includes('no other bags')) .map((s) => contentsRuleDef.exec(s)) - .reduce( - (children, child) => ({ + .reduce((children, child) => { + if (child?.groups === undefined) return children + return { ...children, [child?.groups.color]: parseInt(child?.groups.amount, 10), - }), - {}, - ) + } + }, {}) return { - color: match.groups.color as string, + color: match.groups.color, children: Object.keys(children).length === 0 ? undefined : children, } } -export const parseRules = (rules: string[]): Record => +export const parseRules = (rules: string[]): Bags => rules.reduce((bags, rule) => { const bag = parseRuleLine(rule) if (bag === undefined) return bags diff --git a/day07/solution.spec.ts b/day07/solution.spec.ts new file mode 100644 index 0000000..8303767 --- /dev/null +++ b/day07/solution.spec.ts @@ -0,0 +1,41 @@ +import { loader, loadString } from '../lib/loader' +import { packBag } from './packBag' +import { parseRules } from './parseRules' + +const load = loader(7) +const input = load('input') +/** + * These rules specify the required contents for 9 bag types. In this example, + * every faded blue bag is empty, every vibrant plum bag contains 11 bags + * (5 faded blue and 6 dotted black), and so on. + */ +const sample = `light red bags contain 1 bright white bag, 2 muted yellow bags. +dark orange bags contain 3 bright white bags, 4 muted yellow bags. +bright white bags contain 1 shiny gold bag. +muted yellow bags contain 2 shiny gold bags, 9 faded blue bags. +shiny gold bags contain 1 dark olive bag, 2 vibrant plum bags. +dark olive bags contain 3 faded blue bags, 4 dotted black bags. +vibrant plum bags contain 5 faded blue bags, 6 dotted black bags. +faded blue bags contain no other bags. +dotted black bags contain no other bags.` + +describe('Day 7: Handy Haversacks', () => { + describe('Part 1', () => { + it('should solve the sample', () => { + const rules = parseRules(loadString(sample)) + const packager = packBag(rules) + const bags = packager('shiny gold') + expect(bags).toHaveLength(4) + expect(bags.includes('bright white')).toEqual(true) + expect(bags.includes('muted yellow')).toEqual(true) + expect(bags.includes('dark orange')).toEqual(true) + expect(bags.includes('light red')).toEqual(true) + }) + it('should solve', () => { + const rules = parseRules(input) + const packager = packBag(rules) + const bags = packager('shiny gold') + expect(bags).toHaveLength(378) + }) + }) +}) From a9e2cc1f8cf400ad820ca980a391037a39b57e8b Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Mon, 7 Dec 2020 09:31:57 +0100 Subject: [PATCH 30/60] feat(day07): part 2 --- day07/countBags.ts | 22 ++++++++++++++++++++++ day07/solution.spec.ts | 29 +++++++++++++++++++++++++++-- 2 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 day07/countBags.ts diff --git a/day07/countBags.ts b/day07/countBags.ts new file mode 100644 index 0000000..5a70bd8 --- /dev/null +++ b/day07/countBags.ts @@ -0,0 +1,22 @@ +import { Bag, Bags } from './parseRules' + +const countChildren = (bags: Bags) => (bag: Bag): number => { + // Bag has no children, so no more bags are needed + if (bag.children === undefined) return 0 + + return Object.entries(bag.children).reduce( + (total, [color, count]) => + total + + // Count all the child bags + count + + // and add the amount of bags they contain multiplied by the number of bags + count * countChildren(bags)(bags[color]), + 0, + ) +} + +/** + * Count how many bags are need to transport the given bag + */ +export const countBags = (bags: Bags) => (color: string): number => + countChildren(bags)(bags[color]) diff --git a/day07/solution.spec.ts b/day07/solution.spec.ts index 8303767..2c52e7d 100644 --- a/day07/solution.spec.ts +++ b/day07/solution.spec.ts @@ -1,4 +1,5 @@ import { loader, loadString } from '../lib/loader' +import { countBags } from './countBags' import { packBag } from './packBag' import { parseRules } from './parseRules' @@ -19,6 +20,14 @@ vibrant plum bags contain 5 faded blue bags, 6 dotted black bags. faded blue bags contain no other bags. dotted black bags contain no other bags.` +const sample2 = `shiny gold bags contain 2 dark red bags. +dark red bags contain 2 dark orange bags. +dark orange bags contain 2 dark yellow bags. +dark yellow bags contain 2 dark green bags. +dark green bags contain 2 dark blue bags. +dark blue bags contain 2 dark violet bags. +dark violet bags contain no other bags.` + describe('Day 7: Handy Haversacks', () => { describe('Part 1', () => { it('should solve the sample', () => { @@ -34,8 +43,24 @@ describe('Day 7: Handy Haversacks', () => { it('should solve', () => { const rules = parseRules(input) const packager = packBag(rules) - const bags = packager('shiny gold') - expect(bags).toHaveLength(378) + expect(packager('shiny gold')).toHaveLength(378) + }) + }) + describe('Part 2', () => { + it('should solve the sample', () => { + const rules = parseRules(loadString(sample)) + const counter = countBags(rules) + expect(counter('shiny gold')).toEqual(32) + }) + it('should solve the second sample', () => { + const rules = parseRules(loadString(sample2)) + const counter = countBags(rules) + expect(counter('shiny gold')).toEqual(126) + }) + it('should solve', () => { + const rules = parseRules(input) + const counter = countBags(rules) + expect(counter('shiny gold')).toEqual(27526) }) }) }) From 13f0ae0228d5c5e24a129b0580c890f01d26b2bf Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Mon, 7 Dec 2020 09:34:44 +0100 Subject: [PATCH 31/60] docs: improve docs --- day07/packBag.ts | 4 ++++ day07/parseRules.ts | 10 +++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/day07/packBag.ts b/day07/packBag.ts index 3b17655..6e21aaa 100644 --- a/day07/packBag.ts +++ b/day07/packBag.ts @@ -8,9 +8,13 @@ const findContainingBag = (bags: Bags) => (bag: Bag): string[] => { const parents = Object.values(bags).filter( ({ children }) => children?.[bag.color] !== undefined, ) + // No one contains this bag, so it's just that if (parents.length === 0) return [bag.color] + return [ + // Return the parents ...parents.map(({ color }) => color), + // and the parents of the parents ...parents.map(findContainingBag(bags)).flat(), ].filter(unique) } diff --git a/day07/parseRules.ts b/day07/parseRules.ts index 266df53..238b9c6 100644 --- a/day07/parseRules.ts +++ b/day07/parseRules.ts @@ -8,14 +8,19 @@ export type Bags = Record const ruleDef = /^(?[a-z ]+) bags contain (?.+)/ const contentsRuleDef = /^(?[0-9]+) (?[a-z ]+) bags?/ +/** + * Parses a single rule line + */ export const parseRuleLine = (rule: string): Bag | undefined => { const match = ruleDef.exec(rule) if (match?.groups === undefined) return const children = match.groups.contents + // children counts are separated by comma .split(',') .map((s) => s.trim()) - .filter((s) => s !== undefined) + // handle special case of no children .filter((s) => !s.includes('no other bags')) + // parse the child rule .map((s) => contentsRuleDef.exec(s)) .reduce((children, child) => { if (child?.groups === undefined) return children @@ -30,6 +35,9 @@ export const parseRuleLine = (rule: string): Bag | undefined => { } } +/** + * Parse the bag in a record with the color as key + */ export const parseRules = (rules: string[]): Bags => rules.reduce((bags, rule) => { const bag = parseRuleLine(rule) From dad6eb8ce18c80d9a5d6c904401765f15be2b7f4 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Tue, 8 Dec 2020 09:48:38 +0100 Subject: [PATCH 32/60] feat(day08): part 1 --- day08/handheld.ts | 32 +++ day08/input.txt | 613 +++++++++++++++++++++++++++++++++++++++++ day08/solution.spec.ts | 27 ++ 3 files changed, 672 insertions(+) create mode 100644 day08/handheld.ts create mode 100644 day08/input.txt create mode 100644 day08/solution.spec.ts diff --git a/day08/handheld.ts b/day08/handheld.ts new file mode 100644 index 0000000..7aaf0cc --- /dev/null +++ b/day08/handheld.ts @@ -0,0 +1,32 @@ +export const boot = (bootCode: string[]): number => { + const bootInstructions = bootCode + .map((s) => s.split(' ')) + .map(([i, a]) => [i, parseInt(a, 10)]) + let acc = 0 + let ptr = 0 + const lineExecutions = {} as Record + let ins, arg + do { + if (lineExecutions[ptr] !== undefined) return acc + lineExecutions[ptr] = true + ins = bootInstructions[ptr]?.[0] + arg = bootInstructions[ptr]?.[1] + if (ins === undefined) return acc // normal termination + switch (ins) { + case 'nop': + ptr++ + break + case 'acc': + acc += arg as number + ptr++ + break + case 'jmp': + ptr += arg as number + break + default: + console.warn(`Unknown instruction: ${ins} ${arg}`) + ptr++ + } + } while (ins !== undefined) + return acc +} diff --git a/day08/input.txt b/day08/input.txt new file mode 100644 index 0000000..37da8aa --- /dev/null +++ b/day08/input.txt @@ -0,0 +1,613 @@ +nop +456 +nop +38 +acc +9 +jmp +153 +acc +15 +nop +560 +jmp +452 +acc +26 +acc +42 +jmp +376 +acc -5 +acc +12 +acc -5 +jmp +15 +jmp +1 +acc -9 +jmp +533 +acc +19 +acc +33 +acc +34 +jmp -6 +nop +404 +nop +140 +acc +0 +jmp +123 +acc +45 +acc +0 +jmp +496 +jmp +487 +acc +9 +acc +34 +jmp +484 +acc +0 +acc -14 +jmp +466 +acc +40 +acc +6 +acc +30 +jmp +444 +nop +386 +jmp +215 +acc +43 +acc +5 +nop -4 +jmp +535 +jmp -13 +acc +3 +acc +7 +acc +49 +acc -1 +jmp +245 +acc +9 +acc +31 +nop +142 +jmp +554 +acc +3 +jmp +493 +nop +399 +jmp +232 +acc -16 +acc +33 +jmp +410 +acc +33 +acc +5 +acc -17 +jmp +272 +acc -3 +acc +37 +jmp +181 +jmp -12 +nop +344 +acc +5 +acc -16 +jmp +290 +nop +530 +acc +15 +acc +3 +jmp +343 +acc +2 +acc +19 +jmp +298 +acc +43 +acc +25 +acc -19 +jmp +439 +acc +43 +acc +45 +acc +20 +jmp +355 +acc +13 +acc +24 +acc -15 +nop +396 +jmp +215 +acc -7 +acc +17 +jmp +441 +acc -8 +acc -19 +jmp +505 +jmp +282 +acc -17 +acc -8 +acc +20 +jmp +359 +acc +26 +acc +14 +acc +47 +acc +3 +jmp +298 +acc +31 +nop +205 +acc +0 +acc +7 +jmp +389 +acc -5 +acc +47 +jmp +94 +acc -13 +jmp +358 +acc -13 +jmp +134 +acc +8 +acc -19 +jmp +312 +acc +43 +acc +17 +jmp +97 +jmp +48 +nop +253 +acc +48 +acc -7 +acc -2 +jmp +23 +acc +26 +acc +14 +acc -14 +acc +17 +jmp +18 +acc +14 +acc +8 +jmp +341 +acc +35 +jmp +227 +acc +15 +acc -7 +jmp -95 +acc -19 +jmp -59 +jmp -31 +acc -6 +acc -4 +acc +24 +jmp +84 +acc -15 +jmp +82 +nop +74 +acc +8 +acc +9 +acc +13 +jmp +194 +jmp +376 +acc +34 +nop -16 +jmp -90 +acc +4 +acc +43 +nop +215 +jmp -147 +acc +0 +acc +11 +acc -15 +acc +23 +jmp +130 +acc +40 +jmp +106 +acc -4 +acc -18 +acc +18 +nop +329 +jmp +230 +acc +19 +nop +172 +acc +43 +jmp +304 +acc +44 +nop +213 +nop +195 +acc +6 +jmp -79 +acc +41 +acc -11 +acc +18 +acc -9 +jmp -25 +acc +27 +acc -6 +acc +31 +jmp -56 +acc +5 +acc +12 +acc +32 +acc +34 +jmp -189 +acc +32 +acc +5 +acc -16 +jmp +301 +nop +108 +nop -108 +jmp -141 +acc -12 +jmp +273 +acc +3 +jmp +140 +acc +7 +acc -11 +acc -17 +nop +194 +jmp -122 +acc -14 +nop +186 +acc +24 +jmp +277 +nop +341 +acc +18 +jmp -64 +acc +45 +acc +42 +jmp +52 +acc +39 +nop +91 +nop -8 +jmp +217 +acc +44 +acc +15 +jmp +72 +acc +24 +jmp -231 +acc -16 +nop +55 +nop +262 +acc +40 +jmp +234 +jmp -14 +acc +31 +nop -177 +acc +40 +jmp +343 +acc -8 +jmp -169 +acc +30 +acc +12 +acc -11 +jmp +41 +acc +9 +acc -9 +jmp +65 +acc +38 +acc +14 +jmp +335 +acc -19 +acc +38 +acc +16 +acc -11 +jmp +230 +jmp -71 +acc +48 +acc -13 +nop -255 +jmp +1 +jmp -220 +acc +2 +jmp +157 +jmp -105 +acc -16 +acc -5 +jmp -196 +acc +30 +jmp +139 +jmp +83 +acc -3 +acc -12 +jmp +254 +jmp -60 +acc +33 +jmp -37 +acc +17 +acc -14 +jmp +93 +nop +178 +acc +38 +acc +47 +jmp -89 +jmp +271 +acc +43 +acc +32 +jmp -240 +acc +26 +acc +32 +acc +30 +nop +284 +jmp +169 +acc -7 +acc +37 +jmp +102 +acc +4 +jmp +86 +jmp -123 +acc +0 +acc -14 +acc +18 +jmp +1 +jmp -5 +jmp -36 +jmp +148 +acc -17 +acc -14 +acc +28 +acc +15 +jmp +79 +jmp -289 +acc +42 +acc -5 +acc +13 +jmp +240 +acc -10 +acc -18 +acc -16 +jmp +103 +acc +21 +jmp +32 +nop +118 +acc +22 +acc -16 +acc +15 +jmp -186 +acc -2 +acc -14 +acc +22 +acc +16 +jmp +73 +acc -6 +jmp -225 +acc -18 +nop +113 +acc +50 +acc -6 +jmp +181 +acc +41 +jmp +1 +nop +92 +acc +23 +jmp +190 +acc +39 +acc +0 +acc +33 +jmp +111 +nop -63 +nop -81 +acc +9 +acc +35 +jmp +50 +acc +11 +jmp -295 +nop +230 +acc +34 +acc +12 +acc +47 +jmp +126 +acc +0 +nop -1 +acc +19 +acc -16 +jmp -360 +acc +29 +acc -2 +jmp -110 +acc +2 +acc +50 +jmp -36 +jmp -107 +jmp +178 +acc -11 +jmp +181 +nop +115 +nop +186 +jmp +95 +jmp +1 +nop +148 +acc +2 +acc +49 +jmp +173 +acc +38 +jmp +178 +acc +28 +acc +6 +acc +15 +jmp +110 +acc +49 +nop +100 +jmp +57 +acc +45 +nop +65 +acc +43 +acc +12 +jmp -272 +jmp -260 +nop +100 +jmp -224 +jmp +142 +jmp +52 +jmp -34 +jmp -110 +acc +35 +nop -112 +jmp +16 +jmp -18 +jmp -157 +jmp +81 +acc +1 +jmp -107 +acc +16 +acc +23 +jmp -255 +acc +22 +jmp +42 +nop +168 +acc +41 +jmp -311 +jmp -163 +jmp +118 +nop +4 +acc +18 +jmp +54 +jmp -414 +nop -181 +acc +10 +acc +23 +jmp -321 +nop -322 +acc -9 +jmp +101 +nop -7 +acc +35 +acc +46 +jmp -312 +nop +64 +nop -386 +jmp -280 +acc +16 +jmp -156 +acc +13 +nop -131 +jmp +1 +jmp -416 +jmp +15 +jmp -94 +jmp -330 +nop +93 +nop -205 +acc +48 +jmp -19 +jmp -70 +nop +21 +acc -5 +acc +19 +jmp +62 +acc +22 +jmp -448 +jmp -77 +acc +26 +acc -2 +jmp +70 +acc -2 +acc +21 +jmp -195 +nop -114 +jmp +107 +acc +37 +acc +6 +jmp -436 +acc +48 +jmp +96 +jmp -121 +acc +0 +jmp -74 +jmp +1 +acc +27 +acc +2 +jmp -279 +acc +7 +acc +0 +jmp +1 +jmp -413 +acc +6 +jmp -180 +acc +18 +acc +10 +jmp -437 +jmp -338 +nop -456 +jmp -463 +acc +1 +nop -54 +jmp -168 +acc +27 +jmp -479 +acc +42 +jmp -408 +jmp +85 +acc -16 +acc +24 +jmp -391 +jmp -206 +nop +8 +jmp +1 +acc +38 +nop -473 +jmp -94 +acc +10 +acc -14 +jmp -425 +acc +17 +nop -208 +acc +39 +jmp -265 +acc +3 +jmp -284 +acc +19 +acc +5 +nop -111 +acc +22 +jmp -309 +acc +12 +acc +39 +jmp -151 +acc +33 +acc -14 +jmp -450 +acc +16 +nop +50 +jmp -188 +acc -13 +acc +15 +acc +4 +jmp -484 +acc +27 +jmp -98 +acc +34 +jmp -120 +jmp -537 +acc +43 +acc -8 +acc -6 +jmp -405 +acc -8 +nop -179 +acc -11 +jmp -264 +acc +24 +jmp -280 +acc -6 +acc +1 +jmp -353 +acc -18 +jmp -58 +acc +1 +acc -7 +acc -2 +acc +44 +jmp -115 +nop -328 +acc +27 +acc +2 +jmp +20 +acc +14 +acc +34 +jmp -460 +nop -445 +acc -9 +acc +24 +acc -11 +jmp -72 +jmp -434 +jmp -370 +acc +35 +acc +43 +acc +45 +acc +44 +jmp -287 +jmp -546 +nop -474 +acc -6 +jmp -357 +nop -163 +nop -218 +nop -342 +jmp -570 +acc +44 +acc +4 +acc +35 +acc +6 +jmp -541 +jmp -274 +acc +48 +acc -18 +jmp -171 +acc -13 +acc -14 +acc +25 +acc +26 +jmp +1 \ No newline at end of file diff --git a/day08/solution.spec.ts b/day08/solution.spec.ts new file mode 100644 index 0000000..a951b0c --- /dev/null +++ b/day08/solution.spec.ts @@ -0,0 +1,27 @@ +import { loader, loadString } from '../lib/loader' +import { boot } from './handheld' + +const load = loader(8) +const input = load('input') +const sample = loadString(`nop +0 +acc +1 +jmp +4 +acc +3 +jmp -3 +acc -99 +acc +1 +jmp -4 +acc +6`) + +describe('Day 8: Handheld Halting', () => { + describe('Part 1', () => { + it('should solve the sample', () => { + const handheldBootCode = boot(sample) + expect(handheldBootCode).toEqual(5) + }) + it('should solve the', () => { + const handheldBootCode = boot(input) + expect(handheldBootCode).toEqual(1087) + }) + }) +}) From 4cae087e9754912f846fe70bc9c23a009538e590 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Tue, 8 Dec 2020 10:27:59 +0100 Subject: [PATCH 33/60] feat(day08): part 2 --- day08/handheld.ts | 8 ++++---- day08/solution.spec.ts | 43 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/day08/handheld.ts b/day08/handheld.ts index 7aaf0cc..5eb19dd 100644 --- a/day08/handheld.ts +++ b/day08/handheld.ts @@ -1,4 +1,4 @@ -export const boot = (bootCode: string[]): number => { +export const boot = (bootCode: string[]): [number, number] => { const bootInstructions = bootCode .map((s) => s.split(' ')) .map(([i, a]) => [i, parseInt(a, 10)]) @@ -7,11 +7,11 @@ export const boot = (bootCode: string[]): number => { const lineExecutions = {} as Record let ins, arg do { - if (lineExecutions[ptr] !== undefined) return acc + if (lineExecutions[ptr] !== undefined) return [-1, acc] lineExecutions[ptr] = true ins = bootInstructions[ptr]?.[0] arg = bootInstructions[ptr]?.[1] - if (ins === undefined) return acc // normal termination + if (ins === undefined) return [0, acc] // normal termination switch (ins) { case 'nop': ptr++ @@ -28,5 +28,5 @@ export const boot = (bootCode: string[]): number => { ptr++ } } while (ins !== undefined) - return acc + return [-1, acc] } diff --git a/day08/solution.spec.ts b/day08/solution.spec.ts index a951b0c..cfbca12 100644 --- a/day08/solution.spec.ts +++ b/day08/solution.spec.ts @@ -12,16 +12,53 @@ acc -99 acc +1 jmp -4 acc +6`) +const sample2 = loadString(`nop +0 +acc +1 +jmp +4 +acc +3 +jmp -3 +acc -99 +acc +1 +nop -4 +acc +6`) describe('Day 8: Handheld Halting', () => { describe('Part 1', () => { it('should solve the sample', () => { const handheldBootCode = boot(sample) - expect(handheldBootCode).toEqual(5) + expect(handheldBootCode).toEqual([-1, 5]) }) - it('should solve the', () => { + it('should solve', () => { const handheldBootCode = boot(input) - expect(handheldBootCode).toEqual(1087) + expect(handheldBootCode).toEqual([-1, 1087]) + }) + }) + describe('Part 2', () => { + it('should solve the sample', () => { + const handheldBootCode = boot(sample2) + expect(handheldBootCode).toEqual([0, 8]) + }) + it('should solve', () => { + // Find all the jumps + const jmps = input.reduce((jmps, i, k) => { + if (i.startsWith('jmp')) return [...jmps, k] + return jmps + }, [] as number[]) + + // Change one jpm instruction after another and run the program + expect( + jmps.reduce( + (exit, line) => { + if (exit[0] === 0) return exit + return boot([ + ...input.slice(0, line), + input[line].replace('jmp', 'nop'), + ...input.slice(line + 1), + ]) + }, + [-1, 0], + ), + ).toEqual([0, 780]) }) }) }) From a97bc88879a02f5c7b9f5654cb265e4f2e4ee82b Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Tue, 8 Dec 2020 10:30:11 +0100 Subject: [PATCH 34/60] refactor: improve readability --- day08/handheld.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/day08/handheld.ts b/day08/handheld.ts index 5eb19dd..a4a1c85 100644 --- a/day08/handheld.ts +++ b/day08/handheld.ts @@ -1,4 +1,10 @@ +/** + * Run the boot program with loop protection + * and return an exit code (-1 on error) and + * the value of the accumulator. + */ export const boot = (bootCode: string[]): [number, number] => { + // Parse the instructions const bootInstructions = bootCode .map((s) => s.split(' ')) .map(([i, a]) => [i, parseInt(a, 10)]) @@ -8,7 +14,7 @@ export const boot = (bootCode: string[]): [number, number] => { let ins, arg do { if (lineExecutions[ptr] !== undefined) return [-1, acc] - lineExecutions[ptr] = true + lineExecutions[ptr] = true // Record line executions ins = bootInstructions[ptr]?.[0] arg = bootInstructions[ptr]?.[1] if (ins === undefined) return [0, acc] // normal termination @@ -25,8 +31,8 @@ export const boot = (bootCode: string[]): [number, number] => { break default: console.warn(`Unknown instruction: ${ins} ${arg}`) - ptr++ + return [-2, acc] } } while (ins !== undefined) - return [-1, acc] + return [-3, acc] } From fac40ec0c1b76fbd03594ba9b9c5110baf7f4f05 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Wed, 9 Dec 2020 07:59:19 +0100 Subject: [PATCH 35/60] feat(day09): part 1 --- day09/findInvalidNumber.ts | 14 + day09/input.txt | 1000 ++++++++++++++++++++++++++++++++++++ day09/solution.spec.ts | 35 ++ 3 files changed, 1049 insertions(+) create mode 100644 day09/findInvalidNumber.ts create mode 100644 day09/input.txt create mode 100644 day09/solution.spec.ts diff --git a/day09/findInvalidNumber.ts b/day09/findInvalidNumber.ts new file mode 100644 index 0000000..0809051 --- /dev/null +++ b/day09/findInvalidNumber.ts @@ -0,0 +1,14 @@ +import { uniqueCombinations } from '../lib/uniqueCombinations' + +const sum = (numbers: number[]) => numbers.reduce((total, n) => total + n, 0) + +export const findInvalidNumber = (preambleLength: number) => ( + input: number[], +): number | undefined => { + const c = uniqueCombinations(2) + return input.find((n, k, arr) => { + if (k < preambleLength) return false + const preamble = c(arr.slice(k - preambleLength, k)) + return preamble.map(sum).find((s) => s === n) === undefined + }) +} diff --git a/day09/input.txt b/day09/input.txt new file mode 100644 index 0000000..92ed3da --- /dev/null +++ b/day09/input.txt @@ -0,0 +1,1000 @@ +14 +9 +43 +18 +13 +24 +3 +38 +33 +8 +41 +4 +32 +15 +31 +44 +17 +34 +21 +10 +50 +37 +2 +23 +6 +47 +5 +9 +11 +16 +12 +18 +7 +13 +26 +14 +19 +8 +20 +15 +29 +58 +17 +22 +21 +24 +25 +10 +27 +31 +33 +23 +28 +30 +34 +32 +35 +38 +49 +18 +26 +36 +37 +47 +39 +56 +40 +42 +43 +41 +44 +45 +46 +48 +50 +51 +53 +79 +73 +69 +117 +54 +55 +90 +57 +62 +75 +114 +85 +94 +110 +81 +98 +153 +86 +89 +204 +96 +101 +103 +104 +152 +169 +124 +135 +109 +143 +171 +119 +132 +137 +207 +166 +167 +184 +185 +170 +175 +182 +187 +190 +197 +233 +204 +212 +244 +299 +228 +339 +241 +246 +269 +415 +319 +298 +349 +337 +333 +444 +357 +345 +362 +365 +562 +377 +387 +401 +416 +541 +469 +472 +474 +647 +591 +487 +515 +567 +617 +686 +1158 +793 +670 +678 +702 +864 +710 +856 +781 +817 +764 +1251 +1214 +885 +941 +943 +946 +961 +1002 +1082 +1456 +1269 +1184 +2104 +1364 +1348 +2032 +1372 +1742 +1412 +1474 +1792 +1545 +1649 +2305 +2358 +1826 +2725 +1828 +3282 +2043 +1907 +1963 +2910 +2266 +2814 +2453 +2532 +2712 +2957 +2720 +2784 +3903 +3019 +3123 +4131 +4006 +3789 +3871 +3654 +4811 +3735 +3791 +5866 +4309 +4416 +4439 +4229 +4719 +5576 +5237 +8578 +5244 +6447 +5504 +8510 +7445 +9570 +7920 +6777 +8725 +7389 +12460 +7606 +13305 +15899 +9992 +14957 +8748 +12843 +8855 +14092 +8948 +9956 +10741 +10481 +10748 +11951 +25705 +12281 +26647 +14697 +14166 +25855 +19473 +16244 +24048 +16354 +16461 +36446 +22914 +17603 +20704 +28195 +17803 +18811 +29429 +18904 +20437 +41380 +24914 +22699 +46409 +26447 +26978 +57624 +33639 +33847 +32598 +41141 +39160 +33957 +70570 +34064 +35406 +36414 +80323 +50894 +36614 +36707 +48333 +63592 +39341 +43136 +66445 +59313 +49146 +92952 +99043 +99227 +73028 +66237 +69012 +66555 +70771 +68021 +107362 +69470 +70478 +71820 +73121 +91469 +76048 +73321 +107478 +108353 +122905 +142591 +92282 +108459 +115383 +125194 +142791 +137491 +135567 +132792 +199928 +134576 +163289 +138499 +334504 +205037 +197014 +142298 +144941 +267785 +149369 +271642 +165603 +237223 +200635 +207665 +227849 +200741 +352606 +259770 +257986 +431074 +310544 +267368 +283440 +291667 +273075 +304102 +402068 +287239 +294310 +307901 +314972 +345682 +350004 +350110 +437245 +612376 +401376 +408300 +435514 +636046 +695539 +675143 +547009 +525354 +540443 +684816 +550808 +1076162 +560314 +567385 +933654 +581549 +595140 +602211 +664976 +968614 +695686 +700114 +751486 +809676 +1044346 +926730 +1318871 +960868 +1065797 +1091251 +1225951 +1646557 +2157048 +1121992 +1153019 +1519422 +1127699 +1155454 +1277235 +1176689 +1183760 +1197351 +1267187 +1360662 +1626844 +1395800 +1712354 +2213243 +1736406 +1887598 +1992527 +2088567 +2026665 +2187789 +2218950 +2277446 +2329708 +2249691 +2280718 +2283153 +2304388 +2311459 +3516878 +2453924 +2544422 +5605445 +2464538 +3353189 +3949649 +3132206 +3108154 +5319995 +5686055 +3914263 +3880125 +5220773 +4115232 +4214454 +4437480 +4468641 +4554079 +4563871 +4530409 +5807113 +4587541 +4615847 +4998346 +6378801 +10826218 +5008960 +5596744 +7018617 +6485395 +6240360 +6988279 +7022417 +9022720 +8530110 +7794388 +7995357 +8329686 +8552712 +8906121 +13145957 +8999050 +12016963 +12615361 +9528755 +15015505 +14537715 +10007306 +13258977 +10605704 +12027577 +13504012 +11837104 +15518389 +13228639 +14782667 +27928624 +14816805 +15789745 +16525467 +16325043 +16548069 +21016013 +21844410 +17905171 +23751661 +20134459 +26930747 +19536061 +20613010 +22034883 +22442808 +31843432 +25096081 +29553682 +36661215 +25065743 +26619771 +29018384 +36817550 +38968275 +30606550 +41591210 +32114788 +25918798 +36084130 +34453240 +37441232 +38039630 +47100626 +63748297 +57537297 +40149071 +43055818 +42647893 +44477691 +47508551 +54114465 +61883293 +50984541 +56525348 +51685514 +52538569 +54937182 +58033586 +69574825 +93966580 +60372038 +103019931 +62002928 +70537370 +95576927 +75480862 +117862762 +82796964 +178500793 +112987469 +123689290 +85703711 +107880589 +174870762 +103523110 +124512007 +102670055 +120036514 +125474552 +161053517 +107475751 +112970768 +169478679 +122374966 +130909408 +211178263 +132540298 +137483790 +183361451 +278938378 +198674479 +215640823 +293167969 +416857259 +218244009 +188373766 +193179462 +249986559 +206193165 +220446519 +227182062 +210145806 +294953231 +229850717 +235345734 +244959541 +243880176 +382035930 +319283174 +367886032 +270024088 +315901749 +320845241 +371735217 +468230568 +592181736 +381553228 +544939790 +418224483 +394566931 +436043882 +399372627 +416338971 +426639684 +439996523 +474810258 +611886647 +465196451 +473730893 +480305275 +743754981 +710468680 +1175665131 +585925837 +590869329 +636746990 +796207024 +760841764 +891955376 +776120159 +780925855 +793939558 +810905902 +826012311 +1026913211 +835416509 +815711598 +842978655 +906944959 +905192974 +938927344 +1077083098 +945501726 +954036168 +1066231112 +1845872303 +1176795166 +1970734724 +1222672827 +1387076353 +1761213324 +1536961923 +1726427581 +2016010442 +1574865413 +1591831757 +1739441284 +1720904572 +1754638942 +2768626923 +3420737716 +1844120318 +1748171629 +1812137933 +1850694700 +1884429070 +1899537894 +2011732838 +2020267280 +3595132693 +3860130760 +3199214286 +2609749180 +3862427538 +3141715295 +3111827336 +5215224728 +3425560113 +3166697170 +3295769985 +3312736329 +3460345856 +3469076201 +3502810571 +3560309562 +3592291947 +3598866329 +7027362661 +5049908986 +4494178250 +3896161908 +4509287074 +4032000118 +5523077851 +7020655418 +6963156427 +5721576516 +5751464475 +6424563665 +6253542631 +6278524506 +8718035299 +6635773371 +9753576634 +10572986837 +6905028276 +6929422057 +7488453855 +7095102518 +7152601509 +7191158276 +14803485620 +14583556373 +7928162026 +10859318335 +13788374880 +8541287192 +9555077969 +11244654367 +12005007106 +14417875912 +11473040991 +12029988981 +13060337036 +12532067137 +12914297877 +13540801647 +13730875889 +13834450333 +14000130794 +14024524575 +14082023566 +20883477398 +26072868784 +14343759785 +15119320302 +19933169132 +22959163104 +16469449218 +29488247101 +20799732336 +18096365161 +21028118960 +23274643348 +55561115885 +24533378027 +26894787369 +24562056118 +27540932441 +25446365014 +69561246679 +27271677536 +27565326222 +27834581127 +48424409839 +28106548141 +28425783351 +42629743188 +44991152530 +35143492121 +50169430717 +40732901468 +34565814379 +37497568178 +38896097497 +39124484121 +51456843487 +44302762308 +51700426699 +49095434145 +77710363158 +50008421132 +51833733654 +54837003758 +56532331492 +55106258663 +55378225677 +55399907349 +63569275472 +62672362520 +80134644651 +93398196453 +73690298500 +76622052299 +69709306500 +72063382557 +73461911876 +106856750836 +76393665675 +115746536420 +90958217775 +119204694012 +105627765637 +99103855277 +148235200211 +135512870328 +104845424890 +110778133026 +109943262421 +195803642665 +110484484340 +118969182821 +216800013257 +209588339617 +132381669020 +141772689057 +195591235120 +267867025222 +187809918977 +303556455397 +145525294433 +149855577551 +167351883450 +181239090565 +201442702115 +190062073052 +224832459649 +204731620914 +260741871878 +215623557916 +214788687311 +306288127005 +274154358077 +355161802427 +400322856034 +252257173397 +313620759585 +277906963453 +282237246571 +356561376368 +506416953919 +295380871984 +442319246449 +312877177883 +317207461001 +326764384998 +604671348451 +348590974015 +385970711479 +391504775167 +569950489738 +419520308225 +883571249323 +430412245227 +467045860708 +488943045388 +526411531474 +708712236168 +530164136850 +640385144583 +577618118555 +591527723038 +612588332985 +595114424454 +769083631447 +747619706228 +608258049867 +908735184039 +630084638884 +643971845999 +712735096477 +897458105935 +734561685494 +777475486646 +1027778358092 +1197655281556 +849932553452 +919355290615 +1021939968265 +955988906096 +1019107182238 +1260973216968 +1107782255405 +1284356990582 +1169145841593 +1480017192336 +1221612361922 +1203372474321 +1225199063338 +1238342688751 +1356706942476 +1252229895866 +1274056484883 +1562667649929 +2066603947528 +2216762463794 +1753668867732 +1627408040098 +1696830777261 +1769287844067 +2922814709325 +2144554353953 +1938462472853 +3878803615421 +2063771161501 +2126889437643 +2276928096998 +2311154729726 +2372518315914 +4619645486586 +2428571537659 +2424984836243 +2441715163072 +4310980788767 +3379119333509 +2919374592405 +2526286380749 +2836724134812 +4046215941065 +6798178207826 +3324238817359 +3381076907830 +6374751950268 +3466118621328 +3707750316920 +6630565026245 +4065351910496 +8189784404188 +4190660599144 +4340699258499 +8803323487927 +4588082826724 +4683673045640 +4797503152157 +7048217024245 +9967591616650 +5361089755477 +4968001543821 +5907363288579 +6984726502901 +5363010515561 +15174510907089 +8406051168995 +6705315725189 +6790357438687 +8178580059987 +8391423362560 +7656779220472 +8988163751301 +10821225625389 +9024372304139 +8531359857643 +8778743425868 +8874333644784 +8928782085223 +9271755872364 +11782229655058 +9765504695978 +10158592907634 +12347737018462 +10331012059382 +16184236140950 +14237344160345 +11270373804140 +14351174266862 +14447136659159 +13495673163876 +15096739087749 +14883895785176 +17415795666699 +28531973159412 +17519523608944 +16585561305695 +17405693502427 +17803115730007 +17555732161782 +32439627946958 +17653077070652 +20144707448924 +20542129676504 +32652471249531 +24649400481154 +19924097603612 +20489604967016 +21601385863522 +23826685223258 +24766046968016 +48476085704412 +25621548071002 +27846847430738 +31966660268103 +28379568949052 +29980634872925 +34001356972394 +33991254808122 +44910754416940 +61838102238860 +37127690982199 +34961425664209 +41525483467134 +35208809232434 +48336452397754 +37577174674264 +40068805052536 +53568046131625 +40413702570628 +47222933934524 +68448374001588 +42090990830538 +45428071086780 +54746681840941 +50387595039018 +53468395501740 +54001117020054 +56226416379790 +58360203821977 +62380925921446 \ No newline at end of file diff --git a/day09/solution.spec.ts b/day09/solution.spec.ts new file mode 100644 index 0000000..f914356 --- /dev/null +++ b/day09/solution.spec.ts @@ -0,0 +1,35 @@ +import { loader, loadString } from '../lib/loader' +import { findInvalidNumber } from './findInvalidNumber' + +const toInt = (s: string) => parseInt(s, 10) +const load = loader(9) +const sample = loadString(`35 +20 +15 +25 +47 +40 +62 +55 +65 +95 +102 +117 +150 +182 +127 +219 +299 +277 +309 +576`).map(toInt) +const input = load('input').map(toInt) + +describe('Day 9: Encoding Error', () => { + describe('Part 1', () => { + it('should solve the sample', () => + expect(findInvalidNumber(5)(sample)).toEqual(127)) + it('should solve', () => + expect(findInvalidNumber(25)(input)).toEqual(25918798)) + }) +}) From 6c8951459caa23cf6aa92942566c0d9b234935de Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Wed, 9 Dec 2020 08:20:51 +0100 Subject: [PATCH 36/60] feat(day09): part 2 --- day09/findInvalidNumber.ts | 3 ++- day09/findSet.ts | 18 ++++++++++++++++++ day09/solution.spec.ts | 11 +++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 day09/findSet.ts diff --git a/day09/findInvalidNumber.ts b/day09/findInvalidNumber.ts index 0809051..d82de3f 100644 --- a/day09/findInvalidNumber.ts +++ b/day09/findInvalidNumber.ts @@ -1,6 +1,7 @@ import { uniqueCombinations } from '../lib/uniqueCombinations' -const sum = (numbers: number[]) => numbers.reduce((total, n) => total + n, 0) +export const sum = (numbers: number[]): number => + numbers.reduce((total, n) => total + n, 0) export const findInvalidNumber = (preambleLength: number) => ( input: number[], diff --git a/day09/findSet.ts b/day09/findSet.ts new file mode 100644 index 0000000..6231bb7 --- /dev/null +++ b/day09/findSet.ts @@ -0,0 +1,18 @@ +// Use backtracking to iterate over growing sets of previous numbers +const sumSet = (input: number[], find: number) => ( + start: number, + size = 2, +): number[] => { + const begin = start - size + if (begin < 0) return [] + const set = input.slice(begin, start) + const setSum = set.reduce((total, n) => total + n, 0) + if (setSum === find) return set + // The set is getting too large + if (setSum > find) return sumSet(input, find)(start - 1) // Move up one line + // Grow the set + return sumSet(input, find)(start, size + 1) +} + +export const findSet = (n: number) => (input: number[]): number[] => + sumSet(input, n)(input.indexOf(n)) diff --git a/day09/solution.spec.ts b/day09/solution.spec.ts index f914356..12d27e6 100644 --- a/day09/solution.spec.ts +++ b/day09/solution.spec.ts @@ -1,5 +1,6 @@ import { loader, loadString } from '../lib/loader' import { findInvalidNumber } from './findInvalidNumber' +import { findSet } from './findSet' const toInt = (s: string) => parseInt(s, 10) const load = loader(9) @@ -32,4 +33,14 @@ describe('Day 9: Encoding Error', () => { it('should solve', () => expect(findInvalidNumber(25)(input)).toEqual(25918798)) }) + describe('Part 2', () => { + it('should solve the sample', () => { + expect(findSet(127)(sample)).toEqual([15, 25, 47, 40]) + }) + it('should solve', () => { + const set = findSet(25918798)(input) + set.sort((a, b) => a - b) + expect(set[0] + set[set.length - 1]).toEqual(3340942) + }) + }) }) From a5630a0e45357b3677f013fc796a4400f2755a54 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Wed, 9 Dec 2020 08:30:56 +0100 Subject: [PATCH 37/60] refactor: improve readability --- day09/findInvalidNumber.ts | 15 +++++++++++++-- day09/findSet.ts | 22 +++++++++++++--------- day09/solution.spec.ts | 4 ++-- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/day09/findInvalidNumber.ts b/day09/findInvalidNumber.ts index d82de3f..0e3dde9 100644 --- a/day09/findInvalidNumber.ts +++ b/day09/findInvalidNumber.ts @@ -1,15 +1,26 @@ import { uniqueCombinations } from '../lib/uniqueCombinations' -export const sum = (numbers: number[]): number => +const sum = (numbers: number[]): number => numbers.reduce((total, n) => total + n, 0) +const equal = (n: number) => (compare: number): boolean => compare === n + +/** + * Finds the invalid number in the input: + * To be valid, the number must be the sum of two of those numbers in + * the subset of preambleLength preceeding it. + */ export const findInvalidNumber = (preambleLength: number) => ( input: number[], ): number | undefined => { const c = uniqueCombinations(2) + // Go through all numbers return input.find((n, k, arr) => { + // Skip if it is part of the preamble if (k < preambleLength) return false + // Build a list of all possible pairs of numbers in the preamble const preamble = c(arr.slice(k - preambleLength, k)) - return preamble.map(sum).find((s) => s === n) === undefined + // If there is no pair which's sum equals this number, it is invalid + return preamble.map(sum).find(equal(n)) === undefined }) } diff --git a/day09/findSet.ts b/day09/findSet.ts index 6231bb7..a8b2dbd 100644 --- a/day09/findSet.ts +++ b/day09/findSet.ts @@ -1,18 +1,22 @@ -// Use backtracking to iterate over growing sets of previous numbers -const sumSet = (input: number[], find: number) => ( - start: number, +/** + * Use backtracking to iterate over growing sets of previous numbers in input + * until a continuous set of numbers is found which's sums up the the number + * we are interested in. + */ +export const findSet = ( + input: number[], + interestingNumber: number, + start = input.indexOf(interestingNumber), size = 2, ): number[] => { const begin = start - size if (begin < 0) return [] const set = input.slice(begin, start) const setSum = set.reduce((total, n) => total + n, 0) - if (setSum === find) return set + if (setSum === interestingNumber) return set // The set is getting too large - if (setSum > find) return sumSet(input, find)(start - 1) // Move up one line + if (setSum > interestingNumber) + return findSet(input, interestingNumber, start - 1) // Move up one line // Grow the set - return sumSet(input, find)(start, size + 1) + return findSet(input, interestingNumber, start, size + 1) } - -export const findSet = (n: number) => (input: number[]): number[] => - sumSet(input, n)(input.indexOf(n)) diff --git a/day09/solution.spec.ts b/day09/solution.spec.ts index 12d27e6..20b4652 100644 --- a/day09/solution.spec.ts +++ b/day09/solution.spec.ts @@ -35,10 +35,10 @@ describe('Day 9: Encoding Error', () => { }) describe('Part 2', () => { it('should solve the sample', () => { - expect(findSet(127)(sample)).toEqual([15, 25, 47, 40]) + expect(findSet(sample, 127)).toEqual([15, 25, 47, 40]) }) it('should solve', () => { - const set = findSet(25918798)(input) + const set = findSet(input, 25918798) set.sort((a, b) => a - b) expect(set[0] + set[set.length - 1]).toEqual(3340942) }) From 122e451a2feffeb9824eddd8809fb50b6a35a7c1 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Thu, 10 Dec 2020 09:00:02 +0100 Subject: [PATCH 38/60] feat(day10): part 1 --- day10/input.txt | 106 ++++++++++++++++++++++++++++++++++++++ day10/sample.txt | 11 ++++ day10/sample2.txt | 31 +++++++++++ day10/solution.spec.ts | 31 +++++++++++ day10/stringUpAdapters.ts | 24 +++++++++ 5 files changed, 203 insertions(+) create mode 100644 day10/input.txt create mode 100644 day10/sample.txt create mode 100644 day10/sample2.txt create mode 100644 day10/solution.spec.ts create mode 100644 day10/stringUpAdapters.ts diff --git a/day10/input.txt b/day10/input.txt new file mode 100644 index 0000000..33cc291 --- /dev/null +++ b/day10/input.txt @@ -0,0 +1,106 @@ +66 +7 +73 +162 +62 +165 +157 +158 +137 +125 +138 +59 +36 +40 +94 +95 +13 +35 +136 +96 +156 +155 +24 +84 +42 +171 +142 +3 +104 +149 +83 +129 +19 +122 +68 +103 +74 +118 +20 +110 +54 +127 +88 +31 +135 +26 +126 +2 +51 +91 +16 +65 +128 +119 +67 +48 +111 +29 +49 +12 +132 +17 +41 +166 +75 +146 +50 +30 +1 +164 +112 +34 +18 +72 +97 +145 +11 +117 +58 +78 +152 +90 +172 +163 +89 +107 +45 +37 +79 +159 +141 +105 +10 +115 +69 +170 +25 +100 +80 +4 +85 +169 +106 +57 +116 +23 \ No newline at end of file diff --git a/day10/sample.txt b/day10/sample.txt new file mode 100644 index 0000000..cd1b40b --- /dev/null +++ b/day10/sample.txt @@ -0,0 +1,11 @@ +16 +10 +15 +5 +1 +11 +7 +19 +6 +12 +4 \ No newline at end of file diff --git a/day10/sample2.txt b/day10/sample2.txt new file mode 100644 index 0000000..be5c492 --- /dev/null +++ b/day10/sample2.txt @@ -0,0 +1,31 @@ +28 +33 +18 +42 +31 +14 +46 +20 +48 +47 +24 +23 +49 +45 +19 +38 +39 +11 +1 +32 +25 +35 +8 +17 +7 +9 +4 +2 +34 +10 +3 \ No newline at end of file diff --git a/day10/solution.spec.ts b/day10/solution.spec.ts new file mode 100644 index 0000000..ca4df6c --- /dev/null +++ b/day10/solution.spec.ts @@ -0,0 +1,31 @@ +import { loader } from '../lib/loader' +import { countDifferences, stringUpAdapters } from './stringUpAdapters' + +const toInt = (s: string) => parseInt(s, 10) +const load = loader(10) +const sample = load('sample').map(toInt) +const sample2 = load('sample2').map(toInt) +const input = load('input').map(toInt) + +describe('Day 10: Adapter Array', () => { + describe('Part 1', () => { + it('should solve the sample', () => { + const adapters = stringUpAdapters(sample) + expect(adapters).toEqual([1, 4, 5, 6, 7, 10, 11, 12, 15, 16, 19, 22]) + const differences = countDifferences(adapters) + expect(differences).toEqual({ 1: 7, 3: 5 }) + }) + it('should solve the seconds sample', () => + expect(countDifferences(stringUpAdapters(sample2))).toEqual({ + 1: 22, + 3: 10, + })) + it('should solve the seconds sample', () => + expect( + Object.values(countDifferences(stringUpAdapters(input))).reduce( + (total, r) => total * r, + 1, + ), + ).toEqual(2482)) + }) +}) diff --git a/day10/stringUpAdapters.ts b/day10/stringUpAdapters.ts new file mode 100644 index 0000000..9afb66b --- /dev/null +++ b/day10/stringUpAdapters.ts @@ -0,0 +1,24 @@ +/** + * String up all adapters (by sorting them). + * Finally, your device's built-in adapter is always 3 higher than the highest adapter + */ +export const stringUpAdapters = (adapterRatings: number[]): number[] => { + const sorted = [...adapterRatings].sort((a, b) => a - b) + sorted.push(sorted[sorted.length - 1] + 3) // Add device adapter + return sorted +} + +/** + * Count the rating differences in the string of adapters + */ +export const countDifferences = ( + adapterRatings: number[], +): Record => + adapterRatings.reduce((diff, rating, index, ratings) => { + const previousRating = ratings[index - 1] ?? 0 + const ratingDiff = rating - previousRating + return { + ...diff, + [ratingDiff]: (diff[ratingDiff] ?? 0) + 1, // Increase counter for this rating differences + } + }, {} as Record) From 3d0882a15222a8561ba6ae0aa3d6ecc0cff8cfe4 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Thu, 10 Dec 2020 18:49:59 +0100 Subject: [PATCH 39/60] feat(day10): part 2 ... after 3rd try --- day10/arrangeAdapters.ts | 80 +++++++++++++++++++++++++++++++ day10/countAdapterArrangements.ts | 39 +++++++++++++++ day10/countRoutes.ts | 26 ++++++++++ day10/solution.spec.ts | 32 +++++++++++++ 4 files changed, 177 insertions(+) create mode 100644 day10/arrangeAdapters.ts create mode 100644 day10/countAdapterArrangements.ts create mode 100644 day10/countRoutes.ts diff --git a/day10/arrangeAdapters.ts b/day10/arrangeAdapters.ts new file mode 100644 index 0000000..899d3c5 --- /dev/null +++ b/day10/arrangeAdapters.ts @@ -0,0 +1,80 @@ +import { countDifferences, stringUpAdapters } from './stringUpAdapters' + +const checks = {} as Record + +const hashRatings = (ratings: number[]): string => ratings.toString() + +const isValid = (ratings: number[]): boolean => { + const hash = hashRatings(ratings) + if (checks[hash] === undefined) { + const diffs = countDifferences(ratings) + // All differences must be between 1-3 volts + const diffRatingsValid = Object.keys(diffs).reduce((isValid, rating) => { + if (isValid === false) return false + const r = parseInt(rating, 10) + return r >= 1 && r <= 3 + }, true) + checks[hash] = diffRatingsValid + } + return checks[hash] +} + +/** + * First attempt, mutate the arrangements by removing one or more adapters + * and verifying if this arrangement is valid. + * If yes, remove more adapters until it is not. + * + * This works, but is too slow. + */ +const mutate = ( + ratings: number[], + mutations: number[][], + deviceRating: number = ratings[ratings.length - 1], + deleteFrom = 0, + deleteAmount = 1, + previousPassed = true, +): boolean => { + // We would be deleting the entire list of adapters + if (deleteFrom >= ratings.length) return false + if (deleteFrom + deleteAmount >= ratings.length) return false + // Create the mutation by removing adapters from the given position + const mutation = [ + ...ratings.slice(0, deleteFrom), + ...ratings.slice(deleteFrom + deleteAmount), + ] + // We removed all + if (mutation.length === 0) return false + // We no longer can connect to the device + if (mutation[mutation.length - 1] !== deviceRating) return false + // We already know this is a valid mutations + const mutationHash = hashRatings(mutation) + if (mutations.find((m) => hashRatings(m) === mutationHash)) return false + // We have already checked this mutation + if (checks[mutationHash] !== undefined) { + return mutate(ratings, mutations, deviceRating, deleteFrom + 1, 1, false) + } + if (isValid(mutation)) { + mutations.push(mutation) // Found one + // Continue with this mutation, delete more + mutate(mutation, mutations, deviceRating, deleteFrom - deleteAmount, 1) + mutate( + mutation, + mutations, + deviceRating, + deleteFrom - deleteAmount, + deleteAmount + 1, + ) + // If we found this from a previously valid combination, + // continue with the entire chain and delete more + if (previousPassed) + mutate(ratings, mutations, deviceRating, deleteFrom, deleteAmount + 1) + } + return mutate(ratings, mutations, deviceRating, deleteFrom + 1, 1, false) +} + +export const arrangeAdapters = (ratings: number[]): number[][] => { + const sorted = stringUpAdapters(ratings) + const mutations = [] as number[][] + mutate(sorted, mutations) + return [sorted, ...mutations] +} diff --git a/day10/countAdapterArrangements.ts b/day10/countAdapterArrangements.ts new file mode 100644 index 0000000..8e4186b --- /dev/null +++ b/day10/countAdapterArrangements.ts @@ -0,0 +1,39 @@ +import { stringUpAdapters } from './stringUpAdapters' + +const chainConnections = ( + connections: Record, + chains = 0, + rating = 0, +): number => { + // If there is no more adapter to connect, we have reached the end of the chain + if (connections[rating].length === 0) { + // end of chain + return 1 + } + // For all possible connections to this adapter extend the chain + return connections[rating].reduce( + (total, connection) => + total + chainConnections(connections, chains, connection), + chains, + ) +} + +/** + * Improved implementation: this one first determins all possible adapters one, + * and then creates a chain for all these combinations using backtracking. + */ +export const countAdapterArrangements = (ratings: number[]): number => { + const connections = [0, ...stringUpAdapters(ratings)] + .sort((a, b) => a - b) + .reduce( + (connections, rating, _, ratings) => ({ + ...connections, + [rating]: ratings.filter((r) => { + const diff = r - rating + return diff >= 1 && diff <= 3 + }), + }), + {} as Record, + ) + return chainConnections(connections) +} diff --git a/day10/countRoutes.ts b/day10/countRoutes.ts new file mode 100644 index 0000000..e60a064 --- /dev/null +++ b/day10/countRoutes.ts @@ -0,0 +1,26 @@ +import { stringUpAdapters } from './stringUpAdapters' + +/** + * Third aproach: count the possible routes + * Go through each adapter and count how many routes lead to this adapter. + * There can be at max three adapters leading to this one in the previous + * connection, because of the rating constraint (diff must be 1-3). + */ +export const countRoutes = (ratings: number[]): number => { + const adapters = [0, ...stringUpAdapters(ratings)] // sort by rating + const routes = adapters.map((_, k) => (k === 0 ? 1 : 0)) // Create the map to store the routes needed to reach each adapter + + // there are n adapters + for (let n = 0; n < routes.length; n++) { + // add the number of routes that lead to the preceeding 3 adapters + for (let j = n - 3; j < n; j++) { + if (adapters[n] <= adapters[j] + 3) { + routes[n] += routes[j] + } + } + } + + // the last entry now contains the sum of all possibly combinations leading + // to the last adapter + return routes[routes.length - 1] +} diff --git a/day10/solution.spec.ts b/day10/solution.spec.ts index ca4df6c..3afcb58 100644 --- a/day10/solution.spec.ts +++ b/day10/solution.spec.ts @@ -1,5 +1,8 @@ import { loader } from '../lib/loader' import { countDifferences, stringUpAdapters } from './stringUpAdapters' +import { arrangeAdapters } from './arrangeAdapters' +import { countAdapterArrangements } from './countAdapterArrangements' +import { countRoutes } from './countRoutes' const toInt = (s: string) => parseInt(s, 10) const load = loader(10) @@ -28,4 +31,33 @@ describe('Day 10: Adapter Array', () => { ), ).toEqual(2482)) }) + describe('Part 2', () => { + it('should solve the sample', () => { + const arr = arrangeAdapters(sample) + expect(arr).toHaveLength(8) + expect(arr).toContainEqual([1, 4, 5, 6, 7, 10, 11, 12, 15, 16, 19, 22]) + expect(arr).toContainEqual([1, 4, 5, 6, 7, 10, 12, 15, 16, 19, 22]) + expect(arr).toContainEqual([1, 4, 5, 7, 10, 11, 12, 15, 16, 19, 22]) + expect(arr).toContainEqual([1, 4, 5, 7, 10, 12, 15, 16, 19, 22]) + expect(arr).toContainEqual([1, 4, 6, 7, 10, 11, 12, 15, 16, 19, 22]) + expect(arr).toContainEqual([1, 4, 6, 7, 10, 12, 15, 16, 19, 22]) + expect(arr).toContainEqual([1, 4, 7, 10, 11, 12, 15, 16, 19, 22]) + expect(arr).toContainEqual([1, 4, 7, 10, 12, 15, 16, 19, 22]) + }) + it('should solve the sample (using countAdapterArrangements)', () => { + const arr = countAdapterArrangements(sample) + expect(arr).toEqual(8) + }) + it('should solve the sample (using countAdapterArrangements)', () => + expect(countAdapterArrangements(sample)).toEqual(8)) + + it('should solve the second sample (using countAdapterArrangements)', () => + expect(countAdapterArrangements(sample2)).toEqual(19208)) + + // The two above approaches were too slow + it('should solve the second sample (using countWays)', () => + expect(countRoutes(sample2)).toEqual(19208)) + + it('should solve', () => expect(countRoutes(input)).toEqual(96717311574016)) + }) }) From a0788065dfcf42480e3eb27e780bc16f2f154c81 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Fri, 11 Dec 2020 09:07:15 +0100 Subject: [PATCH 40/60] feat(day11): part 1 --- day11/input.txt | 91 ++++++++++++++++++++++++++++++++++ day11/seatingSimulator.ts | 102 ++++++++++++++++++++++++++++++++++++++ day11/solution.spec.ts | 39 +++++++++++++++ 3 files changed, 232 insertions(+) create mode 100644 day11/input.txt create mode 100644 day11/seatingSimulator.ts create mode 100644 day11/solution.spec.ts diff --git a/day11/input.txt b/day11/input.txt new file mode 100644 index 0000000..75548d9 --- /dev/null +++ b/day11/input.txt @@ -0,0 +1,91 @@ +LLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLL.LLLL.L.LLLLLLL.LLLLLLL.LLLLLL.LL.LLLL.LLLLLLLLLLLLLLL +LLL.LLLLL.LLLLLLLLLLL.LLLLLLLLL.LLLLLL.LLLL.LLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL +LLLLLLLLL.LLLL.LLLLLLLLLL.LLLLLLL.LLLL.LLL....LLL.LLL.LLLLLLL.LLL.LLLLL.LLLLLLLL.LLLLLLLLLLL +LLLLLLLLLLLLLL.LLLLLL.LLLLLLLLL.LLLLLL.LLLL.LLL.LLLLL.LLLLLLL.LLLLLLLLL.LLLLLLLLLLLLLLLLLLLL +LLLL.LLLL.LLLL.LLLLLL.LLLLLLLLL.LLLLLL.LLLL.LLLLLLLLL.LLLLLLL.LLL.LLLLL.LLLLLLLL.LLLLLLLLLLL +LLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLL.LLLLL.LLLL.LLLLLLL.L.LLL.LLL.LLLLLLLLL.LLLLLLLL.LLLLLLLLLLL +LLLLLLLLL.LLLL.LLLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLL.LLLLLLLL.LLL..LL.LLL +LLLLLLLLL.LLLLLLLLLLL.LLLLL.LLL.LLLLLL.LLLL.LL.L.LLLL.LLLLLLL.LLLLLLLLL.LLLLLLLLLLLLLLLLLLLL +LLLLLLLLLLLLLL.LLLLLL.L.LLLLLLLLLL.LLL.LLLL.LLLLLLLLLLLLL.LLL.LLLLLLLLLLLLLLLLLL.LLLLLLLLLLL +....L..L....L...L.......L.LL.....L..L...LLLL.LLL..L.L...LL..L...LL.....L..LL.....L....L.L..L +LLLLLLLLLLLLLL.LLLLLL.LLLLLLLLL.LLLLLLLLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLLL.LLLLLLLL.LLLLLLLLLLL +LLLLL.LLL.LLLL.LLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLLLL +LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLL.LL.LLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLL..LLLLLLLLLL +LLLLLLLLL.LLLL.LLLLLL.LLLLLLLLL.LLLLLLLLLLLLLL.LLLLLL.LL..LLL.LLLLLLLLLLLLLLLLLL.LLLLLLLLLLL +LLLLLLLLLLLLLL.LLLLLLLLLLLLLLLL.LLLLLL.LLLL.LLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLL +LLL..LLLL.LLLLL.LLLLLLLL.LLLLLLLLLLLLL.LLLL.LLLLLLLLL.LLLLLLL.LLLLLLLLL.LLLLLLLLLLLLLLLLLLLL +LLLLLLLLL.LLLL.LLLLLLLLLLL.LLLLLLLLLLL.LLLL.LLLLLLLLL.L.LLLLL.LLLLLLLLL.LLLLLLLL.LLLLLLLLLLL +LLLLLLLLLLLLLL.LLLLLL.LLLLLLLLLLL.LLLL.LLLL.LLLLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLLL.LLLLLLLLLLL +LLLLLLLLL.LLLLLLLLLLL.LLL.LLLLL.LLLLLLLLLLLLLLLLLLLLL..LLLLLL.LLLLLLLLL.LLLLLLLL.LLLLLLLLLLL +.L..L......L.L....L...L..........L.L....L...LL....LL....LL...LLL....LL..L...L...L.........L. +LLLLLLLLL.LLLLLLLLL.LLLLLLLLLLL.LLL.LL.LLLLLLLLLLLLLLLLLLLLL..LLLLLLLLLLLLLLLLLL.LLLLLLLLLLL +LLLLLLLLL.LLLL.LLLLLLLL.LLLLLLL.LLLLLL.LLLLLLLLLLL.LL.LLLLLLL.LLLLLLL.L.LLL.LLLL.LLLLLLLLLLL +LLLLLL.LL.LLLL.LLLLLL.LLLLLLLLL.LLLLLLLLLLL.LLLLLLLLL.LLLL.LL.LLLLLLLLLLLLLLLLLL.LLLLLLLLLLL +LLLLLLLLL.LLLLLLLLLLL.LLLLLLLLL.LLLLLLLLLLL.LLLLLLLLL.LLLLLLL.LLLLLLLLL.LLLLLLLL..LLLLLLLLLL +LLLLLLLLL.LLLLLLLLLLL.LLLLLLLLL.LLLLLL.L.LLLLLLLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLLL.LLLLLLLLLLL +LLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLL.LLLL.LLLLLLLLL.LLLL.LL.L.LLLLLLLLLLLLLL.L.LLLLLLLLLLL +LLLLLLLLLLLLLL.LLLLLLLLLLLLLLLL.LL.LLLLLLLL.LLLLLLLLL.LLLLLLL.LLLLLLLLL.LLLLLLLLLLLLLLLLLLLL +LLLLLLLLL.LLLLLLLLLLL.LLLLLLLLL.LLLLLL.LLLL.LLLLLLLLL.LLLLLLL.LLLLLLLLL.LLLLLLLLLLLLLLLLLLLL +..L.L.L..L.L.....LL..L........L..L....L...LL.........L.L.L.L..L......L.........L..L....L.... +LLLLLLL.LLLLLLLLLLLLL.LLLLLLLLLLLLLL.L.LLLL.LLLLLLLLL.LLLLLLL.LLLLLLL.L.LLLLLLLLLLLLLLL.LLLL +LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLL.LLLLLLLLL.LLLLLLLL.LLLLLL.LLLLLLLLLLLLLLLLLLLLLL +LLLL.LLLL.LLLLLLLLLL..LLLLLLLLL.LLLLLLLLLLL.LLL.LLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLL.LLLLLLLLLLL +LLLL.LLLL.LLL..LLLLLLLLLLLLLLLL.LLLLLLLLLLL.LLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLL +LLLLL.LLL.LLLLLLLLLLL.LLLLLLLLL.LLLLLLLLLLL.LLLLLLLLL.LLLLLLL.LLLLLLLLL.LLL.LLLL.LLLLLLLLLLL +LLLLLLLLLLLLLLLL.LLLL.LLLLLLL.L.LL.LLLLLLLL.LLLLLLLLL.LLLLLLL.LLLLLLL.L.LLLLLLLL.LL.LLLLLLLL +LLLLLLL.LLLLLL.LLLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLL.LLLLLLLLLLL +L...L.......LL.LL.L....L...L.....L.......L.........L.L.L..LL.L.L.L.L..L....L.L...L.L.LL..... +LL.LLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLL.LLLL.LLLLLLLLL.LLLLLL..LLLLLLLLL.LLLLLLLLLLLLLLLLLLLL +LLLLL.LLL.LLLL.LLLLLL.LLLLLLLLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLL.LLL.LLLLLL. +LLLLLLLLL.LLLL.LLLLLL.LLLLLLLLL.LLLLLL..LLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.L.LLLLLLLL. +LLLLLLLLL.LLLLLLLLLLLLLLLLLLLLL.LLLLL..LLLL.LLLLLLLLL.LLLLLLL.LLLLLLLLL.LLLLLLLL.LLLLLLLL.LL +..LLL.L..L..L..L..L..L.L...LL..L.....LLL.L..LL.....LLL.......L.L...L........LL........L....L +LLLLLLLLL.LLLL.LLLLLLLLLLLLLLLL.LLLLLL.LLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLL.LLLL.LLLLLLLLLLLLLLL +LLLLLLLLL.LLLLLLLLLLL.LLLLLLLLLLLLLLLL.LLLL.LLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLL.LLLLLLLLLLL +LLLLLLLLLLLLLL.LLLLLL.LLLLLLLLL.LLLLLL.LLLL.LLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLLLLLL +L.LLLLLLL.LLLL.LLLLLL.LLLLLLLLL.LL.LLLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLLL.LLLLLLLLLLL +LLLLLLLLL.LLLL.LLLLLL.LLLLLLLLL.LLLLLL.LLLL.LLLLLLLLL.LLLLLLL.LLLLLLLLL.LLLLLLLL.LLLLLLLLLLL +LL.LL...L......L.L.....L.........L....L...L..L..LLL.L...L......L.L.....LL..LL..LLL....L..L.L +LLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLLLLLLL.LLLLLLLLL.LLLLLL.LLLL.LLLLLLLL +LL.LLLLLL.LLLLLLLLLLL.LLLLLLLLL.LLLLLL.LLLLLLLLLLLLLLLLLLLLLL.L.LLLLLLL.LLLLLLLL.LLLLLLLLLLL +LLLLLLLLL.LLLLLLLLLLL.LLLLLLLLL.LLLLLLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLL.LLLLLLLLLLL +LLLLLLLLL.LLLL.LLLLLLLLLLLLLLLL.LLLLLL.LLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLL.L.LLLLLL.L.LLLLLLLLL +LLLLLLL.L.LLLL.LLLL.L.LLLLLLLLL.LLLLLL.LLLL.LLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLL.LLLLLLLL.LL +L..L.L....L......LLLL...L....LL...L..LLL......LLL.LL.LLL...LL..L...LLL........L.....LL.L.LLL +LLLLLLLLL.LLLL.LLLLLL.LLLLLLLLL.LLLLLL.LLLL.LLLLLLLLL.LLLLLLL.LLLLLL.LL.LLLLLLLL.LLLLLLLLLLL +LLLL.LLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLL.LLLLLLLL.LLLLLLLLLLL +LLLLLLLLL.LLLLLLLLLLL.LLLLLLLLL.LLLLLL.LLLL.L.LLLLLLL.LLLLLLL.LLLLLLL.L.LL.LLLLL.LLLLLLLLLLL +LLLLLLLLL.LLLLLLLLLLL.LLLLLLLLL.LLLLL..LLLLLL.LLLL.LLLLLLLLLL.LLLLLLLLL.LLLLLLLLLLLLLLLLLLLL +LL.......L......L...LL.......LL.LL.LL.L.LL.L..L.......L.L.LLLL.LL...LL......LLL..L....LLL... +LLLLLLLLL.LLL..LLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLLL.LLLLLLLLLLL +LLLLLLLLL.LLLL.LLLLLLLLLL.LLLLL.LLLLLLLL.LL.LLLLLLLLL.L.LLLLL.LLLLLLLLL.LLLLLLLLLLLLLLLL.LLL +LLLLLLLLLLLLLLLLLLLLL.L.LLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLL.LLLLLLLLL.LLLLLLLL.LLLLLLLLLLL +LLLLLLLLLLLLLL.LLLLLL.LLLL.LLLLLLLLLLL.LLLLLLLLLLLLLL.LLLLL.LLLLLLLLL.L.LLLLLLLL.LLLLLLLLLLL +LLLLLLL.LLLLLL.LLLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLLLLLLL.LLLLLLL..LLLLLLLL.LLLLLLLLLLLLLLLLLLLL +LLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLL.LLLLL.LLLL.LLLLLLLLL.LLLLLLL.LLLLLLLLL.LLLLLLLLLL.LLLLLLLLL +LLLLLLLLLLLLLL.LLLLLL.LLLLLLLLLLLLLLLL.LLLL.LLLLLLLLL.LLLLLLL.LLLLLLL.L.LLLLLLLLLLLLLLLLLLLL +...L..L..L..L...L.........L.L.L..LLL.....LL......L..LLL..L.L.......L.L.L..LLL...........L... +LLLLLLLLL.LLLL..LLLLLLLLLLLLLLL.LLLLLL.LLLL.LLLLLLLLL.LLLLLLL.LLLLLLLLL.LLLLLLLL.LLLLLLLLLLL +LLLLLLLLLLLLLL.LLLLLL.LLLLLLLLLLLLLLLL.LLLL.LLLLLLLLL.LLLLLLL.LLLLL.LLL.LLLLLLLL.LLLLLLLLLLL +LLLLLL.LLLLLLLLLLLLLLLLL.LLLLLL.LLLLLL.LLLL.L.LLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLLL.L.LLLLLLLLL +LLLLLLLLL.LLLL.LLL..L.LLLLLLLLL.LLLLLL.LLLL.LLLLLLLLL.L.LLLLL.LLLLLLLLL.LLLLLLLL.LLLLLLLLLLL +LLLLLLLLLL.LLL.LLLLLLLLLLLLLLLL.LLLLLL.LLLL.LLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL +LLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLL.LLL.LLLL.LLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLL.LLL.LLLLLLLLLLL +LLLLLLLLL.LLLL.LLLLLLLLL.LLLLLLLLLLLLL.LLLL.LLLLLLLLL.LLLLLLL.LLL.LLLLL.LLLLLLLL.LLLLLLLLLLL +LLLLLLLLL.LLLL.LLLLLL.LLLLLLLLL.LLLLLL.LLLLLLLLLLL.LLLLLLL.LL.LLLLLLLLL.LLLLLLLL.LLLLLLLLLLL +LLLLLLLLL.LLLL.LLLLLLLLLLLLLLLLLLLLLLL.LLLL.LLLLLLLLL.LLLLLLL.LLLLLLLLL..LLLLLLLLLLLLLLLLLLL +..L.LLL.....L....L.L.L..L.L..L.L..LL.......L.L.L......L..L..L..L..L.......L...LL..LL..L...LL +LLLLLLLLL.LL.LLLL.LLL.LLLLLLLLLL.LLLLL.LLLL.LLLLLLLLL.LLLLLLLLLLLLLLLL..LLLLLL.L.LLLLLLLLLLL +LLLLLLLLL.LLLL.LLLLLL.LL.LLLLLL.LLLLLL.L.LL.LLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLL +LLLLLLLLL.LLLL.LLLLLLLLLLLLL.LL.LLLLLL.LLLL.LLLLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLL +LLLLLLLLLLLLLL.LLLLLL.L.LLLLLLL.LLLLLL.LLLL.LLLLLLLLLLLLLLLLL.LLL.LLLL..LLLLLLLL.LLLLLLLLLLL +LLLLLLLLLLLLL..LLLLLLLLLLLLLLLL.LLLL.L.LLLLLLLLLLLLLL.LLLLLLL.LLLLLLLL..LL.LLLLL.LLLLLLLLLLL +LLLLLLLLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLL.LLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLLL.LLLLLLLLL.L +LLLL.LLLL.LLLLLLLLLLL.LLLLLLLLLLLLLLLL.LLLL.LLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLLL +LLLLLLLLL.LLLL.LLLLLLLLLLLLLLLL.LLLLLLLLLLL.LLLLLLLLL.LLLLLLL.LLLLLLLLL.LLLLLLLL.LLLLLL.LLLL +LLLLLLLLLLLLLLLLLLLLL.LLLLLLLL..LLLLLLLLLLL.LLLLLLLLL.L.LLLLLLLLLLLLLLL.LLLLLLLL..LLLLLLLLLL +LLLLLLLLLLLLLL.LLLLLL.LLLLLLLLLLLLLLLLLLLLL.LLLL.LLLL.LLLLLLL.LLLLLLLLL.LLLLLLLLLLLLLLLLLLLL +LLLLLLLLL.LLLL.LLLLLL.LLLLLLLLL.LLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLL.LLLLLLLLLLLLLLLLLLLL +LLLLLLLLL.LLLLLLL.LLL.LLLLLLLLL.LLLLLL.LLLL.LLLLLLLLL.LLLLLL..LLLLLL.LLLLLLLLLLLLLLLLLLLLLLL +L.LLLLLLLL.LLLLLLLLLL.LLLLLLLLLLLLLLLL.LLLL.LLLLL.LLL.LLLLLL..LLLLLLLLLLLLLLLLLL.LLL.LLLLLLL \ No newline at end of file diff --git a/day11/seatingSimulator.ts b/day11/seatingSimulator.ts new file mode 100644 index 0000000..913e86f --- /dev/null +++ b/day11/seatingSimulator.ts @@ -0,0 +1,102 @@ +enum Tile { + Empty = 'L', + Occupied = '#', +} +enum Direction { + N, + NE, + E, + SE, + S, + SW, + W, + NW, + NONE, +} + +const is = ( + world: string[][], + row: number, + col: number, + state: Tile, + dir = Direction.NONE, +): boolean => { + switch (dir) { + case Direction.NONE: + if (row < 0) return false + if (row >= world.length) return false + if (col < 0) return false + if (col >= world[row].length) return false + return world[row][col] === state + case Direction.N: + return is(world, row - 1, col, state) + case Direction.NE: + return is(world, row - 1, col + 1, state) + case Direction.E: + return is(world, row, col + 1, state) + case Direction.SE: + return is(world, row + 1, col + 1, state) + case Direction.S: + return is(world, row + 1, col, state) + case Direction.SW: + return is(world, row + 1, col - 1, state) + case Direction.W: + return is(world, row, col - 1, state) + case Direction.NW: + return is(world, row - 1, col - 1, state) + default: + console.error(`Unknown direction ${dir}.`) + return false + } +} + +export const render = (world: string[][]): string => + world.map((s) => s.join('')).join('\n') + +const iteration = (current: string[][]): string[][] => { + const next = [] + for (let row = 0; row < current.length; row++) { + next[row] = [] as string[] + for (let col = 0; col < current[0].length; col++) { + let occupied = 0 + occupied += is(current, row, col, Tile.Occupied, Direction.N) ? 1 : 0 + occupied += is(current, row, col, Tile.Occupied, Direction.NE) ? 1 : 0 + occupied += is(current, row, col, Tile.Occupied, Direction.E) ? 1 : 0 + occupied += is(current, row, col, Tile.Occupied, Direction.SE) ? 1 : 0 + occupied += is(current, row, col, Tile.Occupied, Direction.S) ? 1 : 0 + occupied += is(current, row, col, Tile.Occupied, Direction.SW) ? 1 : 0 + occupied += is(current, row, col, Tile.Occupied, Direction.W) ? 1 : 0 + occupied += is(current, row, col, Tile.Occupied, Direction.NW) ? 1 : 0 + if (current[row][col] === Tile.Empty) { + next[row][col] = occupied === 0 ? Tile.Occupied : current[row][col] + } else if (current[row][col] === Tile.Occupied) { + next[row][col] = occupied >= 4 ? Tile.Empty : current[row][col] + } else { + next[row][col] = current[row][col] + } + } + } + return next +} + +/** + * Run until equilibrium is reached + */ +export const seatingSimulator = (world: string): string[][] => { + const start = world + .split('\n') + .map((s) => s.trim().split('')) + .filter((s) => s.length > 0) + + let prevOccupied = -1 + let occ = -1 + let gen = start + do { + prevOccupied = occ + gen = iteration(gen) + occ = render(gen) + .split('') + .filter((s) => s === '#').length + } while (occ != prevOccupied) + return gen +} diff --git a/day11/solution.spec.ts b/day11/solution.spec.ts new file mode 100644 index 0000000..38d5e03 --- /dev/null +++ b/day11/solution.spec.ts @@ -0,0 +1,39 @@ +import { loader } from '../lib/loader' +import { render } from './seatingSimulator' +import { seatingSimulator } from './seatingSimulator' + +const load = loader(11) +const sample = ` +L.LL.LL.LL +LLLLLLL.LL +L.L.L..L.. +LLLL.LL.LL +L.LL.LL.LL +L.LLLLL.LL +..L.L..... +LLLLLLLLLL +L.LLLLLL.L +L.LLLLL.LL` + +const input = load('input') + +describe('Day 11: Seating System', () => { + describe('Part 1', () => { + it('should solve the sample', () => { + const stable = seatingSimulator(sample) + expect( + render(stable) + .split('') + .filter((s) => s === '#').length, + ).toEqual(37) + }) + it('should solve the sample', () => { + const stable = seatingSimulator(input.join('\n')) + expect( + render(stable) + .split('') + .filter((s) => s === '#').length, + ).toEqual(2164) + }) + }) +}) From 4872fd8409e2a0c983462f12d0a74d2fb24c4f1b Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Fri, 11 Dec 2020 09:58:38 +0100 Subject: [PATCH 41/60] feat(day11): part 2 --- day11/seatingSimulator.spec.ts | 36 ++++++++ day11/seatingSimulator.ts | 153 +++++++++++++++++++++++++-------- day11/solution.spec.ts | 28 +++--- 3 files changed, 170 insertions(+), 47 deletions(-) create mode 100644 day11/seatingSimulator.spec.ts diff --git a/day11/seatingSimulator.spec.ts b/day11/seatingSimulator.spec.ts new file mode 100644 index 0000000..9031a4c --- /dev/null +++ b/day11/seatingSimulator.spec.ts @@ -0,0 +1,36 @@ +import { loadString, isOccupied, Direction } from './seatingSimulator' + +describe('seatingSimulator', () => { + describe('isOccupied', () => { + const world1 = loadString(`.......#. + ...#..... + .#....... + ......... + ..#L....# + ....#.... + ......... + #........ + ...#.....`) + it.each([ + [Direction.E], + [Direction.SE], + [Direction.S], + [Direction.SW], + [Direction.W], + [Direction.NW], + [Direction.N], + [Direction.NE], + ])('should see a seat in direction %s', (direction) => + expect(isOccupied(world1, 4, 3, direction, direction)).toEqual(1), + ) + + it('should only see one seat', () => { + const world2 = loadString( + `............. + .L.L.#.#.#.#. + .............`, + ) + expect(isOccupied(world2, 1, 1, Direction.E, Direction.E)).toEqual(0) + }) + }) +}) diff --git a/day11/seatingSimulator.ts b/day11/seatingSimulator.ts index 913e86f..f7a7868 100644 --- a/day11/seatingSimulator.ts +++ b/day11/seatingSimulator.ts @@ -2,7 +2,7 @@ enum Tile { Empty = 'L', Occupied = '#', } -enum Direction { +export enum Direction { N, NE, E, @@ -14,59 +14,102 @@ enum Direction { NONE, } -const is = ( +/** + * Determines whether a seat is occupied by going in direction dir from the start + * row and col. + * Optionally it will walk down the direction until it finds a seat to evaluate. + */ +export const isOccupied = ( world: string[][], row: number, col: number, - state: Tile, dir = Direction.NONE, -): boolean => { + walk = Direction.NONE, +): number => { switch (dir) { case Direction.NONE: - if (row < 0) return false - if (row >= world.length) return false - if (col < 0) return false - if (col >= world[row].length) return false - return world[row][col] === state + if (row < 0) return 0 + if (row >= world.length) return 0 + if (col < 0) return 0 + if (col >= world[row].length) return 0 + if (world[row][col] === Tile.Occupied) return 1 + if (world[row][col] === Tile.Empty) return 0 + switch (walk) { + case Direction.NONE: + return 0 + case Direction.N: + return isOccupied(world, row - 1, col, Direction.NONE, walk) + case Direction.NE: + return isOccupied(world, row - 1, col + 1, Direction.NONE, walk) + case Direction.E: + return isOccupied(world, row, col + 1, Direction.NONE, walk) + case Direction.SE: + return isOccupied(world, row + 1, col + 1, Direction.NONE, walk) + case Direction.S: + return isOccupied(world, row + 1, col, Direction.NONE, walk) + case Direction.SW: + return isOccupied(world, row + 1, col - 1, Direction.NONE, walk) + case Direction.W: + return isOccupied(world, row, col - 1, Direction.NONE, walk) + case Direction.NW: + return isOccupied(world, row - 1, col - 1, Direction.NONE, walk) + default: + console.error(`Unknown direction ${dir}.`) + return 0 + } case Direction.N: - return is(world, row - 1, col, state) + return isOccupied(world, row - 1, col, Direction.NONE, walk) case Direction.NE: - return is(world, row - 1, col + 1, state) + return isOccupied(world, row - 1, col + 1, Direction.NONE, walk) case Direction.E: - return is(world, row, col + 1, state) + return isOccupied(world, row, col + 1, Direction.NONE, walk) case Direction.SE: - return is(world, row + 1, col + 1, state) + return isOccupied(world, row + 1, col + 1, Direction.NONE, walk) case Direction.S: - return is(world, row + 1, col, state) + return isOccupied(world, row + 1, col, Direction.NONE, walk) case Direction.SW: - return is(world, row + 1, col - 1, state) + return isOccupied(world, row + 1, col - 1, Direction.NONE, walk) case Direction.W: - return is(world, row, col - 1, state) + return isOccupied(world, row, col - 1, Direction.NONE, walk) case Direction.NW: - return is(world, row - 1, col - 1, state) + return isOccupied(world, row - 1, col - 1, Direction.NONE, walk) default: console.error(`Unknown direction ${dir}.`) - return false + return 0 } } export const render = (world: string[][]): string => world.map((s) => s.join('')).join('\n') -const iteration = (current: string[][]): string[][] => { +/** + * All decisions are based on the number of occupied seats adjacent to a given + * seat (one of the eight positions immediately up, down, left, right, or + * diagonal from the seat). The following rules are applied to every seat + * simultaneously: + * + * - If a seat is empty (L) and there are no occupied seats adjacent to it, + * the seat becomes occupied. + * - If a seat is occupied (#) and four or more seats adjacent to it are also + * occupied, the seat becomes empty. + * - Otherwise, the seat's state does not change. + * + * Floor (.) never changes; seats don't move, and nobody sits on the floor. + */ +export const part1rules = (current: string[][]): string[][] => { const next = [] for (let row = 0; row < current.length; row++) { next[row] = [] as string[] for (let col = 0; col < current[0].length; col++) { let occupied = 0 - occupied += is(current, row, col, Tile.Occupied, Direction.N) ? 1 : 0 - occupied += is(current, row, col, Tile.Occupied, Direction.NE) ? 1 : 0 - occupied += is(current, row, col, Tile.Occupied, Direction.E) ? 1 : 0 - occupied += is(current, row, col, Tile.Occupied, Direction.SE) ? 1 : 0 - occupied += is(current, row, col, Tile.Occupied, Direction.S) ? 1 : 0 - occupied += is(current, row, col, Tile.Occupied, Direction.SW) ? 1 : 0 - occupied += is(current, row, col, Tile.Occupied, Direction.W) ? 1 : 0 - occupied += is(current, row, col, Tile.Occupied, Direction.NW) ? 1 : 0 + occupied += isOccupied(current, row, col, Direction.N) + occupied += isOccupied(current, row, col, Direction.NE) + occupied += isOccupied(current, row, col, Direction.E) + occupied += isOccupied(current, row, col, Direction.SE) + occupied += isOccupied(current, row, col, Direction.S) + occupied += isOccupied(current, row, col, Direction.SW) + occupied += isOccupied(current, row, col, Direction.W) + occupied += isOccupied(current, row, col, Direction.NW) if (current[row][col] === Tile.Empty) { next[row][col] = occupied === 0 ? Tile.Occupied : current[row][col] } else if (current[row][col] === Tile.Occupied) { @@ -80,23 +123,65 @@ const iteration = (current: string[][]): string[][] => { } /** - * Run until equilibrium is reached + * Same as part one, but instead of considering just the eight immediately + * adjacent seats, consider the first seat in each of those eight directions. + * + * Also, it now takes five or more visible occupied seats for an occupied seat + * to become empty. */ -export const seatingSimulator = (world: string): string[][] => { - const start = world +export const part2rules = (current: string[][]): string[][] => { + const next = [] + for (let row = 0; row < current.length; row++) { + next[row] = [] as string[] + for (let col = 0; col < current[0].length; col++) { + let occupied = 0 + occupied += isOccupied(current, row, col, Direction.N, Direction.N) + occupied += isOccupied(current, row, col, Direction.NE, Direction.NE) + occupied += isOccupied(current, row, col, Direction.E, Direction.E) + occupied += isOccupied(current, row, col, Direction.SE, Direction.SE) + occupied += isOccupied(current, row, col, Direction.S, Direction.S) + occupied += isOccupied(current, row, col, Direction.SW, Direction.SW) + occupied += isOccupied(current, row, col, Direction.W, Direction.W) + occupied += isOccupied(current, row, col, Direction.NW, Direction.NW) + if (current[row][col] === Tile.Empty) { + next[row][col] = occupied === 0 ? Tile.Occupied : current[row][col] + } else if (current[row][col] === Tile.Occupied) { + next[row][col] = occupied >= 5 ? Tile.Empty : current[row][col] + } else { + next[row][col] = current[row][col] + } + } + } + return next +} + +export const occupied = (world: string[][]): number => + render(world) + .split('') + .filter((s) => s === '#').length + +export const loadString = (world: string): string[][] => + world .split('\n') .map((s) => s.trim().split('')) .filter((s) => s.length > 0) +/** + * Run until equilibrium is reached + */ +export const seatingSimulator = ( + world: string, + rules: (world: string[][]) => string[][], +): string[][] => { + const start = loadString(world) + let prevOccupied = -1 let occ = -1 let gen = start do { prevOccupied = occ - gen = iteration(gen) - occ = render(gen) - .split('') - .filter((s) => s === '#').length + gen = rules(gen) + occ = occupied(gen) } while (occ != prevOccupied) return gen } diff --git a/day11/solution.spec.ts b/day11/solution.spec.ts index 38d5e03..add295a 100644 --- a/day11/solution.spec.ts +++ b/day11/solution.spec.ts @@ -1,5 +1,5 @@ import { loader } from '../lib/loader' -import { render } from './seatingSimulator' +import { occupied, part1rules, part2rules } from './seatingSimulator' import { seatingSimulator } from './seatingSimulator' const load = loader(11) @@ -20,20 +20,22 @@ const input = load('input') describe('Day 11: Seating System', () => { describe('Part 1', () => { it('should solve the sample', () => { - const stable = seatingSimulator(sample) - expect( - render(stable) - .split('') - .filter((s) => s === '#').length, - ).toEqual(37) + const stable = seatingSimulator(sample, part1rules) + expect(occupied(stable)).toEqual(37) }) it('should solve the sample', () => { - const stable = seatingSimulator(input.join('\n')) - expect( - render(stable) - .split('') - .filter((s) => s === '#').length, - ).toEqual(2164) + const stable = seatingSimulator(input.join('\n'), part1rules) + expect(occupied(stable)).toEqual(2164) + }) + }) + describe('Part 2', () => { + it('should solve the sample', () => { + const stable = seatingSimulator(sample, part2rules) + expect(occupied(stable)).toEqual(26) + }) + it('should solve the sample', () => { + const stable = seatingSimulator(input.join('\n'), part2rules) + expect(occupied(stable)).toEqual(1974) }) }) }) From 1c138c506679ed667acc99738cd8cc769301be9a Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Sat, 12 Dec 2020 10:33:44 +0100 Subject: [PATCH 42/60] feat(day12): part 1 --- day12/input.txt | 768 +++++++++++++++++++++++++++++++++++++++++ day12/navigate.ts | 87 +++++ day12/solution.spec.ts | 26 ++ 3 files changed, 881 insertions(+) create mode 100644 day12/input.txt create mode 100644 day12/navigate.ts create mode 100644 day12/solution.spec.ts diff --git a/day12/input.txt b/day12/input.txt new file mode 100644 index 0000000..5931b41 --- /dev/null +++ b/day12/input.txt @@ -0,0 +1,768 @@ +S1 +F17 +S3 +F56 +W5 +F11 +N4 +F94 +W4 +S1 +L180 +E2 +F38 +S3 +F46 +L90 +N2 +S3 +W3 +L90 +E1 +L180 +F73 +L90 +E1 +N3 +R90 +S5 +E5 +L90 +W2 +F1 +E5 +R270 +W3 +S4 +W5 +F55 +E2 +L90 +W5 +L90 +E1 +L90 +F9 +W5 +F21 +E4 +F63 +E1 +F48 +N1 +F80 +E5 +L90 +N1 +E1 +S4 +R180 +F48 +F87 +N5 +W2 +F90 +S4 +E5 +F76 +F37 +R180 +E5 +F51 +S3 +R90 +F79 +F25 +L90 +W1 +F100 +S2 +E3 +L90 +N1 +W4 +F41 +S5 +L90 +W5 +L90 +W2 +S4 +W3 +F75 +L90 +F20 +E5 +N5 +R90 +F99 +N4 +N1 +L90 +N5 +N2 +E2 +S4 +F29 +L180 +N1 +W3 +L90 +W3 +L180 +F84 +F25 +E1 +S3 +R90 +F64 +L90 +E1 +F40 +N3 +R90 +N3 +F67 +F37 +L90 +F17 +E4 +F87 +N3 +W5 +S2 +R90 +E4 +N1 +W4 +F75 +E2 +F18 +R90 +F6 +S4 +F13 +E1 +L270 +F50 +W2 +R90 +W4 +S5 +R90 +F14 +L180 +N5 +L180 +F78 +E1 +S3 +R90 +E2 +R270 +E4 +S1 +L90 +L180 +F91 +W3 +W5 +F45 +N4 +F44 +L90 +N3 +L90 +S2 +L90 +F76 +W3 +R90 +F3 +W3 +F24 +L90 +F83 +W2 +F19 +S4 +L90 +N4 +E5 +L180 +N5 +W5 +F67 +S3 +R90 +E4 +F51 +L90 +E5 +L90 +F79 +E2 +N2 +W4 +E2 +L90 +F41 +E4 +N2 +L90 +N2 +L90 +N3 +F51 +F79 +N2 +W2 +N5 +W4 +F60 +N3 +R90 +W4 +S1 +F59 +W1 +F3 +N5 +L180 +N5 +F23 +N4 +E3 +R90 +F14 +W4 +F86 +L90 +N2 +S1 +W3 +R90 +N1 +F25 +L90 +F22 +E5 +F88 +L270 +F14 +N5 +F32 +N1 +F98 +S1 +W2 +E5 +L180 +E4 +S2 +F46 +L180 +W4 +F87 +E2 +F83 +R90 +S5 +F68 +E5 +F95 +N1 +F43 +E2 +F64 +S3 +F5 +S1 +W3 +L90 +E4 +L90 +F63 +S3 +F44 +N4 +R90 +F95 +S5 +W1 +N4 +W4 +F87 +W3 +N3 +L180 +W4 +R180 +N2 +E2 +N2 +L90 +W5 +R90 +W1 +F22 +L180 +N4 +W1 +S1 +R90 +N3 +R180 +S5 +W4 +R90 +E3 +S1 +E3 +N1 +L270 +F96 +E2 +N1 +F98 +W4 +L90 +W1 +W4 +R90 +W2 +S3 +F64 +S3 +F67 +N2 +R180 +S5 +F13 +N4 +F53 +W1 +N1 +L90 +F54 +S1 +E2 +F28 +R90 +W3 +L90 +E3 +N4 +F34 +R90 +F51 +L90 +F24 +R180 +W4 +N2 +F88 +F78 +S2 +E1 +N2 +L180 +F58 +E4 +R90 +N4 +L90 +N5 +R180 +N5 +R270 +W3 +F41 +S4 +F61 +R90 +F71 +S1 +F9 +R90 +F47 +W2 +N4 +L180 +W5 +F52 +L90 +N4 +F11 +W3 +L90 +W5 +N4 +F10 +S1 +F75 +S5 +L90 +S2 +F28 +L90 +F80 +E3 +R180 +E4 +F42 +E4 +F85 +N1 +W4 +R90 +E2 +F38 +R90 +F77 +F95 +L90 +S5 +F86 +R90 +N1 +E2 +R90 +N3 +F28 +R180 +N5 +F25 +E3 +F52 +N4 +E3 +N4 +E3 +F37 +L180 +N1 +E2 +L180 +E5 +F82 +N4 +F100 +N3 +E3 +L90 +W3 +S1 +R270 +E5 +W5 +R90 +F44 +F15 +R180 +S3 +L90 +E4 +F44 +R90 +N1 +E4 +N4 +F62 +R90 +S4 +L180 +S1 +F13 +E3 +F70 +L270 +F52 +L270 +F80 +L90 +F89 +N4 +F79 +W5 +F55 +R90 +F62 +E4 +F91 +R180 +E2 +F74 +R90 +F18 +L90 +E3 +N5 +E2 +R90 +W2 +R180 +N3 +F69 +W3 +R90 +F92 +E2 +F48 +N2 +L90 +S3 +F49 +E3 +L180 +F6 +R90 +S5 +F58 +F67 +E5 +S2 +L90 +W5 +F3 +S1 +F73 +W1 +E4 +R180 +N3 +E2 +F72 +L90 +S1 +F31 +W1 +F44 +L180 +F100 +W3 +N1 +W5 +L90 +S2 +N3 +R90 +W4 +S5 +F62 +E5 +F55 +L180 +W2 +L90 +E1 +F45 +S3 +W2 +F49 +N4 +L90 +E3 +N2 +R180 +E5 +N1 +N5 +E5 +R90 +W3 +F73 +E3 +F66 +L90 +S2 +E3 +F100 +S3 +W2 +S4 +W5 +R180 +E4 +S3 +S1 +W2 +R90 +F22 +R90 +F76 +L270 +S5 +F95 +L90 +N3 +F16 +R270 +S3 +N5 +F66 +R90 +F63 +W5 +F37 +N2 +L90 +W1 +F68 +R90 +F98 +E4 +S3 +R90 +E2 +S1 +F91 +E1 +F42 +E1 +F13 +S4 +F10 +R180 +E4 +R90 +N2 +W4 +L180 +N5 +R90 +N3 +F26 +R90 +F42 +L180 +E5 +S3 +L90 +S3 +E3 +F79 +R270 +E4 +F54 +N5 +W3 +F16 +W1 +S3 +R90 +F100 +S1 +W3 +N2 +E1 +S4 +F1 +R180 +F66 +W2 +R90 +W2 +F27 +E2 +F16 +R90 +S3 +F61 +E1 +F4 +L90 +N5 +F45 +L90 +N1 +L90 +F50 +W1 +R90 +N1 +F44 +S2 +F53 +S5 +F59 +E4 +S3 +E2 +N5 +E2 +L90 +E4 +L90 +N1 +L90 +N5 +F31 +R180 +N2 +F18 +E2 +F27 +L90 +F57 +R90 +F40 +R180 +E2 +F94 +S3 +E2 +S4 +E4 +R90 +L90 +E5 +N5 +E1 +N3 +F97 +S3 +F16 +E3 +W5 +F80 +S1 +W2 +S4 +F18 +N4 +E5 +R90 +N1 +F43 +N4 +E4 +N1 +E2 +W1 +F99 +W4 +F79 +F20 +E3 +F63 +W4 +F21 +E1 +F82 +E3 +R90 +F8 +N5 +W2 +L180 +W5 +F13 +S2 +L90 +N3 +R180 +N4 +F9 +L90 +F39 \ No newline at end of file diff --git a/day12/navigate.ts b/day12/navigate.ts new file mode 100644 index 0000000..355d575 --- /dev/null +++ b/day12/navigate.ts @@ -0,0 +1,87 @@ +export enum Direction { + N, + E, + S, + W, +} +type Position = { x: number; y: number } + +const instructionRx = /^(?N|S|E|W|L|R|F)(?[0-9]+)$/ + +const headingToDirection = (heading: number): Direction => { + switch (heading % 360) { + case 0: + return Direction.N + case 90: + case -270: + return Direction.E + case -90: + case 270: + return Direction.W + case 180: + case -180: + return Direction.S + default: + console.warn(`Unknown heading: ${heading % 360}`) + return Direction.N + } +} + +const move = (pos: Position) => (dir: Direction, n: number) => { + switch (dir) { + case Direction.N: + pos.y -= n + break + case Direction.S: + pos.y += n + break + case Direction.E: + pos.x += n + break + case Direction.W: + pos.x -= n + break + } +} + +export const navigate = ( + instructions: string[], + startDirection = 90, +): Position => { + const pos = { x: 0, y: 0 } + const mv = move(pos) + let heading = startDirection + + instructions.forEach((s) => { + const m = instructionRx.exec(s) + if (m === null) { + console.warn(`Invalid instruction: ${s}!`) + } + const { dir, amount } = m?.groups as any + const n = parseInt(amount, 10) + switch (dir) { + case 'N': + mv(Direction.N, n) + break + case 'S': + mv(Direction.S, n) + break + case 'E': + mv(Direction.E, n) + break + case 'W': + mv(Direction.W, n) + break + case 'L': + heading -= n + break + case 'R': + heading += n + break + case 'F': + mv(headingToDirection(heading), n) + break + } + }) + return pos +} diff --git a/day12/solution.spec.ts b/day12/solution.spec.ts new file mode 100644 index 0000000..dbab447 --- /dev/null +++ b/day12/solution.spec.ts @@ -0,0 +1,26 @@ +import { loader, loadString } from '../lib/loader' +import { navigate } from './navigate' + +const load = loader(12) +const input = load('input') + +describe('Day 12: Rain Risk', () => { + describe('Part 1', () => { + it('should solve the sample', () => { + const { x, y } = navigate( + loadString( + `F10 + N3 + F7 + R90 + F11`, + ), + ) + expect(Math.abs(x) + Math.abs(y)).toEqual(25) + }) + it('should solve', () => { + const { x, y } = navigate(input) + expect(Math.abs(x) + Math.abs(y)).toEqual(441) + }) + }) +}) From e31c0f050475b3cffddab6d24dd969807ff4a891 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Sat, 12 Dec 2020 11:21:34 +0100 Subject: [PATCH 43/60] feat(day12): part 2 --- day12/navigate.ts | 104 ++++++++++++++++++++++++++++++++++------- day12/solution.spec.ts | 40 ++++++++++------ 2 files changed, 115 insertions(+), 29 deletions(-) diff --git a/day12/navigate.ts b/day12/navigate.ts index 355d575..f0f7ee8 100644 --- a/day12/navigate.ts +++ b/day12/navigate.ts @@ -8,8 +8,13 @@ type Position = { x: number; y: number } const instructionRx = /^(?N|S|E|W|L|R|F)(?[0-9]+)$/ -const headingToDirection = (heading: number): Direction => { - switch (heading % 360) { +/** + * Translates the heading to a direction + * + * Note: Turn instructions are only given in 90 degree steps. + */ +const headingToDirection = (headingInDegrees: number): Direction => { + switch (headingInDegrees % 360) { case 0: return Direction.N case 90: @@ -22,11 +27,15 @@ const headingToDirection = (heading: number): Direction => { case -180: return Direction.S default: - console.warn(`Unknown heading: ${heading % 360}`) + console.warn(`Unknown heading: ${headingInDegrees % 360}`) return Direction.N } } +/** + * Move the given position in the given direction. + * pos is modified in place. + */ const move = (pos: Position) => (dir: Direction, n: number) => { switch (dir) { case Direction.N: @@ -44,14 +53,78 @@ const move = (pos: Position) => (dir: Direction, n: number) => { } } -export const navigate = ( +/** + * Convert degrees to radians + */ +const degreesToRadians = (deg: number): number => (deg * Math.PI) / 180 + +/** + * Rotate the given position for the given angle around 0,0 + * pos is modified in place. + */ +const rotate = (pos: Position) => (angleInDegrees: number) => { + const s = Math.sin(degreesToRadians(angleInDegrees)) + const c = Math.cos(degreesToRadians(angleInDegrees)) + + const newX = pos.x * c - pos.y * s + const newY = pos.x * s + pos.y * c + + pos.x = Math.round(newX) + pos.y = Math.round(newY) +} + +/** + * Implements the relative navigation where instructions are applied relative + * to the waypoint + */ +export const navigateRelative = ( + instructions: string[], + waypoint: Position, +): Position => { + const shipPosition = { x: 0, y: 0 } + navigate({ + instructions, + moveTo: move(waypoint), + changeDir: rotate(waypoint), + forward: (n: number) => { + shipPosition.x += waypoint.x * n + shipPosition.y += waypoint.y * n + }, + }) + return shipPosition +} + +/** + * Implements the absolute navigation where instructions are applied to the ship + */ +export const navigateAbsolute = ( instructions: string[], - startDirection = 90, + shipHeading = 90, ): Position => { - const pos = { x: 0, y: 0 } - const mv = move(pos) - let heading = startDirection + const shipPosition = { x: 0, y: 0 } + const moveShip = move(shipPosition) + navigate({ + instructions, + forward: (n: number) => moveShip(headingToDirection(shipHeading), n), + moveTo: moveShip, + changeDir: (n: number) => { + shipHeading += n + }, + }) + return shipPosition +} +const navigate = ({ + instructions, + moveTo, + changeDir, + forward, +}: { + instructions: string[] + moveTo: (dir: Direction, amount: number) => void + changeDir: (amount: number) => void + forward: (amount: number) => void +}): void => { instructions.forEach((s) => { const m = instructionRx.exec(s) if (m === null) { @@ -61,27 +134,26 @@ export const navigate = ( const n = parseInt(amount, 10) switch (dir) { case 'N': - mv(Direction.N, n) + moveTo(Direction.N, n) break case 'S': - mv(Direction.S, n) + moveTo(Direction.S, n) break case 'E': - mv(Direction.E, n) + moveTo(Direction.E, n) break case 'W': - mv(Direction.W, n) + moveTo(Direction.W, n) break case 'L': - heading -= n + changeDir(-n) break case 'R': - heading += n + changeDir(n) break case 'F': - mv(headingToDirection(heading), n) + forward(n) break } }) - return pos } diff --git a/day12/solution.spec.ts b/day12/solution.spec.ts index dbab447..4e6401c 100644 --- a/day12/solution.spec.ts +++ b/day12/solution.spec.ts @@ -1,26 +1,40 @@ import { loader, loadString } from '../lib/loader' -import { navigate } from './navigate' +import { navigateAbsolute, navigateRelative } from './navigate' const load = loader(12) +const sample = loadString( + `F10 + N3 + F7 + R90 + F11`, +) const input = load('input') +const manhatten = ( + { x: x1, y: y1 }: { x: number; y: number }, + { x: x2, y: y2 } = { x: 0, y: 0 }, +): number => Math.abs(x1 - x2) + Math.abs(y1 - y2) + describe('Day 12: Rain Risk', () => { describe('Part 1', () => { it('should solve the sample', () => { - const { x, y } = navigate( - loadString( - `F10 - N3 - F7 - R90 - F11`, - ), - ) - expect(Math.abs(x) + Math.abs(y)).toEqual(25) + const pos = navigateAbsolute(sample, 90) + expect(manhatten(pos)).toEqual(25) + }) + it('should solve', () => { + const pos = navigateAbsolute(input, 90) + expect(manhatten(pos)).toEqual(441) + }) + }) + describe('Part 2', () => { + it('should solve the sample', () => { + const pos = navigateRelative(sample, { x: 10, y: -1 }) + expect(manhatten(pos)).toEqual(286) }) it('should solve', () => { - const { x, y } = navigate(input) - expect(Math.abs(x) + Math.abs(y)).toEqual(441) + const pos = navigateRelative(input, { x: 10, y: -1 }) + expect(manhatten(pos)).toEqual(40014) }) }) }) From 45d587f2152d5179203bc99df287c6009cbd0f13 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Sun, 13 Dec 2020 11:09:32 +0100 Subject: [PATCH 44/60] feat(day13): part 1 --- day13/findShuttle.ts | 30 ++++++++++++++++++++++++++++++ day13/solution.spec.ts | 20 ++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 day13/findShuttle.ts create mode 100644 day13/solution.spec.ts diff --git a/day13/findShuttle.ts b/day13/findShuttle.ts new file mode 100644 index 0000000..acdf43e --- /dev/null +++ b/day13/findShuttle.ts @@ -0,0 +1,30 @@ +export const findShuttle = ( + notes: string[], +): { bus: number; waitTime: number } => { + // Read arrival time from notes + const arrivaleTime = parseInt(notes[0], 10) + // Read bus linses from notes + const buslines = notes[1] + .split(',') + .filter((s) => s !== 'x') + .map((s) => parseInt(s, 10)) + + // Calculate the next time of each bus arriving that is after the arrival time + const schedulAfterArrival = buslines.reduce( + (schedule, line) => ({ + ...schedule, + [line]: Math.ceil(arrivaleTime / line) * line, + }), + {} as Record, + ) + + // Sort by closes arrivale time and pick the bus that arrives first + const [bus, waitTime] = Object.entries(schedulAfterArrival).sort( + ([, timeA], [, timeB]) => timeA - timeB, + )[0] + + return { + waitTime: waitTime - arrivaleTime, + bus: parseInt(bus, 10), + } +} diff --git a/day13/solution.spec.ts b/day13/solution.spec.ts new file mode 100644 index 0000000..f2d9611 --- /dev/null +++ b/day13/solution.spec.ts @@ -0,0 +1,20 @@ +import { loadString } from '../lib/loader' +import { findShuttle } from './findShuttle' + +const sample = `939 +7,13,x,x,59,x,31,19` +const input = `1003240 +19,x,x,x,x,x,x,x,x,41,x,x,x,37,x,x,x,x,x,787,x,x,x,x,x,x,x,x,x,x,x,x,13,x,x,x,x,x,x,x,x,x,23,x,x,x,x,x,29,x,571,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,17` + +describe('Day 13: Shuttle Search', () => { + describe('Part 1', () => { + it('should solve the sample', () => { + const { bus, waitTime } = findShuttle(loadString(sample)) + expect(bus * waitTime).toEqual(295) + }) + it('should solve', () => { + const { bus, waitTime } = findShuttle(loadString(input)) + expect(bus * waitTime).toEqual(3997) + }) + }) +}) From 1ac378735f5c434f4e214dde169707f7df1d8d5d Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Sun, 13 Dec 2020 16:19:19 +0100 Subject: [PATCH 45/60] feat(day13): part 2 --- day13/findTime.ts | 24 ++++++++++++++++++++++++ day13/solution.spec.ts | 7 +++++++ 2 files changed, 31 insertions(+) create mode 100644 day13/findTime.ts diff --git a/day13/findTime.ts b/day13/findTime.ts new file mode 100644 index 0000000..ca8754c --- /dev/null +++ b/day13/findTime.ts @@ -0,0 +1,24 @@ +/** + * Find the time required by multiplying each bus with the time of the + * previous' bus iterations needed to arrive on the correct time + */ +export const findTime = (times: string): number => { + const slots = times.split(',').reduce((slots, k, n) => { + if (k === 'x') return slots + return [...slots, [parseInt(k, 10), n]] + }, [] as number[][]) + + let time = 0 + // start with the first bus' timeslot + let inc = slots[0][0] + // now go over all other buses + for (let bus = 1; bus < slots.length; bus++) { + // increment time until the next bus arrives at the desired time + while ((time + slots[bus][1]) % slots[bus][0] != 0) { + time += inc + } + // the next bus needs it's time multiplied by all previous busses + inc *= slots[bus][0] + } + return time +} diff --git a/day13/solution.spec.ts b/day13/solution.spec.ts index f2d9611..5c3f33b 100644 --- a/day13/solution.spec.ts +++ b/day13/solution.spec.ts @@ -1,5 +1,6 @@ import { loadString } from '../lib/loader' import { findShuttle } from './findShuttle' +import { findTime } from './findTime' const sample = `939 7,13,x,x,59,x,31,19` @@ -17,4 +18,10 @@ describe('Day 13: Shuttle Search', () => { expect(bus * waitTime).toEqual(3997) }) }) + describe('Part 2', () => { + it('should solve the sample', () => + expect(findTime(loadString(sample)[1])).toEqual(1068781)) + it('should solve', () => + expect(findTime(loadString(input)[1])).toEqual(500033211739354)) + }) }) From d923cca1a1f7267a30a3ec3f3182901179f29776 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Mon, 14 Dec 2020 14:57:36 +0100 Subject: [PATCH 46/60] feat(day14): part 1 --- day14/input.txt | 578 +++++++++++++++++++++++++++++++++++++++++ day14/run.ts | 34 +++ day14/solution.spec.ts | 25 ++ 3 files changed, 637 insertions(+) create mode 100644 day14/input.txt create mode 100644 day14/run.ts create mode 100644 day14/solution.spec.ts diff --git a/day14/input.txt b/day14/input.txt new file mode 100644 index 0000000..b9ca38f --- /dev/null +++ b/day14/input.txt @@ -0,0 +1,578 @@ +mask = 1101000X0110100X1X1X00001010XX00X0X0 +mem[48482] = 6450058 +mem[5309] = 2219920 +mem[27274] = 43286042 +mem[40233] = 504849 +mask = 1X1101XX1110X000101100XX001X000100X1 +mem[40763] = 53122377 +mem[24930] = 244 +mem[60497] = 16546 +mem[60898] = 654 +mask = 1011100X10111XX0011XX010001X1XX0X100 +mem[35453] = 378 +mem[445] = 17680 +mem[19816] = 1045213 +mem[496] = 222512 +mask = X00100X100100011001011000X0X0110000X +mem[25953] = 120906 +mem[42177] = 14177504 +mem[12302] = 31911950 +mem[33869] = 46903 +mask = 10011X1111100X1110001X0000110000XX01 +mem[43400] = 15586 +mem[5165] = 24662 +mem[3053] = 496403 +mask = 10110110X1X0011XX0110010X11011X0010X +mem[23273] = 359 +mem[8290] = 1906218 +mem[4777] = 33822 +mem[24904] = 92027 +mem[55979] = 348 +mask = X0X1100010X1XX010X0000X00001XX100000 +mem[63411] = 198864361 +mem[2323] = 12235447 +mem[53128] = 3559 +mem[37957] = 978071 +mem[12837] = 57030 +mem[18230] = 7330 +mask = 11X100X111X0001101X01101X11XX0110001 +mem[20551] = 95829554 +mem[52592] = 3255 +mem[14690] = 66824 +mem[53729] = 16600 +mem[14246] = 48015 +mem[49654] = 13036614 +mem[12199] = 78275448 +mask = 100XX00100X0X011001X1010010110X00X11 +mem[11978] = 57478 +mem[23642] = 1593 +mem[26097] = 6120 +mem[54294] = 1426 +mem[25730] = 2662370 +mem[48051] = 283445930 +mask = 0X01111X111X00X11010000010XX001X000X +mem[48807] = 1811127 +mem[54732] = 130682 +mem[14556] = 127239 +mem[8434] = 329378888 +mem[65311] = 30415 +mem[38753] = 129645 +mask = 1101X1X11110X011X0X000XXX00010000110 +mem[58126] = 5447027 +mem[61916] = 262525830 +mem[29247] = 53096 +mask = X010011001100001101111001000X0X0X000 +mem[27274] = 20355 +mem[24280] = 94406194 +mem[46969] = 32599 +mask = 10110110111XXXXX1011X11X111010101XX1 +mem[13208] = 1476 +mem[17525] = 174267 +mem[40650] = 47095 +mem[6880] = 23668444 +mem[18597] = 210524 +mem[61423] = 11469 +mem[28797] = 72808658 +mask = 1101X11X11X001111X101XX001X100X00000 +mem[10402] = 382156 +mem[11615] = 91849 +mem[55387] = 38274 +mem[41608] = 99166858 +mask = 10XXXX1X111000X1101X0X10110010101010 +mem[64410] = 16272 +mem[53605] = 39 +mem[43920] = 231262355 +mem[24494] = 101085 +mem[2266] = 7434 +mem[6405] = 490 +mem[20768] = 56259 +mask = 1101111X11100X11100001X00X00100000X1 +mem[12148] = 1542 +mem[14674] = 32572259 +mem[13208] = 1048025 +mem[10573] = 2522 +mem[25144] = 65748456 +mask = 1X0X1X01X11000XX0X10101100X111X01000 +mem[216] = 3249 +mem[61137] = 125226363 +mem[20373] = 8025 +mem[10889] = 447307190 +mask = 1X01111111100X1110X00110XX1110XX1X0X +mem[43138] = 1515 +mem[59301] = 99565475 +mem[24915] = 103737871 +mem[20768] = 514918 +mem[11898] = 685393 +mem[36252] = 2583474 +mem[5165] = 129314 +mask = 1011100011X1X00XX1X00X1XX01X01111011 +mem[34243] = 6266385 +mem[32449] = 3199 +mem[37594] = 12713 +mem[33859] = 85810 +mem[61637] = 4581168 +mem[40941] = 2511 +mask = 10011XX1XX1X0X011X0100110011110X0000 +mem[11494] = 359697 +mem[45551] = 128326843 +mem[12702] = 427072 +mask = 1X01X0X111100X110010001X001111X000X0 +mem[19264] = 1388 +mem[14556] = 2634 +mem[56860] = 913 +mem[46144] = 410717 +mem[26110] = 286330629 +mem[13224] = 70224078 +mem[51706] = 1781457 +mask = 11X10011111X0X11X0X00XX100XX01000011 +mem[1827] = 352974 +mem[53395] = 1253519 +mem[5593] = 204616 +mem[24059] = 9680329 +mem[51280] = 893 +mem[18437] = 1179 +mask = 10110X101110X001001111X01X1110011000 +mem[27171] = 219265 +mem[47619] = 677 +mem[36434] = 924 +mem[10402] = 23151360 +mask = 1001X1111110001X10000X0X001110101101 +mem[19629] = 665 +mem[52439] = 250 +mem[8361] = 28482 +mask = 101110X110X0X0100110X0110X1010011X11 +mem[20558] = 558 +mem[26949] = 7777 +mem[22160] = 171308 +mem[15631] = 328260 +mem[45856] = 230942 +mask = 110100111100001X101X010000110X0X0010 +mem[30840] = 683 +mem[41251] = 652 +mem[10584] = 103692712 +mem[5860] = 3950330 +mem[61507] = 647961 +mem[43181] = 13247 +mask = X0110110X11011X01011X10001X010111X00 +mem[19238] = 39433935 +mem[19155] = 2409 +mem[16137] = 5550 +mask = 101X1XX0111XX01110100010X00110X01100 +mem[43920] = 947024008 +mem[2335] = 2498 +mem[15363] = 65058906 +mask = 110100X1X11X0011001X01X1000001010000 +mem[31189] = 13626 +mem[41212] = 161 +mem[53454] = 12060062 +mem[47394] = 8828 +mask = 1011X0X011100011X01X0X101000X1110010 +mem[64452] = 5096 +mem[4245] = 745302 +mem[46144] = 3353 +mem[25610] = 1258 +mask = 0101001XX110001101X00X10X1X001010X01 +mem[1677] = 23846073 +mem[50713] = 1754903 +mem[34243] = 619756 +mask = X10110111X1101110010001111111X0X001X +mem[20746] = 11327 +mem[60677] = 55286634 +mem[18904] = 33122 +mem[42335] = 4994 +mask = X101100X1X10001X0X100011X011X0X01001 +mem[32832] = 20230 +mem[54205] = 1405755 +mem[27010] = 1483 +mem[25730] = 416967 +mask = 11110X11111X0X11000001X11XX0X0X00101 +mem[20547] = 993 +mem[32667] = 3520 +mask = 11010XXX011XX000101X1X0011X000001001 +mem[24634] = 245639 +mem[59394] = 184364 +mem[60948] = 20401794 +mem[9342] = 60279080 +mem[17142] = 10401929 +mem[40232] = 3268 +mask = XX011111111000X110XX00101X1X10100000 +mem[6405] = 2064 +mem[31624] = 208587070 +mem[2258] = 3965844 +mem[14742] = 6124264 +mem[2985] = 1824 +mem[4950] = 3019502 +mem[8036] = 157 +mask = 1X01001X11X00011X01001X01011XX01101X +mem[41340] = 163017 +mem[46907] = 1047 +mem[2512] = 1340 +mem[33913] = 20303 +mem[58546] = 153629023 +mem[19536] = 109607 +mask = X01X0X10X1100001X01110101X0X1X00101X +mem[25394] = 131964 +mem[18030] = 99092 +mem[19264] = 12572 +mask = X011X0X110101010011000X00010XX111000 +mem[12088] = 165 +mem[46867] = 6359415 +mem[52891] = 29571 +mem[37957] = 1880 +mem[38886] = 32297 +mem[47674] = 40454 +mask = 1010XX1011100011X01000X1X0111X011010 +mem[62632] = 184293833 +mem[43181] = 6802 +mem[29534] = 17997 +mem[55058] = 527832513 +mem[17560] = 876465884 +mem[33007] = 195444229 +mask = 111100X11X100X11X0100100X0X0X1000000 +mem[22371] = 620962 +mem[27171] = 13951 +mem[23941] = 285120 +mem[53371] = 2727 +mask = 101110011X111011X1000000X101X1X01X00 +mem[57437] = 4447669 +mem[62084] = 14810 +mem[20380] = 2 +mask = X01X100X10X11001X00001X00001X0001111 +mem[10604] = 29217 +mem[40103] = 20019 +mem[5593] = 1282 +mask = XX0100111X100011011X100XX11101X10111 +mem[29655] = 188308404 +mem[16108] = 987052 +mem[27684] = 1845758 +mem[8627] = 30072056 +mem[24904] = 28977792 +mem[24100] = 11388269 +mask = 11X1100XX01X001101100111110000100011 +mem[9003] = 63644817 +mem[23905] = 249772171 +mem[41608] = 566869 +mask = X001X0011110X011X0101X10001010000X1X +mem[19837] = 1474559 +mem[6082] = 213612431 +mem[25394] = 746122 +mask = 101110X1111X101X01100000100101111X10 +mem[41906] = 2538917 +mem[43592] = 738 +mem[38721] = 69444 +mem[24036] = 6469 +mask = 0011100010X111X100001001XX000X000101 +mem[32354] = 709541 +mem[18383] = 3835385 +mem[1313] = 1178709 +mem[30236] = 6347401 +mask = 11011X001X10X0X1X0000100001010000000 +mem[64686] = 4029603 +mem[37187] = 269 +mem[41728] = 15291311 +mem[703] = 176262655 +mem[23732] = 473740 +mem[4238] = 2073061 +mask = 1101011111101X1X0010110X0XX110001X10 +mem[24443] = 487215 +mem[44567] = 898248 +mem[41636] = 11946 +mem[21254] = 1162908 +mask = X01110X11X1X101X01100X0000X01011X101 +mem[41555] = 13384162 +mem[51011] = 12307 +mem[54861] = 435 +mem[61876] = 10233 +mem[3849] = 14042 +mem[25473] = 273 +mem[10402] = 17072 +mask = 100100101110XX110X100110X010000XXXX1 +mem[13744] = 663718668 +mem[18696] = 361798 +mem[21207] = 851454 +mem[21194] = 21025 +mask = 1XX101XXX11X000X10111110111000X1X001 +mem[48482] = 107005 +mem[26156] = 15617 +mem[49747] = 65227757 +mem[52440] = 112190 +mem[36683] = 26159 +mem[19486] = 3181 +mask = X011X0X01XX1000101XX0010X11001110010 +mem[4510] = 7353062 +mem[10923] = 25067923 +mem[16714] = 173017 +mem[41162] = 12385087 +mem[25346] = 1388660 +mask = X10110011110001100101111001X000X1X01 +mem[27395] = 52406 +mem[63935] = 70016372 +mem[61748] = 1598 +mask = 1101101XX111011X001X00001111100X0111 +mem[2512] = 629921058 +mem[48026] = 247446319 +mem[48328] = 2018 +mem[9614] = 49871 +mem[25296] = 53536568 +mask = 10X110X0101X10011X00X010001XX0101011 +mem[62912] = 108898 +mem[22160] = 5738253 +mem[37655] = 5684656 +mem[292] = 103716917 +mem[40727] = 6480899 +mem[43121] = 2495962 +mem[8256] = 9752 +mask = 111X011111100000XX110110110X1X0X10X0 +mem[42306] = 3814 +mem[22173] = 104438687 +mem[60145] = 51698 +mem[44805] = 14155 +mem[23905] = 15867565 +mask = 1X01111X1X1001X110X000XX0000X0000010 +mem[7284] = 513301 +mem[14240] = 9298 +mem[9803] = 254768 +mem[36226] = 722 +mask = 10110111X1101000X011101001X10010101X +mem[19105] = 1399632 +mem[40477] = 14030402 +mem[9180] = 258090132 +mem[2864] = 1722022 +mem[6880] = 31 +mask = 1011100X1X11X001X100X0100X100X1X0X10 +mem[3335] = 303249475 +mem[33869] = 89890 +mem[40724] = 3168 +mem[44588] = 3236692 +mem[43374] = 875137580 +mem[39986] = 327100054 +mem[16676] = 47668 +mask = 1011X00110111100011XX00X00X11111X001 +mem[46881] = 2251035 +mem[31188] = 860796 +mem[15313] = 88528 +mem[33666] = 645 +mem[9205] = 45363830 +mem[57565] = 604 +mem[13224] = 1342 +mask = 10X10X101X10011X101100X101X01X001000 +mem[25292] = 3155 +mem[18230] = 27276287 +mem[16051] = 270672 +mask = 1XX10001101X0011011011000101X11X0011 +mem[46144] = 8381238 +mem[22497] = 2356142 +mem[8433] = 70526 +mem[44424] = 8986 +mem[18442] = 508814 +mask = 101110011X1110X10XX000000X01X1X111XX +mem[20373] = 1622495 +mem[44697] = 127381 +mem[20688] = 4500 +mem[16805] = 923777 +mem[32947] = 8080048 +mask = 0001X101XX10011110000X00000110X00000 +mem[31189] = 51277 +mem[1279] = 7010 +mem[40666] = 1361051 +mem[20337] = 6622 +mem[44409] = 245840 +mem[2587] = 231888105 +mask = 100X00111011XXXXX0X0100111X000010110 +mem[38644] = 122518 +mem[14690] = 853513 +mem[27280] = 499865495 +mask = 1XX1001011110110X011111011101XX0X100 +mem[5253] = 104635924 +mem[9220] = 469551991 +mem[54123] = 603 +mask = 1X01111111100X11101001X110X110100101 +mem[28857] = 4958 +mem[26793] = 43481 +mem[26110] = 2002 +mem[13670] = 737550271 +mem[48748] = 2175 +mem[15379] = 956329 +mask = X001111X101X01111010000100100000100X +mem[5038] = 1896 +mem[1219] = 1590 +mem[2335] = 6839 +mem[44175] = 3246581 +mem[10128] = 861384 +mask = 10X100X1001X0X11011010100100X11000X1 +mem[25953] = 500230911 +mem[56860] = 3606219 +mem[3909] = 4193582 +mem[20077] = 13280564 +mem[42329] = 2622 +mem[19629] = 2920217 +mask = 1000X0111XX1XX11001000011X10110X0110 +mem[65286] = 10087505 +mem[39772] = 5587787 +mem[49314] = 25559 +mem[27912] = 135405924 +mem[46907] = 7910 +mem[36657] = 1549461 +mem[37088] = 74 +mask = 1101001XXX100X1100X0000010110010110X +mem[26128] = 3098182 +mem[19238] = 6294862 +mem[35146] = 4761321 +mem[13782] = 407506 +mem[57435] = 1986 +mem[56396] = 1173362 +mask = 10X110011X11100X01101010X0X0X0010101 +mem[26478] = 5717 +mem[7980] = 895287 +mem[26719] = 254026 +mem[58541] = 444 +mem[43236] = 1222225 +mask = 10101010111100XX101000010X01X0101101 +mem[19246] = 1542 +mem[30987] = 1317750 +mem[15786] = 214473235 +mem[33835] = 989447 +mem[49063] = 63501903 +mem[50294] = 351534 +mem[4146] = 12924485 +mask = 1101100X11X00X1100X00X1X00011000X00X +mem[49673] = 11520693 +mem[8936] = 422236363 +mem[22275] = 116474 +mask = 101110011X11X011000X0XX00X000X011X01 +mem[44344] = 518186197 +mem[20820] = 2429569 +mem[25541] = 30403114 +mask = 1X0X1011111X0111X0100111001111X00X10 +mem[47674] = 15040841 +mem[54205] = 9684 +mem[52058] = 38432 +mem[20458] = 522505115 +mem[16470] = 96407696 +mask = 101110001011X0010100X01011X0001000X0 +mem[2903] = 9215 +mem[24100] = 10412 +mem[65308] = 3449 +mask = 11110100011X00001011011X111101XX0001 +mem[1383] = 20524 +mem[43138] = 1853 +mem[53] = 13474143 +mem[53737] = 139742 +mem[36626] = 111978547 +mem[6473] = 296847 +mask = X00100X11010X01X011001XX101011001X00 +mem[14690] = 2176 +mem[49976] = 138885734 +mem[63369] = 58 +mem[24904] = 127774567 +mem[45788] = 935 +mem[15363] = 3333 +mask = 100100111X100011001X1011010111000XX0 +mem[44478] = 18487 +mem[25541] = 10395 +mem[2258] = 208737 +mem[33632] = 355267 +mask = 1X01001X1XX00111011000101XX10X01X100 +mem[46117] = 129267954 +mem[18953] = 496 +mem[3156] = 23246 +mem[22307] = 471295 +mem[56163] = 6733185 +mem[1324] = 2074915 +mask = 1X0100X1XX1000110X1001100001X10XX0X0 +mem[33913] = 191232 +mem[11074] = 586 +mem[6405] = 52666 +mask = X10X10X01110001X0110X011100100XX1001 +mem[2512] = 177970 +mem[58654] = 2392973 +mem[4166] = 3276 +mem[39753] = 1233 +mem[61980] = 474314617 +mem[37355] = 58269 +mask = X011100X1111X01100101000000X00110X1X +mem[33118] = 5010 +mem[4760] = 111160 +mem[37689] = 823166 +mem[15678] = 1634 +mask = XX0101X111100111100000X0X0X0110X1XX1 +mem[17229] = 4665 +mem[22930] = 1040260 +mem[1324] = 260 +mem[31615] = 5434357 +mem[545] = 215622 +mask = 10110111X11X000110X10100110X0XX01110 +mem[44567] = 220705 +mem[53112] = 1089 +mask = X0010X101X1X11110X1X0110X0X1X0000000 +mem[7] = 1698581 +mem[53112] = 112679 +mem[63935] = 6201 +mask = 1010011011X1111X1011001000X010001X1X +mem[27421] = 22548 +mem[20688] = 29314044 +mem[35943] = 66340108 +mem[17023] = 115252 +mem[47844] = 1957 +mem[20801] = 243380907 +mem[58453] = 1786 +mask = 10X11110X0XX0101X01010101101000X001X +mem[56724] = 25322561 +mem[23838] = 128622093 +mem[14602] = 1871 +mem[9600] = 482868337 +mem[13919] = 427123809 +mask = 110100010110X011X11X11X001XX1X100010 +mem[26083] = 962249 +mem[48067] = 107 +mem[6405] = 979668 +mask = 10110X10111X0110101X010X110010X0000X +mem[27181] = 581 +mem[1935] = 1700145 +mem[31816] = 7821892 +mem[62084] = 16529134 +mem[63391] = 3109 +mem[64545] = 30527 +mask = X101X11X11100111100XX0000X0X101X1001 +mem[8381] = 33407838 +mem[40566] = 15796331 +mem[18597] = 68546 +mem[25473] = 7358888 +mem[41562] = 4109 +mem[8797] = 4761 +mask = 1101001111100011X110X0010001X1X10001 +mem[48089] = 50505 +mem[8627] = 111289788 +mem[49063] = 7497 +mask = 10X1X011XX10X01X0110110X0X0101100011 +mem[6133] = 237 +mem[65302] = 776 +mem[24930] = 240012 +mem[49747] = 1455 +mem[25610] = 77345999 +mem[65463] = 830 +mem[18804] = 409066 +mask = 10X11001111X1001000X01XX11111101XX11 +mem[52439] = 54286 +mem[27158] = 334127093 +mem[50444] = 1667 +mem[1037] = 9375588 +mem[15887] = 95826 +mem[18383] = 4398280 +mask = XX01101111X101110X1X1X010101100001X0 +mem[38753] = 1944309 +mem[56903] = 103577 +mem[52840] = 85 +mem[47810] = 954770 +mem[31815] = 1660528 +mask = 101X011X1X11111110110000001010000X11 +mem[59096] = 180976584 +mem[64686] = 16261 +mem[31497] = 671389398 +mem[23216] = 4065503 +mem[55058] = 1248965 +mem[56396] = 3400500 +mask = 1X011011111001X1X01X000X10X1001X1010 +mem[20173] = 4586 +mem[61916] = 424482839 +mem[63391] = 6915265 \ No newline at end of file diff --git a/day14/run.ts b/day14/run.ts new file mode 100644 index 0000000..397c451 --- /dev/null +++ b/day14/run.ts @@ -0,0 +1,34 @@ +/** + * Returns the value with the given mask applied + */ +const mask = (value: number, mask: string): number => { + // Convert to 36 bit long binary string + const valueAsBinary = [...value.toString(2).padStart(36, '0')] + for (let i = 0; i < 36; i++) { + const maskVal = mask[mask.length - i - 1] + if (maskVal !== 'X') { + // Overwrite value bit with mask bit + valueAsBinary[valueAsBinary.length - i - 1] = maskVal + } + } + return parseInt(valueAsBinary.join(''), 2) +} + +export const run = (program: string[]): Record => + program.reduce( + (context, instruction) => { + const [cmd, value] = instruction.split(' = ') + if (cmd === 'mask') { + context.mask = value + } else { + const addr = parseInt(/mem\[([0-9]+)\]/.exec(cmd)?.[1] as string, 10) + const v = parseInt(value, 10) + context.memory[addr] = mask(v, context.mask) + } + return context + }, + { + memory: {} as Record, + mask: 'X'.repeat(36), + }, + ).memory diff --git a/day14/solution.spec.ts b/day14/solution.spec.ts new file mode 100644 index 0000000..c569f89 --- /dev/null +++ b/day14/solution.spec.ts @@ -0,0 +1,25 @@ +import { loader, loadString } from '../lib/loader' +import { run } from './run' + +const sample = `mask = XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X +mem[8] = 11 +mem[7] = 101 +mem[8] = 0` + +const load = loader(14) +const input = load('input') + +describe('Day 14: Docking Data', () => { + describe('Part 1', () => { + it('should solve the sample', () => { + const mem = run(loadString(sample)) + expect(mem[8] + mem[7]).toEqual(165) + }) + it('should solve the sample', () => { + const mem = run(input) + expect(Object.values(mem).reduce((sum, v) => v + sum, 0)).toEqual( + 15403588588538, + ) + }) + }) +}) From b590b76988178ce353ac4c865235ed5f36419077 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Tue, 15 Dec 2020 09:31:29 +0100 Subject: [PATCH 47/60] feat(day15): part 1 --- day15/memoryGame.ts | 29 +++++++++++++++++++++++++++++ day15/solution.spec.ts | 24 ++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 day15/memoryGame.ts create mode 100644 day15/solution.spec.ts diff --git a/day15/memoryGame.ts b/day15/memoryGame.ts new file mode 100644 index 0000000..fd42f40 --- /dev/null +++ b/day15/memoryGame.ts @@ -0,0 +1,29 @@ +export const memoryGame = (numbers: number[], iterations: number): number => { + const spokenTurn = {} as Record + let speak + let lastSpoken + for (let turn = 0; turn < iterations; turn++) { + // Carry over what was said in the last turn + lastSpoken = speak + // They begin by taking turns reading from a list of starting numbers + if (turn < numbers.length) { + speak = numbers[turn] + } else { + // Now, consider the last number spoken + + const lastSpokenTurn = spokenTurn[lastSpoken as number] as + | number + | undefined + if (lastSpokenTurn === undefined) { + // If it is the first time the number is spoken return 0 + speak = 0 + } else { + // Otherwise, announce how many turns apart the number is from when it was previously spoken. + speak = turn - lastSpokenTurn + } + } + // Record what was said in the last turn + spokenTurn[lastSpoken ?? -1] = turn + } + return speak ?? -1 +} diff --git a/day15/solution.spec.ts b/day15/solution.spec.ts new file mode 100644 index 0000000..7339127 --- /dev/null +++ b/day15/solution.spec.ts @@ -0,0 +1,24 @@ +import { memoryGame } from './memoryGame' + +describe('Day 15: Rambunctious Recitation', () => { + describe('Part 1', () => { + const numbers = [0, 3, 6] + it.each([ + [1, 0], + [2, 3], + [3, 6], + [4, 0], + [5, 3], + [6, 3], + [7, 1], + [8, 0], + [9, 4], + [10, 0], + [2020, 436], + ])('the spoken number in turn %d should be %d', (turn, expected) => + expect(memoryGame(numbers, turn)).toEqual(expected), + ) + it('should solve', () => + expect(memoryGame([0, 5, 4, 1, 10, 14, 7], 2020)).toEqual(203)) + }) +}) From cb1190d0cd89507b9f2bc681aedbafc18242973b Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Tue, 15 Dec 2020 09:48:30 +0100 Subject: [PATCH 48/60] feat(day15): part 2 --- day15/memoryGame.ts | 1 - day15/solution.spec.ts | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/day15/memoryGame.ts b/day15/memoryGame.ts index fd42f40..0f8b3dd 100644 --- a/day15/memoryGame.ts +++ b/day15/memoryGame.ts @@ -10,7 +10,6 @@ export const memoryGame = (numbers: number[], iterations: number): number => { speak = numbers[turn] } else { // Now, consider the last number spoken - const lastSpokenTurn = spokenTurn[lastSpoken as number] as | number | undefined diff --git a/day15/solution.spec.ts b/day15/solution.spec.ts index 7339127..a3a7e14 100644 --- a/day15/solution.spec.ts +++ b/day15/solution.spec.ts @@ -21,4 +21,9 @@ describe('Day 15: Rambunctious Recitation', () => { it('should solve', () => expect(memoryGame([0, 5, 4, 1, 10, 14, 7], 2020)).toEqual(203)) }) + describe('Part 2', () => { + // This takes 5 minutes + it.skip('should solve', () => + expect(memoryGame([0, 5, 4, 1, 10, 14, 7], 2020)).toEqual(9007186)) + }) }) From 745850319810b91bc76ed1bdfae6be0897054c3f Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Wed, 16 Dec 2020 17:22:19 +0100 Subject: [PATCH 49/60] feat(day16): part 1 and started part 2 --- day16/isValidTicket.ts | 44 ++++++++ day16/rules.txt | 20 ++++ day16/solution.spec.ts | 98 +++++++++++++++++ day16/solveFields.ts | 66 ++++++++++++ day16/test.ts | 14 +++ day16/tickets.txt | 236 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 478 insertions(+) create mode 100644 day16/isValidTicket.ts create mode 100644 day16/rules.txt create mode 100644 day16/solution.spec.ts create mode 100644 day16/solveFields.ts create mode 100644 day16/test.ts create mode 100644 day16/tickets.txt diff --git a/day16/isValidTicket.ts b/day16/isValidTicket.ts new file mode 100644 index 0000000..0ca911a --- /dev/null +++ b/day16/isValidTicket.ts @@ -0,0 +1,44 @@ +export type Rules = Record + +export const parseRules = (rules: string[]): Rules => + rules.reduce((rules, rule) => { + const m = /^(?[^:]+): (?[0-9]+)-(?[0-9]+) or (?[0-9]+)-(?[0-9]+)$/.exec( + rule, + ) + if (m === null) { + console.error(`Could not parse rule ${rule}!`) + return rules + } + return { + ...rules, + [m.groups?.class as string]: [ + [ + parseInt(m.groups?.from1 as string, 10), + parseInt(m.groups?.to1 as string, 10), + ] as [number, number], + [ + parseInt(m.groups?.from2 as string, 10), + parseInt(m.groups?.to2 as string, 10), + ] as [number, number], + ], + } + }, {} as Rules) + +/** + * Returns the invalid numbers in a ticket + */ +export const findInvalidNumbers = (rules: Rules) => ( + ticket: number[], +): number[] => + ticket.filter((n) => { + const range = Object.values(rules).find( + (ruleRanges) => + ruleRanges.find(([from, to]) => { + if (n < from) return false + if (n > to) return false + return true + }) !== undefined, + ) + const isInRange = range !== undefined + return !isInRange + }) diff --git a/day16/rules.txt b/day16/rules.txt new file mode 100644 index 0000000..a503013 --- /dev/null +++ b/day16/rules.txt @@ -0,0 +1,20 @@ +departure location: 26-715 or 727-972 +departure station: 45-164 or 175-960 +departure platform: 43-247 or 270-972 +departure track: 25-306 or 330-949 +departure date: 26-635 or 660-961 +departure time: 42-773 or 793-961 +arrival location: 28-928 or 943-952 +arrival station: 36-593 or 613-966 +arrival platform: 33-280 or 297-951 +arrival track: 44-358 or 371-974 +class: 39-815 or 839-955 +duration: 39-573 or 589-959 +price: 49-846 or 865-962 +route: 30-913 or 924-954 +row: 29-865 or 890-965 +seat: 44-667 or 683-969 +train: 32-473 or 482-969 +type: 40-424 or 432-953 +wagon: 49-156 or 164-960 +zone: 34-521 or 534-971 \ No newline at end of file diff --git a/day16/solution.spec.ts b/day16/solution.spec.ts new file mode 100644 index 0000000..207282b --- /dev/null +++ b/day16/solution.spec.ts @@ -0,0 +1,98 @@ +import { loader, loadString } from '../lib/loader' +import { findInvalidNumbers, parseRules } from './isValidTicket' +import { solveFields } from './solveFields' + +const sampleRules = loadString(`class: 1-3 or 5-7 +row: 6-11 or 33-44 +seat: 13-40 or 45-50`) + +const load = loader(16) +const rules = load('rules') +const tickets = load('tickets') + +describe('Day 16: Ticket Translation', () => { + describe('parseRules', () => { + it('should parse the rules', () => + expect(parseRules(sampleRules)).toEqual({ + class: [ + [1, 3], + [5, 7], + ], + row: [ + [6, 11], + [33, 44], + ], + seat: [ + [13, 40], + [45, 50], + ], + })) + }) + describe('findInvalidNumbers', () => { + it.each([ + [[7, 1, 14], []], + [[7, 3, 47], []], + [[40, 4, 50], [4]], + [[55, 2, 20], [55]], + [[38, 6, 12], [12]], + ])('the ticket %s invalid numbers are %s', (ticket, invalidNumbers) => + expect(findInvalidNumbers(parseRules(sampleRules))(ticket)).toEqual( + invalidNumbers, + ), + ) + }) + describe('Part 1', () => { + const ticketScanningErrorRate = ( + rules: string[], + tickets: string[], + ): number => + tickets + .map((s) => s.split(',').map((s) => parseInt(s, 10))) + .map(findInvalidNumbers(parseRules(rules))) + .flat() + .reduce((sum, n) => n + sum, 0) + + it('should solve the sample', () => + expect( + ticketScanningErrorRate( + sampleRules, + loadString(`7,3,47 + 40,4,50 + 55,2,20 + 38,6,12`), + ), + ).toEqual(71)) + it('should solve', () => + expect(ticketScanningErrorRate(rules, tickets)).toEqual(21081)) + }) + describe('Part 2', () => { + it('should solve the sample', () => { + const step2sampleTickets = loadString(` + 3,9,18 + 15,1,5 + 5,14,9`).map((s) => s.split(',').map((s) => parseInt(s, 10))) + const sample2Rules = parseRules( + loadString(`class: 0-1 or 4-19 + row: 0-5 or 8-19 + seat: 0-13 or 16-19`), + ) + const validTickets = step2sampleTickets.filter( + (t) => findInvalidNumbers(sample2Rules)(t).length === 0, + ) + expect(validTickets).toHaveLength(3) + + expect(solveFields(sample2Rules)(step2sampleTickets)).toEqual([ + 'row', + 'class', + 'seat', + ]) + }) + it.skip('should solve', () => { + expect( + solveFields(parseRules(rules))( + tickets.map((s) => s.split(',').map((s) => parseInt(s, 10))), + ), + ).toEqual(['row', 'class', 'seat']) + }) + }) +}) diff --git a/day16/solveFields.ts b/day16/solveFields.ts new file mode 100644 index 0000000..5b0df8e --- /dev/null +++ b/day16/solveFields.ts @@ -0,0 +1,66 @@ +import { Rules } from './isValidTicket' + +const combine = (categories: T[]) => { + const combinations: T[][] = [] + const g = (categories: T[], parents: T[] = []) => { + if (categories.length === 0) { + combinations.push(parents) + return + } + categories.forEach((cat) => { + g( + categories.filter((c) => [...parents, cat].includes(c) === false), + [...parents, cat], + ) + }) + } + g(categories) + return combinations +} + +export const solveFields = (rules: Rules, filter?: string) => ( + validTickets: number[][], +): string[] => { + const allCategories = Object.keys(rules) + const filteredCategories = allCategories.filter((s) => + filter === undefined ? true : s.startsWith(filter), + ) + const combinations = combine(filteredCategories) + const missing = allCategories.length - filteredCategories.length + + for (let i = 0; i <= missing; i++) { + for (const c of combinations) { + let validCombination = [] as string[] + ;(() => { + const ranges = [ + ...'-' + .repeat(i) + .split('') + .map(() => [ + [0, Number.MAX_SAFE_INTEGER], + [0, Number.MAX_SAFE_INTEGER], + ]), + ...c.map((c) => rules[c]), + ...'-' + .repeat(missing - i) + .split('') + .map(() => [ + [0, Number.MAX_SAFE_INTEGER], + [0, Number.MAX_SAFE_INTEGER], + ]), + ] + for (const t of validTickets) { + for (let l = 0; l < t.length; l++) { + const n = t[l] + const [[from1, to1], [from2, to2]] = ranges[l] + const valid = (n >= from1 && n <= to1) || (n >= from2 && n <= to2) + if (!valid) return + } + } + validCombination = c + })() + if (validCombination.length > 0) return validCombination + } + } + return [] +} diff --git a/day16/test.ts b/day16/test.ts new file mode 100644 index 0000000..42b6e25 --- /dev/null +++ b/day16/test.ts @@ -0,0 +1,14 @@ +import { loader } from '../lib/loader' +import { parseRules } from './isValidTicket' +import { solveFields } from './solveFields' + +const load = loader(16) +const rules = load('rules') +const tickets = load('tickets') + +console.log( + solveFields( + parseRules(rules), + 'departure', + )(tickets.map((s) => s.split(',').map((s) => parseInt(s, 10)))), +) diff --git a/day16/tickets.txt b/day16/tickets.txt new file mode 100644 index 0000000..bee67ee --- /dev/null +++ b/day16/tickets.txt @@ -0,0 +1,236 @@ +279,705,188,357,892,488,741,247,572,176,760,306,410,861,507,906,179,501,808,245 +51,436,407,893,228,722,213,239,813,460,415,571,95,98,116,138,811,552,164,813 +407,242,909,340,99,906,566,749,880,708,273,843,737,244,244,461,903,198,806,64 +83,740,373,298,441,199,633,271,397,437,693,624,461,372,296,684,122,795,754,124 +294,541,629,865,767,632,434,189,86,799,891,667,466,707,419,197,225,627,243,750 +158,405,551,439,803,149,737,773,220,910,341,798,536,209,753,199,273,141,617,122 +457,176,371,757,456,192,304,803,256,627,695,762,232,400,755,520,706,926,200,382 +566,92,846,448,743,796,54,210,442,623,423,247,52,262,386,747,337,514,145,635 +729,403,105,108,514,434,752,244,175,291,147,78,520,708,843,494,409,392,744,572 +799,76,122,195,129,298,242,547,563,909,750,438,178,632,514,273,858,397,708,151 +482,119,106,800,341,112,804,846,436,566,890,925,515,886,763,236,793,420,908,133 +665,335,739,444,989,246,461,57,684,443,842,146,80,372,152,133,306,628,206,753 +519,350,70,729,633,949,500,664,726,572,844,211,694,399,912,416,199,97,219,691 +379,747,806,134,757,763,334,404,893,909,103,795,522,546,559,394,132,77,457,401 +78,142,536,664,128,804,795,906,204,947,339,388,778,96,766,709,118,227,85,305 +182,465,484,349,383,94,508,345,61,238,299,540,555,735,353,438,378,500,403,289 +132,735,427,356,147,233,905,456,373,712,128,71,559,191,270,350,299,709,453,110 +446,445,408,494,423,3,357,625,702,390,511,896,79,712,493,452,510,205,193,554 +416,667,449,483,803,348,566,569,753,378,762,497,690,208,81,740,522,187,357,276 +890,927,405,213,694,733,76,516,429,489,398,537,540,621,486,727,141,204,145,505 +757,354,134,684,83,73,482,846,800,547,206,808,106,763,685,877,771,221,194,591 +445,857,432,384,630,418,185,108,569,621,619,451,809,763,744,590,698,520,457,247 +769,800,271,50,685,895,125,692,217,419,379,473,18,66,80,381,74,65,57,385 +454,348,573,88,351,551,358,896,380,468,630,400,104,405,591,201,556,542,939,346 +126,236,111,226,241,159,378,686,68,208,810,534,742,356,182,243,302,943,409,540 +120,755,700,704,483,378,666,397,520,209,137,276,361,353,687,709,438,108,129,688 +350,274,153,297,177,909,69,547,762,715,395,729,412,185,53,205,943,807,347,874 +344,472,705,183,192,431,200,53,110,666,332,209,896,376,454,713,768,98,215,148 +417,903,567,89,330,739,447,894,488,57,409,542,274,532,148,737,746,661,753,747 +331,194,101,513,145,81,0,198,226,843,807,88,62,223,904,86,901,737,509,753 +480,270,382,439,707,343,91,458,383,119,808,82,60,684,147,454,110,545,807,405 +760,617,358,697,690,796,55,449,205,510,340,61,66,215,565,650,567,241,229,242 +419,626,848,662,230,392,687,278,625,298,230,756,765,210,840,71,401,633,351,148 +211,544,797,975,432,89,105,713,555,376,115,53,690,703,948,274,809,591,844,541 +628,204,110,450,408,544,812,505,417,769,494,148,147,537,727,902,924,771,202,429 +177,428,57,407,564,243,143,382,500,134,177,304,215,405,624,865,843,486,551,796 +690,454,56,467,144,209,490,458,353,807,731,762,180,990,423,727,444,247,152,391 +675,83,107,514,537,411,444,223,121,154,452,811,180,196,567,591,110,896,696,534 +61,387,141,813,932,793,277,410,902,630,230,272,80,337,493,205,461,797,507,495 +204,124,997,550,378,388,551,189,138,391,560,139,222,149,467,627,702,220,68,436 +273,179,231,383,683,943,499,665,214,508,209,218,127,614,814,63,353,464,290,905 +120,100,143,278,592,486,493,18,149,707,196,302,538,844,145,796,482,764,772,238 +179,561,395,841,699,626,509,126,399,796,771,445,208,700,331,156,285,152,418,755 +116,949,434,491,172,618,416,842,793,947,182,908,629,216,194,846,796,634,496,390 +395,381,94,116,466,402,4,418,511,793,697,927,448,904,454,619,94,110,95,493 +379,521,684,715,944,692,892,276,901,924,373,525,593,238,435,108,512,801,111,944 +733,246,898,356,150,498,195,57,750,210,119,663,823,378,418,66,744,573,538,924 +625,389,928,891,291,305,84,109,794,399,926,181,95,459,464,278,401,347,459,713 +688,275,683,517,559,297,948,439,907,347,710,181,76,739,739,454,548,736,432,989 +237,118,394,111,208,378,138,171,696,412,399,109,210,331,125,205,632,634,696,490 +614,222,593,103,810,55,762,503,945,541,182,693,75,124,400,414,710,213,177,781 +927,689,185,155,852,703,927,189,386,51,155,53,280,928,634,76,543,456,815,806 +990,410,149,206,666,384,394,903,345,97,77,214,473,244,152,618,534,242,560,208 +70,220,193,447,202,77,420,733,627,686,513,948,121,746,900,488,453,284,589,192 +897,707,928,247,434,623,516,854,703,416,589,905,739,485,468,341,799,491,683,451 +377,507,192,518,208,352,217,554,390,910,194,878,699,109,927,182,735,705,146,415 +548,101,144,738,801,455,372,571,899,301,350,271,155,337,714,791,436,619,133,304 +460,400,122,744,132,754,624,570,572,500,566,436,17,513,699,749,483,709,403,738 +181,57,627,947,429,758,593,512,504,101,799,842,155,843,901,633,555,563,211,144 +322,928,464,714,793,621,731,71,551,509,910,354,708,388,809,666,208,623,543,467 +61,331,911,372,765,445,494,621,631,472,519,352,345,409,338,152,154,763,55,658 +405,438,749,236,551,593,895,539,846,246,749,513,259,376,106,82,467,194,440,564 +549,924,407,756,689,692,105,349,943,50,80,622,282,438,63,235,748,846,912,946 +557,550,557,415,483,544,621,802,520,566,397,274,425,846,57,493,800,537,556,742 +120,572,517,114,423,499,634,110,357,435,684,349,861,707,483,434,389,702,661,61 +98,976,516,114,927,899,566,104,903,796,758,633,538,411,148,499,553,383,506,227 +80,510,571,571,837,518,111,139,550,843,387,76,305,544,543,456,683,707,124,711 +450,710,277,420,123,843,59,123,151,414,712,197,929,202,663,896,400,749,75,486 +545,504,550,621,143,815,543,517,837,502,765,590,513,398,338,558,107,573,468,50 +574,865,925,711,122,812,442,732,738,743,758,460,948,572,140,102,896,372,499,543 +222,450,273,686,384,806,619,153,58,378,356,628,355,191,176,683,193,132,881,518 +725,386,299,568,689,402,68,65,223,412,802,804,123,151,115,689,338,448,615,355 +276,696,105,492,279,424,623,118,215,334,556,708,875,615,626,213,246,503,693,487 +431,147,183,619,441,411,50,565,909,406,407,692,109,243,799,404,743,540,117,928 +114,492,740,453,302,279,666,948,356,107,393,104,411,345,560,110,436,437,83,171 +375,571,195,376,194,755,242,232,216,698,336,244,928,946,412,231,793,887,97,808 +545,473,297,408,563,386,713,385,624,378,414,483,766,941,761,731,210,149,538,243 +173,810,239,98,186,492,84,50,332,355,395,710,906,303,741,451,812,795,272,404 +398,106,207,892,383,435,913,404,332,793,541,345,339,466,549,382,744,124,430,558 +452,806,843,623,734,395,341,330,192,84,206,184,988,226,75,794,544,762,413,103 +539,406,740,772,794,211,892,294,635,393,235,694,176,627,772,449,710,502,63,622 +128,813,68,945,275,453,902,402,79,736,696,21,891,132,204,626,797,667,843,470 +404,205,793,552,946,830,76,56,728,213,563,154,468,347,272,927,225,630,357,395 +695,199,943,764,147,58,216,147,377,633,635,123,735,442,568,710,944,543,754,937 +178,218,127,156,316,118,624,82,449,747,125,624,387,233,177,376,154,446,554,385 +764,564,557,793,913,591,984,568,276,188,518,542,807,627,80,388,93,554,689,439 +692,810,19,84,553,571,353,736,56,486,451,756,121,710,342,145,740,729,706,565 +487,548,700,762,763,132,99,811,446,688,509,728,806,614,140,99,942,189,270,502 +412,526,756,894,233,515,703,460,865,464,86,145,228,772,231,211,85,132,446,247 +202,70,211,110,96,370,197,216,768,344,799,191,56,135,540,905,356,715,459,763 +620,56,419,354,708,414,488,710,766,77,463,712,225,8,713,741,204,616,635,626 +84,721,443,572,337,560,813,108,768,432,535,190,231,623,406,114,799,411,151,386 +890,807,897,400,278,570,95,103,626,430,68,299,731,701,625,113,503,617,747,497 +53,376,540,383,336,780,136,925,353,805,346,747,411,911,386,542,116,913,772,803 +382,508,553,893,490,377,186,924,121,573,379,420,306,1,739,589,128,379,734,434 +903,383,741,350,103,350,179,407,72,521,628,773,646,401,755,236,61,372,812,330 +740,565,373,400,491,563,737,625,461,761,67,303,913,979,383,844,711,357,865,740 +701,243,62,760,126,684,343,149,982,444,179,693,212,902,421,347,100,341,617,498 +270,796,626,699,518,735,205,559,13,842,896,909,237,809,102,376,809,558,471,462 +346,565,630,97,382,393,270,904,300,199,465,941,497,126,98,504,705,897,397,567 +908,806,284,518,276,748,113,419,628,86,352,800,745,414,625,213,83,146,137,106 +842,656,845,82,665,489,626,573,242,184,510,400,116,135,215,623,773,892,177,150 +610,949,795,630,201,110,736,891,626,270,198,710,748,89,727,901,55,345,763,613 +395,345,797,185,684,814,738,375,861,737,613,305,381,78,798,766,394,554,548,278 +613,811,302,188,905,96,693,160,441,80,201,692,736,270,626,557,896,485,734,279 +465,13,90,519,760,64,483,613,907,911,408,904,339,537,336,842,155,451,393,134 +67,683,631,389,869,518,385,705,344,212,712,809,80,114,230,415,109,766,482,689 +805,413,65,65,703,564,537,798,277,153,301,393,708,552,759,167,187,744,118,767 +844,153,337,926,845,433,703,176,715,131,130,98,801,122,937,72,737,811,509,742 +409,624,234,846,349,683,406,53,709,773,706,445,557,752,728,455,427,517,695,500 +666,441,92,903,421,526,624,745,443,143,83,175,347,571,123,96,118,194,713,201 +734,592,214,140,786,91,74,560,794,146,741,127,765,217,665,736,561,232,405,505 +201,613,104,413,542,68,179,193,402,757,463,926,844,572,376,553,541,532,492,814 +946,683,522,117,561,613,448,701,123,806,144,383,769,559,179,449,51,892,555,407 +70,490,497,486,666,699,155,374,590,843,57,221,51,169,52,372,145,71,502,223 +728,844,519,105,560,767,449,841,463,240,903,593,21,80,239,900,729,58,275,691 +565,454,713,386,585,545,403,242,356,911,100,234,406,147,339,549,380,297,127,553 +945,229,242,183,534,110,132,374,421,504,911,705,214,628,797,11,552,541,753,520 +354,352,377,124,944,211,203,126,521,386,738,683,350,593,510,948,744,937,494,155 +186,928,801,633,75,299,487,443,375,935,762,152,542,572,573,276,766,217,450,813 +410,59,388,487,419,238,408,488,206,661,236,812,469,551,537,529,119,793,280,613 +501,556,444,750,924,304,155,912,439,137,470,176,907,120,225,227,761,378,692,530 +869,702,773,482,453,372,496,88,698,65,730,229,735,689,105,352,803,709,759,438 +495,891,306,79,839,397,191,371,80,353,539,728,907,419,187,907,13,842,87,947 +850,688,56,305,630,202,398,620,622,798,235,126,799,421,493,131,558,379,395,212 +846,483,500,559,487,100,618,911,642,626,112,306,540,494,150,273,764,707,492,60 +520,749,504,549,502,755,664,338,143,542,388,770,913,402,135,391,572,101,713,722 +751,842,395,629,769,500,663,898,906,119,304,839,714,69,403,431,900,801,592,202 +125,272,125,175,740,56,898,430,549,928,192,570,471,280,510,129,129,471,521,458 +382,868,564,113,185,333,411,247,494,177,228,803,67,912,211,374,483,760,493,487 +372,222,190,306,555,710,186,273,60,688,410,142,514,508,567,848,415,632,728,189 +190,571,374,737,482,476,449,506,807,689,549,489,741,946,727,98,352,238,104,392 +456,182,71,182,463,728,88,138,620,150,342,535,229,228,112,664,735,429,750,120 +941,383,447,520,104,127,89,99,729,841,890,736,623,125,183,142,279,798,729,514 +3,141,589,447,213,498,465,906,146,436,132,539,795,128,733,73,551,562,93,502 +142,102,191,744,130,206,467,241,294,472,520,218,50,896,100,415,561,691,743,131 +757,285,734,924,493,539,485,66,77,343,135,210,442,424,514,50,628,280,397,392 +755,546,755,741,630,187,489,92,689,271,568,59,279,814,545,935,773,519,767,903 +484,348,756,346,184,754,518,695,435,701,415,102,515,54,102,373,139,758,221,266 +904,373,548,420,571,465,865,716,444,446,68,56,231,387,492,141,204,454,568,635 +490,126,752,237,840,441,271,563,499,490,736,18,77,688,751,841,279,814,706,164 +543,895,509,469,893,383,149,485,663,240,442,375,991,193,331,352,464,513,188,727 +205,949,665,231,688,230,413,940,239,764,100,136,684,56,234,377,232,735,737,558 +335,234,516,735,231,128,72,544,81,534,747,975,383,247,591,737,220,213,631,188 +613,803,391,913,692,303,467,71,543,771,414,106,736,133,526,619,740,763,80,57 +805,87,904,745,186,183,196,763,147,448,627,771,157,561,341,731,444,331,728,465 +230,195,809,220,747,613,552,225,70,766,707,743,946,558,298,162,466,302,699,615 +403,91,695,846,99,244,415,105,892,926,350,985,333,505,806,224,746,356,807,343 +798,740,272,936,568,891,535,519,740,701,63,413,66,272,280,204,280,235,123,560 +112,444,470,509,79,207,140,869,539,58,177,123,418,841,772,87,399,562,384,744 +89,550,247,632,563,846,349,763,184,194,898,757,167,222,64,272,456,63,693,415 +492,20,416,846,178,447,495,944,805,237,593,408,501,178,298,228,377,404,224,358 +741,386,138,125,478,553,83,101,304,894,466,437,373,341,623,844,946,810,555,115 +741,162,502,891,131,152,551,113,512,58,760,894,705,505,753,406,743,909,773,547 +404,188,223,57,731,653,124,805,234,752,371,707,356,712,945,331,747,151,947,148 +138,553,98,176,256,457,756,754,108,349,133,422,97,489,565,911,662,147,373,240 +236,51,945,68,67,144,771,763,690,807,505,521,219,572,373,257,195,517,753,53 +391,811,353,558,495,404,374,734,714,335,122,454,589,472,280,890,506,162,683,79 +767,825,905,904,519,332,708,506,436,237,801,302,711,84,196,424,947,84,72,191 +438,568,237,460,347,558,15,304,799,423,69,843,772,185,500,77,150,355,683,238 +497,134,396,536,224,223,414,412,776,416,303,125,275,501,502,839,216,754,687,232 +516,244,444,152,556,297,689,665,445,107,225,293,88,573,113,913,401,769,814,463 +149,902,76,505,508,542,839,176,494,560,900,128,578,156,223,893,218,225,684,807 +54,802,276,514,620,68,797,411,54,273,742,213,715,724,556,80,590,811,96,751 +907,57,490,727,592,86,223,647,444,504,346,708,418,278,404,191,738,62,215,376 +52,265,279,273,336,752,456,768,372,466,272,844,686,410,134,223,203,389,468,196 +223,324,865,68,149,505,488,244,547,117,392,589,896,494,747,98,298,569,507,467 +436,137,440,538,471,385,766,615,846,809,928,689,307,212,446,514,418,203,662,422 +338,697,19,705,689,104,686,538,56,538,434,214,80,214,116,298,183,560,734,414 +58,474,53,498,698,752,752,698,146,155,706,753,894,452,52,415,385,697,904,765 +56,200,449,226,343,76,177,409,228,484,135,350,762,794,691,384,333,945,109,996 +215,140,537,696,390,353,736,550,91,514,235,126,68,79,156,764,874,384,891,228 +297,939,114,134,505,461,706,683,357,246,222,460,763,75,563,392,337,535,546,549 +132,378,395,518,78,746,425,103,357,896,450,233,899,750,634,451,100,274,65,176 +471,893,801,755,528,488,246,665,74,702,489,110,126,138,729,190,752,120,225,437 +396,783,548,357,543,84,150,118,794,891,459,559,633,77,225,558,247,398,67,555 +464,350,68,274,335,352,617,91,555,620,548,708,737,345,852,126,129,555,416,904 +539,74,118,353,160,559,225,435,928,435,205,454,242,234,752,737,815,274,469,742 +422,136,752,128,340,456,507,504,664,551,634,404,733,425,197,534,564,217,536,536 +618,592,432,536,769,347,693,540,241,412,191,554,299,352,218,319,236,727,500,543 +456,180,137,901,569,258,59,900,913,331,462,418,187,747,450,384,210,384,729,373 +813,563,211,800,773,298,238,52,989,454,85,766,102,741,243,752,510,535,483,240 +448,390,933,621,242,50,71,484,104,350,752,271,492,730,335,54,747,103,144,566 +146,742,446,619,744,772,931,52,538,275,75,302,164,499,415,763,140,110,111,400 +123,443,356,91,78,878,507,944,444,949,492,690,740,212,763,714,553,126,278,348 +568,664,563,199,561,315,552,55,198,228,202,493,141,455,691,727,336,175,132,239 +455,514,693,144,198,331,354,383,395,796,460,219,729,341,99,753,623,228,338,162 +550,684,66,278,724,438,60,499,274,199,298,276,707,945,409,445,457,181,349,242 +493,590,810,381,509,898,382,461,301,58,465,743,392,728,376,746,15,142,198,715 +792,183,551,191,349,122,184,695,399,767,735,735,452,446,893,245,70,660,335,507 +403,801,380,689,237,770,192,729,175,205,622,194,383,392,556,724,773,74,949,535 +538,754,418,433,737,552,803,496,352,510,240,303,601,537,797,748,709,901,497,795 +390,193,216,904,228,443,550,627,663,379,219,749,484,163,345,86,733,913,75,707 +106,801,75,913,300,736,614,209,736,76,898,749,298,380,305,435,52,982,129,744 +385,796,354,807,626,272,105,372,441,421,506,508,239,892,224,284,763,766,229,278 +619,422,911,383,347,446,689,347,397,94,232,98,480,455,512,380,198,693,153,548 +60,510,423,890,227,850,924,178,759,182,590,184,453,465,904,466,616,502,63,684 +197,913,442,894,702,226,214,409,513,376,468,538,626,739,731,994,417,227,553,502 +197,625,403,117,300,713,70,795,754,549,815,409,121,148,995,189,796,742,690,273 +689,592,83,122,301,128,235,224,522,566,212,750,102,434,116,630,620,534,434,410 +642,948,901,421,225,666,64,138,635,358,344,690,79,613,98,413,392,57,487,372 +156,419,275,139,745,629,388,805,949,352,63,549,94,746,874,297,568,375,801,74 +710,554,768,379,136,932,376,380,403,739,177,458,391,469,756,180,204,907,244,865 +617,166,415,565,926,119,420,414,560,298,924,381,747,306,468,661,116,240,688,195 +221,358,420,246,368,75,68,279,694,280,341,378,81,752,501,696,404,902,345,752 +900,547,798,277,446,222,152,527,144,509,551,89,713,218,189,624,452,503,246,330 +395,407,16,547,421,517,665,389,97,298,140,126,467,164,420,183,807,93,703,153 +191,337,63,450,517,284,408,135,899,800,126,623,450,435,563,904,420,924,84,146 +693,618,910,843,500,185,509,181,438,461,845,430,450,805,123,247,432,738,374,571 +141,907,556,298,739,302,469,510,548,402,767,893,436,665,62,814,622,944,51,855 +446,434,447,146,643,626,489,344,111,112,801,467,91,177,186,204,613,207,100,519 +911,333,159,241,446,444,199,771,244,419,627,419,543,411,439,485,138,893,99,698 +632,799,441,800,796,439,120,394,536,735,664,794,897,235,121,86,174,519,132,625 +176,760,53,135,347,336,732,487,169,418,67,352,536,454,800,136,133,423,199,125 +508,397,814,752,381,697,243,906,936,144,175,660,842,126,377,749,926,569,620,665 +398,687,231,619,842,270,505,948,806,712,573,925,407,246,191,741,158,631,119,84 +554,844,457,125,88,185,562,120,231,741,341,154,572,279,428,758,306,83,798,338 +833,440,150,616,398,704,521,899,706,771,153,793,571,384,733,334,397,907,541,615 +359,845,422,58,302,629,387,240,627,902,487,455,235,215,353,683,193,440,129,696 +371,226,949,434,56,906,103,387,511,451,473,164,72,805,928,374,748,229,453,16 +155,68,205,133,592,762,60,732,488,133,752,119,507,545,20,97,386,79,727,534 +392,627,416,116,994,684,894,749,615,621,913,767,81,946,192,82,814,631,393,466 +268,494,667,947,393,67,435,135,744,441,840,572,58,270,71,145,229,541,300,464 +214,221,372,749,440,90,402,438,944,732,178,153,118,805,331,418,724,175,625,913 +452,667,686,456,185,472,130,807,898,663,810,354,344,650,385,797,399,708,622,100 +812,149,593,450,212,421,742,613,355,301,450,89,192,899,162,151,843,460,515,92 +531,201,557,279,633,68,131,338,804,199,489,452,220,203,745,128,665,946,410,240 +745,842,703,100,802,735,909,749,461,865,661,512,237,20,694,106,453,709,705,103 +406,247,62,91,375,547,796,53,751,463,753,121,358,293,213,413,631,947,332,355 +633,347,549,56,464,246,700,489,77,90,904,432,181,392,717,415,556,273,562,225 +800,180,876,110,804,375,627,225,892,120,116,117,619,557,81,88,112,537,106,123 +451,233,73,405,746,169,556,551,548,444,91,630,150,521,553,376,332,771,342,560 +348,556,567,684,865,910,200,695,311,418,384,483,905,422,510,185,473,631,560,344 +515,391,442,687,843,412,545,469,159,400,123,153,745,180,842,751,394,492,494,485 +409,442,390,469,223,335,552,77,758,339,94,186,721,683,539,486,924,684,632,192 +700,298,999,164,410,279,113,377,813,909,233,209,376,152,390,340,701,632,153,406 \ No newline at end of file From 0fa3b14b595758caee7c8b2037d3087786dc6b74 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Wed, 16 Dec 2020 22:51:08 +0100 Subject: [PATCH 50/60] feat(day16): part 2 try 2 --- day16/isValidTicket.ts | 2 +- day16/solution.spec.ts | 7 ----- day16/test2.ts | 71 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 8 deletions(-) create mode 100644 day16/test2.ts diff --git a/day16/isValidTicket.ts b/day16/isValidTicket.ts index 0ca911a..1a01d96 100644 --- a/day16/isValidTicket.ts +++ b/day16/isValidTicket.ts @@ -1,4 +1,4 @@ -export type Rules = Record +export type Rules = Record export const parseRules = (rules: string[]): Rules => rules.reduce((rules, rule) => { diff --git a/day16/solution.spec.ts b/day16/solution.spec.ts index 207282b..59efeaa 100644 --- a/day16/solution.spec.ts +++ b/day16/solution.spec.ts @@ -87,12 +87,5 @@ describe('Day 16: Ticket Translation', () => { 'seat', ]) }) - it.skip('should solve', () => { - expect( - solveFields(parseRules(rules))( - tickets.map((s) => s.split(',').map((s) => parseInt(s, 10))), - ), - ).toEqual(['row', 'class', 'seat']) - }) }) }) diff --git a/day16/test2.ts b/day16/test2.ts new file mode 100644 index 0000000..1f727d5 --- /dev/null +++ b/day16/test2.ts @@ -0,0 +1,71 @@ +import { loader } from '../lib/loader' +import { parseRules } from './isValidTicket' + +const load = loader(16) +const tickets = load('tickets').map((s) => + s.split(',').map((s) => parseInt(s, 10)), +) +const rules = parseRules(load('rules')) + +type Rules = [string, [[number, number], [number, number]]][] + +const departureRules: Rules = Object.entries(rules).filter(([k]) => + k.startsWith('departure'), +) + +const findMatch = ( + rules: Rules, + tickets: number[][], + parents: Record = {}, +): any => { + if (rules.length === 0) { + // Check all tickets + for (const ticket of tickets) { + for (const [ruleName, k] of Object.entries(parents)) { + const v = ticket[k] + const rule = rules.find(([name]) => name === ruleName) + const [ruleMin1, ruleMax1] = rule?.[1][0] ?? [ + Number.MAX_SAFE_INTEGER, + -Number.MAX_SAFE_INTEGER, + ] + const [ruleMin2, ruleMax2] = rule?.[1][1] ?? [ + Number.MAX_SAFE_INTEGER, + -Number.MAX_SAFE_INTEGER, + ] + if ( + !( + (v >= ruleMin1 || v >= ruleMin2) && + (v <= ruleMax1 || v <= ruleMax2) + ) + ) { + return // fail + } + } + } + console.log(parents) + return // pass + } + for (let r = 0; r < rules.length; r++) { + const rule = rules[r] + const rest = [...rules.slice(0, r), ...rules.slice(r + 1)] + for (let k = 0; k < tickets[0].length; k++) { + if (Object.values(parents).includes(k)) continue + const [ruleMin1, ruleMax1] = rule[1][0] + const [ruleMin2, ruleMax2] = rule[1][1] + for (const ticket of tickets) { + const v = ticket[k] + if ( + (v >= ruleMin1 || v >= ruleMin2) && + (v <= ruleMax1 || v <= ruleMax2) + ) { + findMatch(rest, tickets, { + ...parents, + [rule[0]]: k, + }) + } + } + } + } +} + +console.log(findMatch(departureRules, tickets)) From a6bd51ff2893ea7e7db252a855784ab1fc018264 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Thu, 17 Dec 2020 13:38:22 +0100 Subject: [PATCH 51/60] feat(day16): part 2 try 3 --- day16/test2.ts | 112 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 73 insertions(+), 39 deletions(-) diff --git a/day16/test2.ts b/day16/test2.ts index 1f727d5..8b217eb 100644 --- a/day16/test2.ts +++ b/day16/test2.ts @@ -1,71 +1,105 @@ -import { loader } from '../lib/loader' +import { loadString } from '../lib/loader' import { parseRules } from './isValidTicket' -const load = loader(16) -const tickets = load('tickets').map((s) => - s.split(',').map((s) => parseInt(s, 10)), -) -const rules = parseRules(load('rules')) - type Rules = [string, [[number, number], [number, number]]][] -const departureRules: Rules = Object.entries(rules).filter(([k]) => - k.startsWith('departure'), -) +const rulePositionChecked = {} as Record +const ruleOrderChecked = {} as Record const findMatch = ( rules: Rules, tickets: number[][], - parents: Record = {}, + remainingRules = rules, + parents: string[] = [], ): any => { - if (rules.length === 0) { - // Check all tickets - for (const ticket of tickets) { - for (const [ruleName, k] of Object.entries(parents)) { + if (remainingRules.length === 0) { + if (rules.length !== parents.length) { + console.error({ + remainingRules, + parents, + }) + throw new Error('BUG!') + } + if (ruleOrderChecked[parents.join(',')] !== undefined) return + // Check all rules with all tickets + for (let k = 0; k < parents.length; k++) { + const ruleName = parents[k] + const key = `${ruleName}-${k}` + if (rulePositionChecked[key] !== undefined) return // fail early + const rule = rules.find(([name]) => name === ruleName) + const [ruleMin1, ruleMax1] = rule?.[1][0] ?? [ + Number.MAX_SAFE_INTEGER, + -Number.MAX_SAFE_INTEGER, + ] + const [ruleMin2, ruleMax2] = rule?.[1][1] ?? [ + Number.MAX_SAFE_INTEGER, + -Number.MAX_SAFE_INTEGER, + ] + for (const ticket of tickets) { const v = ticket[k] - const rule = rules.find(([name]) => name === ruleName) - const [ruleMin1, ruleMax1] = rule?.[1][0] ?? [ - Number.MAX_SAFE_INTEGER, - -Number.MAX_SAFE_INTEGER, - ] - const [ruleMin2, ruleMax2] = rule?.[1][1] ?? [ - Number.MAX_SAFE_INTEGER, - -Number.MAX_SAFE_INTEGER, - ] if ( !( - (v >= ruleMin1 || v >= ruleMin2) && - (v <= ruleMax1 || v <= ruleMax2) + (v >= ruleMin1 && v <= ruleMax1) || + (v >= ruleMin2 && v <= ruleMax2) ) ) { + ruleOrderChecked[parents.join(',')] = false return // fail } } } - console.log(parents) - return // pass + ruleOrderChecked[parents.join(',')] = true + return parents // pass } - for (let r = 0; r < rules.length; r++) { - const rule = rules[r] - const rest = [...rules.slice(0, r), ...rules.slice(r + 1)] + for (let r = 0; r < remainingRules.length; r++) { + const rule = remainingRules[r] + const rest = [...remainingRules.slice(0, r), ...remainingRules.slice(r + 1)] for (let k = 0; k < tickets[0].length; k++) { - if (Object.values(parents).includes(k)) continue + const key = `${rule[0]}-${k}` + if (rulePositionChecked[key] !== undefined) return const [ruleMin1, ruleMax1] = rule[1][0] const [ruleMin2, ruleMax2] = rule[1][1] + let allMatch = true for (const ticket of tickets) { const v = ticket[k] if ( - (v >= ruleMin1 || v >= ruleMin2) && - (v <= ruleMax1 || v <= ruleMax2) + !( + (v >= ruleMin1 && v <= ruleMax1) || + (v >= ruleMin2 && v <= ruleMax2) + ) ) { - findMatch(rest, tickets, { - ...parents, - [rule[0]]: k, - }) + allMatch = false + break } } + if (allMatch) { + const newParents = [...parents] + newParents[k] = rule[0] + return findMatch(rules, tickets, rest, newParents) + } else { + rulePositionChecked[key] = false + } } } } -console.log(findMatch(departureRules, tickets)) +/* +const load = loader(16) +const tickets = load('tickets').map((s) => + s.split(',').map((s) => parseInt(s, 10)), +) +const rules = parseRules(load('rules')) +console.log(findMatch(Object.entries(rules), tickets)) +console.log(rules) +*/ + +const step2sampleTickets = loadString(` +3,9,18 +15,1,5 +5,14,9`).map((s) => s.split(',').map((s) => parseInt(s, 10))) +const sample2Rules = parseRules( + loadString(`class: 0-1 or 4-19 +row: 0-5 or 8-19 +seat: 0-13 or 16-19`), +) +console.log(findMatch(Object.entries(sample2Rules), step2sampleTickets)) // 'row', 'class', 'seat', From ec09102ba69f3f8e9fa7b9972b15b7f984f3f75e Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Thu, 17 Dec 2020 14:38:02 +0100 Subject: [PATCH 52/60] feat(day16): part 2 --- day16/findMatchingRules.ts | 56 ++++++++++++++++++++ day16/solution.spec.ts | 34 +++++++++++- day16/solveFields.ts | 66 ----------------------- day16/test.ts | 14 ----- day16/test2.ts | 105 ------------------------------------- 5 files changed, 88 insertions(+), 187 deletions(-) create mode 100644 day16/findMatchingRules.ts delete mode 100644 day16/solveFields.ts delete mode 100644 day16/test.ts delete mode 100644 day16/test2.ts diff --git a/day16/findMatchingRules.ts b/day16/findMatchingRules.ts new file mode 100644 index 0000000..f6915e4 --- /dev/null +++ b/day16/findMatchingRules.ts @@ -0,0 +1,56 @@ +import { Rules } from './isValidTicket' + +export const findMatchingRules = ( + tickets: number[][], + rules: Rules, + rowRules = [] as string[], + row = 0, + testMemory = {} as Record, +): string[] | undefined => { + if (row >= tickets[0].length) { + // We have assinged rules to all rows, which means we are done. + return rowRules + } + // Assing the remaining rules + const remainingRules = Object.entries(rules).filter( + ([ruleName]) => !rowRules.includes(ruleName), + ) + const matchingRules = [] + for (const [ruleName, [[min1, max1], [min2, max2]]] of remainingRules) { + const key = `${ruleName}-${row}` + const previous = testMemory[key] + if (previous === false) continue // We have tested this rule already for this row and it never matches + if (previous === true) { + // We have tested this rule already for all tickets and can use it + matchingRules.push(ruleName) + continue + } + // Check if all tickets match this rule + let allTicketsMatch = true + for (const ticket of tickets) { + const v = ticket[row] + if (!((v >= min1 && v <= max1) || (v >= min2 && v <= max2))) { + allTicketsMatch = false + testMemory[key] = false + break + } + } + if (allTicketsMatch) { + matchingRules.push(ruleName) + testMemory[key] = true + } + } + if (matchingRules.length) { + for (const matchingRule of matchingRules) { + const res = findMatchingRules( + tickets, + rules, + [...rowRules, matchingRule], + row + 1, + testMemory, + ) + if (res) return res + } + } + return +} diff --git a/day16/solution.spec.ts b/day16/solution.spec.ts index 59efeaa..2c9d343 100644 --- a/day16/solution.spec.ts +++ b/day16/solution.spec.ts @@ -1,6 +1,6 @@ import { loader, loadString } from '../lib/loader' import { findInvalidNumbers, parseRules } from './isValidTicket' -import { solveFields } from './solveFields' +import { findMatchingRules } from './findMatchingRules' const sampleRules = loadString(`class: 1-3 or 5-7 row: 6-11 or 33-44 @@ -81,11 +81,41 @@ describe('Day 16: Ticket Translation', () => { ) expect(validTickets).toHaveLength(3) - expect(solveFields(sample2Rules)(step2sampleTickets)).toEqual([ + expect(findMatchingRules(step2sampleTickets, sample2Rules)).toEqual([ 'row', 'class', 'seat', ]) }) + it('should solve', () => { + const r = parseRules(rules) + const f = findInvalidNumbers(r) + const validTickets = tickets + .map((s) => s.split(',').map((s) => parseInt(s, 10))) + .filter((ticket) => f(ticket).length === 0) + const res = findMatchingRules(validTickets, r) + expect(res).toEqual([ + 'route', + 'arrival track', + 'departure location', + 'type', + 'arrival station', + 'duration', + 'arrival platform', + 'departure platform', + 'train', + 'row', + 'arrival location', + 'wagon', + 'seat', + 'departure time', + 'departure station', + 'class', + 'departure date', + 'price', + 'zone', + 'departure track', + ]) + }) }) }) diff --git a/day16/solveFields.ts b/day16/solveFields.ts deleted file mode 100644 index 5b0df8e..0000000 --- a/day16/solveFields.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { Rules } from './isValidTicket' - -const combine = (categories: T[]) => { - const combinations: T[][] = [] - const g = (categories: T[], parents: T[] = []) => { - if (categories.length === 0) { - combinations.push(parents) - return - } - categories.forEach((cat) => { - g( - categories.filter((c) => [...parents, cat].includes(c) === false), - [...parents, cat], - ) - }) - } - g(categories) - return combinations -} - -export const solveFields = (rules: Rules, filter?: string) => ( - validTickets: number[][], -): string[] => { - const allCategories = Object.keys(rules) - const filteredCategories = allCategories.filter((s) => - filter === undefined ? true : s.startsWith(filter), - ) - const combinations = combine(filteredCategories) - const missing = allCategories.length - filteredCategories.length - - for (let i = 0; i <= missing; i++) { - for (const c of combinations) { - let validCombination = [] as string[] - ;(() => { - const ranges = [ - ...'-' - .repeat(i) - .split('') - .map(() => [ - [0, Number.MAX_SAFE_INTEGER], - [0, Number.MAX_SAFE_INTEGER], - ]), - ...c.map((c) => rules[c]), - ...'-' - .repeat(missing - i) - .split('') - .map(() => [ - [0, Number.MAX_SAFE_INTEGER], - [0, Number.MAX_SAFE_INTEGER], - ]), - ] - for (const t of validTickets) { - for (let l = 0; l < t.length; l++) { - const n = t[l] - const [[from1, to1], [from2, to2]] = ranges[l] - const valid = (n >= from1 && n <= to1) || (n >= from2 && n <= to2) - if (!valid) return - } - } - validCombination = c - })() - if (validCombination.length > 0) return validCombination - } - } - return [] -} diff --git a/day16/test.ts b/day16/test.ts deleted file mode 100644 index 42b6e25..0000000 --- a/day16/test.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { loader } from '../lib/loader' -import { parseRules } from './isValidTicket' -import { solveFields } from './solveFields' - -const load = loader(16) -const rules = load('rules') -const tickets = load('tickets') - -console.log( - solveFields( - parseRules(rules), - 'departure', - )(tickets.map((s) => s.split(',').map((s) => parseInt(s, 10)))), -) diff --git a/day16/test2.ts b/day16/test2.ts deleted file mode 100644 index 8b217eb..0000000 --- a/day16/test2.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { loadString } from '../lib/loader' -import { parseRules } from './isValidTicket' - -type Rules = [string, [[number, number], [number, number]]][] - -const rulePositionChecked = {} as Record -const ruleOrderChecked = {} as Record - -const findMatch = ( - rules: Rules, - tickets: number[][], - remainingRules = rules, - parents: string[] = [], -): any => { - if (remainingRules.length === 0) { - if (rules.length !== parents.length) { - console.error({ - remainingRules, - parents, - }) - throw new Error('BUG!') - } - if (ruleOrderChecked[parents.join(',')] !== undefined) return - // Check all rules with all tickets - for (let k = 0; k < parents.length; k++) { - const ruleName = parents[k] - const key = `${ruleName}-${k}` - if (rulePositionChecked[key] !== undefined) return // fail early - const rule = rules.find(([name]) => name === ruleName) - const [ruleMin1, ruleMax1] = rule?.[1][0] ?? [ - Number.MAX_SAFE_INTEGER, - -Number.MAX_SAFE_INTEGER, - ] - const [ruleMin2, ruleMax2] = rule?.[1][1] ?? [ - Number.MAX_SAFE_INTEGER, - -Number.MAX_SAFE_INTEGER, - ] - for (const ticket of tickets) { - const v = ticket[k] - if ( - !( - (v >= ruleMin1 && v <= ruleMax1) || - (v >= ruleMin2 && v <= ruleMax2) - ) - ) { - ruleOrderChecked[parents.join(',')] = false - return // fail - } - } - } - ruleOrderChecked[parents.join(',')] = true - return parents // pass - } - for (let r = 0; r < remainingRules.length; r++) { - const rule = remainingRules[r] - const rest = [...remainingRules.slice(0, r), ...remainingRules.slice(r + 1)] - for (let k = 0; k < tickets[0].length; k++) { - const key = `${rule[0]}-${k}` - if (rulePositionChecked[key] !== undefined) return - const [ruleMin1, ruleMax1] = rule[1][0] - const [ruleMin2, ruleMax2] = rule[1][1] - let allMatch = true - for (const ticket of tickets) { - const v = ticket[k] - if ( - !( - (v >= ruleMin1 && v <= ruleMax1) || - (v >= ruleMin2 && v <= ruleMax2) - ) - ) { - allMatch = false - break - } - } - if (allMatch) { - const newParents = [...parents] - newParents[k] = rule[0] - return findMatch(rules, tickets, rest, newParents) - } else { - rulePositionChecked[key] = false - } - } - } -} - -/* -const load = loader(16) -const tickets = load('tickets').map((s) => - s.split(',').map((s) => parseInt(s, 10)), -) -const rules = parseRules(load('rules')) -console.log(findMatch(Object.entries(rules), tickets)) -console.log(rules) -*/ - -const step2sampleTickets = loadString(` -3,9,18 -15,1,5 -5,14,9`).map((s) => s.split(',').map((s) => parseInt(s, 10))) -const sample2Rules = parseRules( - loadString(`class: 0-1 or 4-19 -row: 0-5 or 8-19 -seat: 0-13 or 16-19`), -) -console.log(findMatch(Object.entries(sample2Rules), step2sampleTickets)) // 'row', 'class', 'seat', From ee196ce444296889dff7d0ffeb2862a294cc667d Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Thu, 17 Dec 2020 22:40:07 +0100 Subject: [PATCH 53/60] feat: day 17 wip --- day17/test.ts | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 day17/test.ts diff --git a/day17/test.ts b/day17/test.ts new file mode 100644 index 0000000..ea5f3e0 --- /dev/null +++ b/day17/test.ts @@ -0,0 +1,141 @@ +import { loadString } from '../lib/loader' + +type Cube = [number, number, number, boolean] + +const seed = loadString(`.#. +..# +###`) + +const cubes = seed.reduce( + (cubes, line, y) => [ + ...cubes, + ...line.split('').map((s, x) => { + if (s === '#') return [x, y, 0, true] as Cube + return [x, y, 0, false] as Cube + }), + ], + [] as Cube[], +) + +const unique = (v: T, k: number, arr: T[]) => arr.indexOf(v) === k + +const printCubes = (cubes: Cube[]) => { + const layers = cubes + .sort(([, , z1], [, , z2]) => z2 - z1) + .map(([, , z]) => z) + .filter(unique) + for (const z of layers) { + console.log('') + console.log(`z=${z}`) + const cubesOnLayer = cubes.filter(([, , cubeZ]) => cubeZ === z) + const width = cubesOnLayer.reduce( + (width, [x]) => (x > width ? x : width), + 0, + ) + const height = cubesOnLayer.reduce( + (height, [, y]) => (y > height ? y : height), + 0, + ) + const space = [] as string[][] + for (let y = 0; y <= height; y++) { + space[y] = [] + for (let x = 0; x <= width; x++) { + space[y][x] = ' ' + } + } + for (const cube of cubesOnLayer) { + space[cube[1]][cube[0]] = cube[3] ? '#' : '.' + } + console.log(space.map((s) => s.join('')).join('\n')) + } +} + +const equal = (a: Cube) => (b: Cube) => + a[0] === b[0] && a[1] === b[1] && a[2] === b[2] + +const notEqual = (a: Cube) => (b: Cube) => !equal(a)(b) + +const isActive = ([, , , active]: Cube) => active + +const neighbor = (a: Cube) => (b: Cube) => + Math.max( + Math.abs(a[0] - b[0]), + Math.abs(a[1] - b[1]), + Math.abs(a[2] - b[2]), + ) === 1 + +const countActiveNeighbours = (cube: Cube, world: Cube[]): number => + world.filter(notEqual(cube)).filter(isActive).filter(neighbor(cube)).length + +// Extend the world so that each active cube has inactive neighbours around +const extend = (world: Cube[]): Cube[] => + world.filter(isActive).reduce((newCubes, cube) => { + const [x, y, z] = cube + const neighbors = [ + // Front slice + [x - 1, y + 1, z - 1, false], + [x, y + 1, z - 1, false], + [x + 1, y + 1, z - 1, false], + [x - 1, y, z - 1, false], + [x, y, z - 1, false], + [x + 1, y, z - 1, false], + [x - 1, y - 1, z - 1, false], + [x, y - 1, z - 1, false], + [x + 1, y - 1, z - 1, false], + // Center slice + [x - 1, y + 1, z, false], + [x, y + 1, z, false], + [x + 1, y + 1, z, false], + [x - 1, y, z, false], + // [x, y, z, false], + [x + 1, y, z, false], + [x - 1, y - 1, z, false], + [x, y - 1, z, false], + [x + 1, y - 1, z, false], + // Back slice + [x - 1, y + 1, z + 1, false], + [x, y + 1, z + 1, false], + [x + 1, y + 1, z + 1, false], + [x - 1, y, z + 1, false], + [x, y, z + 1, false], + [x + 1, y, z + 1, false], + [x - 1, y - 1, z + 1, false], + [x, y - 1, z + 1, false], + [x + 1, y - 1, z + 1, false], + ] as Cube[] + return neighbors.filter( + ([x, y, z]) => + [...world, ...newCubes].find( + ([wx, wy, wz]) => wx === x && wy === y && wz === z, + ) === undefined, + ) + }, [] as Cube[]) + +const cycle = (cubes: Cube[]): Cube[] => + [...cubes, ...extend(cubes)].map((cube) => { + const activeNeighbors = countActiveNeighbours(cube, cubes) + // If a cube is active and exactly 2 or 3 of its neighbors are also active, + // the cube remains active. Otherwise, the cube becomes inactive. + const [x, y, z] = cube + if (isActive(cube)) { + if (activeNeighbors === 2 || activeNeighbors === 3) { + console.log(`Cube ${cube} stays active (${activeNeighbors} neighbors)`) + return [x, y, z, true] + } + console.log( + `Cube ${cube} becomes inactive (${activeNeighbors} neighbors)`, + ) + return [x, y, z, false] + } + // If a cube is inactive but exactly 3 of its neighbors are active, + // the cube becomes active. Otherwise, the cube remains inactive. + if (!isActive(cube)) { + if (activeNeighbors === 3) return [x, y, z, true] + return [x, y, z, false] + } + return [...cube] + }) + +printCubes(cubes) +console.log(`Cycle 1`) +printCubes(cycle(cubes)) From 2b345d19cea12482ba0cc51d2d8d632a450c8189 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Fri, 18 Dec 2020 00:13:37 +0100 Subject: [PATCH 54/60] feat(day17): part 1 --- day17/cubes.ts | 143 +++++++++++++++++++++++++++++++++++++++++ day17/solution.spec.ts | 40 ++++++++++++ day17/test.ts | 141 ---------------------------------------- 3 files changed, 183 insertions(+), 141 deletions(-) create mode 100644 day17/cubes.ts create mode 100644 day17/solution.spec.ts delete mode 100644 day17/test.ts diff --git a/day17/cubes.ts b/day17/cubes.ts new file mode 100644 index 0000000..ced973e --- /dev/null +++ b/day17/cubes.ts @@ -0,0 +1,143 @@ +type ActiveCube = [number, number, number] + +export const loadSeed = (seed: string[]): ActiveCube[] => + seed.reduce( + (cubes, line, y) => [ + ...cubes, + ...(line + .split('') + .map((s, x) => { + if (s === '#') return [x, y, 0] + return undefined + }) + .filter((c) => c !== undefined) as ActiveCube[]), + ], + [] as ActiveCube[], + ) + +const unique = (v: T, k: number, arr: T[]) => arr.indexOf(v) === k + +export const printCubes = (cubes: ActiveCube[]): void => { + const zs = cubes + .sort(([, , z1], [, , z2]) => z1 - z2) + .map(([, , z]) => z) + .filter(unique) + const xs = cubes + .sort(([x1], [x2]) => x1 - x2) + .map(([x]) => x) + .filter(unique) + const ys = cubes + .sort(([, y1], [, y2]) => y1 - y2) + .map(([, y]) => y) + .filter(unique) + + const width = xs[xs.length - 1] - xs[0] + const xOffset = -xs[0] + const height = ys[ys.length - 1] - ys[0] + const yOffset = -ys[0] + + for (const z of zs) { + console.log('') + console.log(`z=${z}`) + const cubesOnLayer = cubes.filter(([, , cubeZ]) => cubeZ === z) + const space = [] as string[][] + for (let y = 0; y <= height; y++) { + space[y] = [] + for (let x = 0; x <= width; x++) { + space[y][x] = '.' + } + } + for (const cube of cubesOnLayer) { + space[cube[1] + yOffset][cube[0] + xOffset] = '#' + } + console.log(space.map((s) => s.join('')).join('\n')) + } +} + +const equal = (a: ActiveCube) => (b: ActiveCube) => + a[0] === b[0] && a[1] === b[1] && a[2] === b[2] + +const notEqual = (a: ActiveCube) => (b: ActiveCube) => !equal(a)(b) + +const neighbor = (a: ActiveCube) => (b: ActiveCube) => + Math.max( + Math.abs(a[0] - b[0]), + Math.abs(a[1] - b[1]), + Math.abs(a[2] - b[2]), + ) === 1 + +const countActiveNeighbours = (cube: ActiveCube, world: ActiveCube[]): number => + world.filter(notEqual(cube)).filter(neighbor(cube)).length + +// Return all the cubes around the given cube +const expand = (cube: ActiveCube): ActiveCube[] => { + const [x, y, z] = cube + return [ + // Front slice + [x - 1, y + 1, z - 1], + [x, y + 1, z - 1], + [x + 1, y + 1, z - 1], + [x - 1, y, z - 1], + [x, y, z - 1], + [x + 1, y, z - 1], + [x - 1, y - 1, z - 1], + [x, y - 1, z - 1], + [x + 1, y - 1, z - 1], + // Center slice + [x - 1, y + 1, z], + [x, y + 1, z], + [x + 1, y + 1, z], + [x - 1, y, z], + //[x, y, z], // Do not return the cube itself + [x + 1, y, z], + [x - 1, y - 1, z], + [x, y - 1, z], + [x + 1, y - 1, z], + // Back slice + [x - 1, y + 1, z + 1], + [x, y + 1, z + 1], + [x + 1, y + 1, z + 1], + [x - 1, y, z + 1], + [x, y, z + 1], + [x + 1, y, z + 1], + [x - 1, y - 1, z + 1], + [x, y - 1, z + 1], + [x + 1, y - 1, z + 1], + ] as ActiveCube[] +} + +const containsCube = (world: ActiveCube[]) => ([x, y, z]: ActiveCube) => + world.find(([wx, wy, wz]) => wx === x && wy === y && wz === z) !== undefined + +const containsNotCube = (world: ActiveCube[]) => (cube: ActiveCube) => + !containsCube(world)(cube) + +export const cycle = (seed: ActiveCube[]): ActiveCube[] => { + const iteration: ActiveCube[] = [] + for (const cube of seed) { + const activeNeighbors = countActiveNeighbours(cube, seed) + // If a cube is active and exactly 2 or 3 of its neighbors are also active, + // the cube remains active. Otherwise, the cube becomes inactive. + const [x, y, z] = cube + if (activeNeighbors === 2 || activeNeighbors === 3) { + // console.log(`Cube ${cube} stays active (${activeNeighbors} neighbors)`) + iteration.push([x, y, z]) + } else { + // console.log( `Cube ${cube} becomes inactive (${activeNeighbors} neighbors)`, ) + } + + // If a cube is inactive but exactly 3 of its neighbors are active, + // the cube becomes active. Otherwise, the cube remains inactive. + const notInSeed = containsNotCube(seed) + const notInIteration = containsNotCube(iteration) + const inactiveAround = expand(cube).filter(notInSeed).filter(notInIteration) + for (const inactiveCube of inactiveAround) { + const activeNeighbors = countActiveNeighbours(inactiveCube, seed) + if (activeNeighbors === 3) { + // console.log( `Cube ${inactiveCube} becomes active (${activeNeighbors} neighbors)`, ) + iteration.push(inactiveCube) + } + } + } + return iteration +} diff --git a/day17/solution.spec.ts b/day17/solution.spec.ts new file mode 100644 index 0000000..7d78841 --- /dev/null +++ b/day17/solution.spec.ts @@ -0,0 +1,40 @@ +import { loadString } from '../lib/loader' +import { loadSeed, printCubes, cycle } from './cubes' + +const sampleSeed = loadString(`.#. +..# +###`) + +const input = loadString(`####...# +......#. +#..#.##. +.#...#.# +..###.#. +##.###.. +.#...### +.##....#`) + +describe('Day 17: Conway Cubes', () => { + describe('Part 1', () => { + it('should solve the sample', () => { + let space = [...loadSeed(sampleSeed)] + for (let c = 0; c < 6; c++) { + console.log('') + console.log(`Cycle ${c}: ${space.length}`) + space = cycle(space) + printCubes(space) + } + expect(space).toHaveLength(112) + }) + it('should solve', () => { + let space = [...loadSeed(input)] + for (let c = 0; c < 6; c++) { + console.log('') + console.log(`Cycle ${c}: ${space.length}`) + space = cycle(space) + printCubes(space) + } + expect(space).toHaveLength(286) + }) + }) +}) diff --git a/day17/test.ts b/day17/test.ts deleted file mode 100644 index ea5f3e0..0000000 --- a/day17/test.ts +++ /dev/null @@ -1,141 +0,0 @@ -import { loadString } from '../lib/loader' - -type Cube = [number, number, number, boolean] - -const seed = loadString(`.#. -..# -###`) - -const cubes = seed.reduce( - (cubes, line, y) => [ - ...cubes, - ...line.split('').map((s, x) => { - if (s === '#') return [x, y, 0, true] as Cube - return [x, y, 0, false] as Cube - }), - ], - [] as Cube[], -) - -const unique = (v: T, k: number, arr: T[]) => arr.indexOf(v) === k - -const printCubes = (cubes: Cube[]) => { - const layers = cubes - .sort(([, , z1], [, , z2]) => z2 - z1) - .map(([, , z]) => z) - .filter(unique) - for (const z of layers) { - console.log('') - console.log(`z=${z}`) - const cubesOnLayer = cubes.filter(([, , cubeZ]) => cubeZ === z) - const width = cubesOnLayer.reduce( - (width, [x]) => (x > width ? x : width), - 0, - ) - const height = cubesOnLayer.reduce( - (height, [, y]) => (y > height ? y : height), - 0, - ) - const space = [] as string[][] - for (let y = 0; y <= height; y++) { - space[y] = [] - for (let x = 0; x <= width; x++) { - space[y][x] = ' ' - } - } - for (const cube of cubesOnLayer) { - space[cube[1]][cube[0]] = cube[3] ? '#' : '.' - } - console.log(space.map((s) => s.join('')).join('\n')) - } -} - -const equal = (a: Cube) => (b: Cube) => - a[0] === b[0] && a[1] === b[1] && a[2] === b[2] - -const notEqual = (a: Cube) => (b: Cube) => !equal(a)(b) - -const isActive = ([, , , active]: Cube) => active - -const neighbor = (a: Cube) => (b: Cube) => - Math.max( - Math.abs(a[0] - b[0]), - Math.abs(a[1] - b[1]), - Math.abs(a[2] - b[2]), - ) === 1 - -const countActiveNeighbours = (cube: Cube, world: Cube[]): number => - world.filter(notEqual(cube)).filter(isActive).filter(neighbor(cube)).length - -// Extend the world so that each active cube has inactive neighbours around -const extend = (world: Cube[]): Cube[] => - world.filter(isActive).reduce((newCubes, cube) => { - const [x, y, z] = cube - const neighbors = [ - // Front slice - [x - 1, y + 1, z - 1, false], - [x, y + 1, z - 1, false], - [x + 1, y + 1, z - 1, false], - [x - 1, y, z - 1, false], - [x, y, z - 1, false], - [x + 1, y, z - 1, false], - [x - 1, y - 1, z - 1, false], - [x, y - 1, z - 1, false], - [x + 1, y - 1, z - 1, false], - // Center slice - [x - 1, y + 1, z, false], - [x, y + 1, z, false], - [x + 1, y + 1, z, false], - [x - 1, y, z, false], - // [x, y, z, false], - [x + 1, y, z, false], - [x - 1, y - 1, z, false], - [x, y - 1, z, false], - [x + 1, y - 1, z, false], - // Back slice - [x - 1, y + 1, z + 1, false], - [x, y + 1, z + 1, false], - [x + 1, y + 1, z + 1, false], - [x - 1, y, z + 1, false], - [x, y, z + 1, false], - [x + 1, y, z + 1, false], - [x - 1, y - 1, z + 1, false], - [x, y - 1, z + 1, false], - [x + 1, y - 1, z + 1, false], - ] as Cube[] - return neighbors.filter( - ([x, y, z]) => - [...world, ...newCubes].find( - ([wx, wy, wz]) => wx === x && wy === y && wz === z, - ) === undefined, - ) - }, [] as Cube[]) - -const cycle = (cubes: Cube[]): Cube[] => - [...cubes, ...extend(cubes)].map((cube) => { - const activeNeighbors = countActiveNeighbours(cube, cubes) - // If a cube is active and exactly 2 or 3 of its neighbors are also active, - // the cube remains active. Otherwise, the cube becomes inactive. - const [x, y, z] = cube - if (isActive(cube)) { - if (activeNeighbors === 2 || activeNeighbors === 3) { - console.log(`Cube ${cube} stays active (${activeNeighbors} neighbors)`) - return [x, y, z, true] - } - console.log( - `Cube ${cube} becomes inactive (${activeNeighbors} neighbors)`, - ) - return [x, y, z, false] - } - // If a cube is inactive but exactly 3 of its neighbors are active, - // the cube becomes active. Otherwise, the cube remains inactive. - if (!isActive(cube)) { - if (activeNeighbors === 3) return [x, y, z, true] - return [x, y, z, false] - } - return [...cube] - }) - -printCubes(cubes) -console.log(`Cycle 1`) -printCubes(cycle(cubes)) From cd784a05ff50ce544c8779cf097d375e562ebeed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 12 Dec 2020 10:25:14 +0000 Subject: [PATCH 55/60] build(deps): bump ini from 1.3.5 to 1.3.8 Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.8. - [Release notes](https://github.com/isaacs/ini/releases) - [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.8) Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 49c1fbb..389dd3a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3716,9 +3716,9 @@ "dev": true }, "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true }, "ip-regex": { From 9f86abfe1a4fe15cbde4c0d558cd748d24576b48 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Fri, 18 Dec 2020 15:12:46 +0100 Subject: [PATCH 56/60] feat(day18): part 1 --- day18/calc.ts | 62 ++++++++ day18/input.txt | 375 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 437 insertions(+) create mode 100644 day18/calc.ts create mode 100644 day18/input.txt diff --git a/day18/calc.ts b/day18/calc.ts new file mode 100644 index 0000000..85c226a --- /dev/null +++ b/day18/calc.ts @@ -0,0 +1,62 @@ +const isNumber = (s: string): boolean => /^[0-9]$/.test(s) +const isSpace = (s: string): boolean => /^ $/.test(s) +const isOperator = (s: string): boolean => /^[+*]$/.test(s) +const isOpeningParenthesis = (s: string): boolean => /^\($/.test(s) +const isClosingParenthesis = (s: string): boolean => /^\)$/.test(s) + +const findClosing = (expr: string, start: number) => { + let level = 0 + for (let i = start; i < expr.length; i++) { + if (isOpeningParenthesis(expr[i])) level++ + if (isClosingParenthesis(expr[i])) level-- + if (level === 0) return i + } + throw new Error( + `Could not find closing paranthesis in ${expr}, starting at ${start}`, + ) +} + +export const calc = (expr: string): number => { + let a = 0 + let op = '' + let b = 0 + let pos = 0 + for (let i = 0; i < expr.length; i++) { + const e = expr[i] + if (isNumber(e)) { + if (pos === 0) { + a = parseInt(`${a}${e}`, 10) + } else { + b = parseInt(`${b}${e}`, 10) + } + } else if (isOperator(e)) { + pos = ++pos % 2 + if (pos === 0) { + a = calc(`${a} ${op} ${b}`) + b = 0 + pos++ + } + op = e + } else if (isSpace(e)) { + // Pass + } else if (isOpeningParenthesis(e)) { + const closingPos = findClosing(expr, i) + const res = calc(expr.substr(i + 1, closingPos - 1 - i)) + if (pos === 0) a = res + else b = res + i = closingPos + if (closingPos >= expr.length - 1 && pos === 0) return a + } else { + throw new Error(`Unexpected character "${e}" at pos ${i}!`) + } + } + + switch (op) { + case '*': + return a * b + case '+': + return a + b + default: + throw new Error(`Unexpected operator "${op}"!`) + } +} diff --git a/day18/input.txt b/day18/input.txt new file mode 100644 index 0000000..f8777b6 --- /dev/null +++ b/day18/input.txt @@ -0,0 +1,375 @@ +(7 * 5 * 6 + (9 * 8 + 3 * 3 + 5) + 7) * (6 + 3 * 9) + 6 + 7 + (7 * 5) * 4 +(4 + 9 + (8 * 2) + 5) * 8 + (3 + 2 * 3 * 7 * (7 * 4 * 5) * 9) * 2 +3 + 7 + (9 + 6 + 4 * 7 * 3 + 5) * 9 +3 + 3 * (5 + (7 * 5 + 4 * 8 + 9 * 2) + 3) * 8 * 7 +(8 + 3 + 7 * 7) + (3 + 8) * 4 + 2 +2 + 9 * (7 + 3 * 3 * 8) + 9 + 3 +2 * ((5 + 7 + 9 + 7 * 3 * 7) * 2 + 4 * 4 + (2 + 2 + 7) + 3) + 6 +8 * 3 * (6 + (6 * 8 * 2)) + 9 + 9 * 3 +(9 * 7 + 6) + 5 * (7 + 5 + 4) + 2 +(9 + 4 * (5 + 5 + 4 * 2) * 7) * 7 * 9 * 5 * 3 +7 * 6 * ((5 + 6 + 8 + 4 * 3) + 2 + 2 * (4 + 6 + 2 + 7) + 8) + 4 +6 + 5 + 3 * (4 * (8 + 8 + 7 + 2 * 6) + 3 + (7 * 6 * 3) * (9 + 5)) + 4 +9 + 4 + (7 + 3 + 3 + 2 + 8) + (2 * (4 * 2) + 8 + (9 + 9 * 9 * 5 + 2 + 3) * (6 + 4 * 5)) * (4 + 8 * 2) +(2 * 3 + 7 * 5 * (2 + 3 * 7) * 3) + 9 +9 + (6 * 6 * 3) * 3 +((3 * 6) + (5 + 5 * 9 * 7 + 8) * 7 * 8) + 8 + (6 * (4 * 2 + 6 + 7 + 2) * (2 * 8 + 3) * 5 + 7) + 5 + 7 +(2 * 3 + 4 + 9 + 8) + (5 * 4 * (5 + 5 + 3) + 2 * 8 + 2) +7 + 7 + 7 + 4 + (7 + 7 + 8) +9 * (8 + 7) + 2 * 6 +6 + 8 + 8 * 6 * 8 + ((5 + 2 * 2 * 6 + 8) + 9 + 3 + (5 * 3 * 8) + 7) +4 * 9 + 8 + (5 * (5 + 6 * 8) + 5 + 4 + (7 * 2 * 6)) * 5 +(8 * 5 + 3 * 6 + 8 + 6) + 5 * 2 + 6 + (3 + 8 + 3 + 7 * 7 * 6) +5 + (2 * (6 * 8 * 9 + 3 + 9 * 6) + 8 * (7 + 6 + 8) + 9 + 7) + 6 * 6 +7 + 2 * (5 + 4 * 8 + (8 + 9) + 3) * 3 +2 * ((8 + 3 + 2) + 9 * (6 * 2 * 5 * 6)) * 7 * 2 * 9 +((6 + 6) + (4 * 4 + 7 * 6 * 3) * (2 + 2 + 5 + 8) + 7 + 5) + 6 * 8 * 7 * 4 * 7 +6 + 5 * 8 + (8 + 5 + 4 + 6 * 5) + 8 + 9 +2 + (2 + (8 + 8) + 2) +3 * 3 * (8 + 2 + 3) * (2 + 4) + 7 +9 * 2 + 9 + (3 + 5 + 5 * 2 * 2 + 7) +(7 * (2 + 6 * 7 * 2) + (8 + 4 + 4) + 4 + 5) + 3 +(7 * 5 + 7) + (3 * 9 * 4 * (8 * 2 + 9) * 8) * 6 + 9 * 9 +9 + (2 * 5 + 2 * 7 * 3 * 7) + 5 + 3 +(3 * (5 * 3 * 4) * (5 + 2)) + 7 +(7 + 4) + 9 * 2 +3 * (5 * 6 * 5 * 8) * 2 * 2 * 7 * 7 +(7 + (7 * 2 * 5 * 6 * 7 + 2)) * 5 + 9 * 9 +(5 * (3 + 6 + 4 + 4 * 8)) * (8 * 6 * 6 + (4 + 8)) * 2 + 8 + 8 +((9 * 8) * 3 * 7 * (3 + 9 * 8 + 6)) + (4 + 2 + 7 * 9) +(6 * 4 + 8 * 2 * 9) + 5 * 5 * 3 +5 + 6 * 9 * 7 +(2 * 5 * (2 + 8 + 5 + 2 * 5) * 2 * 9) + (6 + 8 * 2) + 5 +7 * ((4 + 8 + 8) * 7 * 3 * 3 * 5 + (5 + 6 + 9 * 6)) +(6 + 5) * 2 +7 * 2 + 4 + (2 * 4) + 5 + 2 +8 * 6 + 9 * (3 + (4 + 2 + 9 + 3 + 8) + (8 + 6 + 3 * 9 * 3 + 7) + 4 + 2) + (5 + 4 + 6) +2 + ((7 * 4) * 9 * 8 + 2 * 8) +6 + 2 * 8 * (5 * 9 * 7 * 9 + (3 + 2 * 9 * 8 * 6 + 7)) * 7 * 6 +9 * 6 * 9 * 8 + (2 + (7 * 4 + 6) * 8 + (3 * 7 + 3 + 4 + 2)) * 7 +5 * 9 * 8 * 2 + 7 +9 + (2 * 6 * 6 * 3) + 7 + 4 + 3 +(9 * 6) * ((5 + 3) * 5) + 2 + 3 + 6 * (6 * (8 + 6 + 2 * 2 + 9 + 8)) +((2 + 5 + 6 + 2 + 5 + 9) + 4 * (5 + 7 * 5) + 2) * 3 + 9 * (6 + 9 * 8 * 7) + 7 +2 * 9 + (4 * (3 + 7 + 3) * 4) + 5 + 9 +((9 * 4 * 4) + 3 + 2 + 3) + 8 + ((7 * 6 * 5 * 2 * 9) + (9 * 6 + 8 + 3 * 8 + 4) * (6 * 8) * 6 + 8) * 5 + 6 +2 * 8 + 5 + 4 +6 + (6 + 6 + 6) + 3 * 4 +6 + (7 + 4 * 9 * 2 + 7) + 7 + 3 * 2 * 2 +(7 * 7 + (3 * 6 + 4 + 9) + (5 * 5 * 7 * 7 + 4 + 6) * (4 + 9 + 7 * 5 * 9)) * 2 + 8 + 3 * 8 +4 * (5 + 5) + (8 + 5 * 4) + 7 * (5 * 6) +9 + 4 * 4 * 3 + 6 + 3 +5 + 5 * (6 + 6 * 5 + (3 + 5 * 6) + (2 * 9) + 2) * 6 + 8 + 5 +5 * 8 * 8 * 5 * 3 + 2 +6 * 2 + 3 + 7 + (6 + 4) + 3 +(5 + 7 + 6 + 5 + (9 * 5 + 5 + 6) + 8) + 3 * 6 * 9 * 6 +(8 + 2 * 7 * 2 * (8 + 9)) + 7 * (4 + 4 + 5 * (8 * 9 * 8 + 4) * (8 + 8 * 5)) * 8 +8 + ((4 * 8 * 8 * 7 + 6 + 9) + 5) + 9 * 4 +((4 * 8 * 5) + 6 + (8 + 4 * 5 + 2) * 5 * 8) + 6 * 3 +8 * ((2 * 9 * 9 * 7 * 2) + 4 + 8 + 2) +2 * 9 + (9 + 6 + 7) * ((8 * 3 * 3 * 7 * 3 + 9) + 4 * 4 + (8 * 7 * 6 * 3) * (6 * 5 * 2 + 6 + 3)) + (2 + 9 + 9 * 5 * 7) +(4 + (9 + 3 * 6) * 8) + 2 +7 + 5 * (3 + 7 * 3 + 7 + (4 * 7) + 3) + 4 * 9 +(3 * 7 * 9 + 7) + 6 * 6 + 7 + (9 * 3) * 7 +6 + (9 + 5 + (9 + 9 * 9 + 8) + 2 + 5 * 9) +9 * 4 +3 + 8 + (4 + 2 + 3) + (7 * 9 * 9 + 3 * (4 + 5 + 3 + 4 * 3) + 8) * 8 * 9 +7 + (7 + 9 * 2 * 2 * 5) +8 * ((5 * 8 * 7 + 5) * 6) * 7 * 5 * 8 +7 + 6 * 6 * 6 * 5 * (4 * (2 + 6 + 6 * 3 * 7)) +((8 + 2 + 2) * 2 * 4) + 5 + (8 + 8 + 2 + 4 * 8 + 9) + 9 +(2 + (5 * 3 * 2 + 3 + 5 + 6) * (5 + 8 + 5 + 3 + 2) + (3 + 3 + 9)) + 9 +(6 * 2 + (3 + 3 + 3 * 6 + 8)) * (6 * (4 + 9 * 9 * 9) + 6) * 4 * 2 +7 + ((9 + 3 * 6 + 4) + 4 * (3 * 9 * 7 * 2) + 2 + 7) * (2 + (5 + 8 + 7) * 9 * (6 * 2 + 3 * 7) + 3) +9 * (7 + (6 * 7 * 2 * 3 + 7) + 4 + 4) * 9 * 7 + (2 * 6) + 8 +6 * (5 + 5 * 5 * (6 * 3) + 6) +7 * 8 * 7 * (9 + (4 + 3 + 9 + 3 + 9)) * 9 +(9 + 6) + (2 + 8) * 9 * 3 +(3 * 9) * 3 * 6 * 5 * 9 +8 * 2 + (7 * 6 * 6) +(9 + 4 * 3 * 9 * 4 + 3) * 3 +2 * ((4 + 9 * 4 + 3 * 9) * 9) + 2 + 2 +8 + 2 * 7 + (4 + 8 * 6) +7 * ((7 + 8 * 9) + 4 + 4 + (7 + 4 + 7 + 5) * 3 + (6 * 9 + 2 * 9)) * 8 + (5 * 7 + (3 + 7 * 3)) +3 * 9 + (3 + (9 + 8 + 4 * 5) + (4 + 2 * 2 * 4)) * 2 + 3 +(5 + 3 * 5) * 8 * 9 * 5 + 2 * 2 +(3 * 4 + 8 + 2 * (7 * 8 * 8 * 9 * 3 * 3) * 7) + 7 + 4 * 7 * 7 +2 * 6 * 6 + (6 * 7 + 8 * 8 * (5 * 9 * 3 + 2 * 2 + 4) + (4 * 5 + 7 + 2 * 8 + 6)) + (9 * (5 + 6 + 4) * 9 * 8 * 8) * (4 + 8 + 7 + 6) +(2 * (6 * 2 * 4 * 7 * 4)) + 4 * 7 * 5 +9 * 7 + 2 + (4 * (4 * 5) * 3 + (2 * 3 + 4 * 4) * 9 * 6) +6 * 6 + (8 * 3 + 5 + (8 + 6 * 2)) * 6 + (7 * 3 * (8 * 8 * 2 * 3) * 7 * 5 * 8) +5 + 2 + 9 +7 * 9 + (8 + 3 + 9) * (3 + 8 * 7) +(7 * 9 * 3 + 8) * (8 * 9) + 7 * 8 * 9 + (2 * 3 + 6 * (6 * 2 * 7) * (2 * 7 + 6 + 8 + 4) + 8) +2 + 2 + 4 * (8 + 2 * 8 + 2) + 5 * 8 +2 * 6 * 8 + (6 * 7 * 2 + 9 + 9) +4 + (3 * 5 + 6 + (9 + 2 + 9 + 4 * 7) * 8 + 7) +9 + ((5 + 2 * 8) * 6 + 9 * 5) +6 * ((2 * 2 * 7 + 8 * 5) * (7 * 7 + 3 + 5 + 6) + 8 * 3) + 9 +2 * 5 + ((5 + 5 * 9) + 5 + 6) * 6 +5 * 5 + 7 * (2 * 9 * 2 * 5) +5 + 2 + 3 * (5 * 5 + (3 * 2) + 8) +(5 + 7 * (4 + 2 + 5 + 7 + 6)) + 9 * 9 * 5 + 4 * 2 +(6 + 8 * 8 + (4 + 5 + 9 * 6 * 9 * 7) + (2 + 7 * 3) + 2) * 5 * 7 +9 * 5 + ((3 + 7 * 7 * 3 + 3) * 6 * (5 * 5 + 8 + 9 * 2 + 7)) + 8 +(5 + (5 * 3 + 5) + (3 * 8 * 7) + 2 * 5 * (8 + 2 + 5)) + 7 * 5 +7 + ((2 * 4) * (3 + 2 * 8 * 3 * 8) * 5 + (9 + 7 + 6 + 3 + 7 * 9) * (4 * 4 + 6 + 9 * 7) * 4) +2 + (8 * 2 + 8 * 4 + 3 + 3) * 9 * 6 + 9 + 2 +8 + 3 + ((3 * 9) * 4 + 6 * (2 * 3 * 3) + 2 + 5) +3 * (7 + (2 * 5 + 7 * 6) * 6 + 9 * 3) + 7 * (3 + 2 + 4) + (5 * 4) + 9 +((2 + 6 + 4 + 4 * 9) * 2 * (4 + 8 + 4) * 7 + 2) * 3 * (6 * 6) +5 * 4 * (2 * 9) +(3 + 4 * 3 + 4) + ((9 * 2 + 2 + 8 * 8 * 9) * 7 * 7 * (7 * 8 + 3 * 2) * (8 + 2 * 7 * 7 + 7 + 7)) + 8 + ((2 * 4) + 8 * 2 + 2 + 3 + 2) +8 + ((8 * 2 * 2 * 5) + 2 * 8) +9 * ((6 * 8 + 9) * 8 * 7 * 2) * 5 * 3 * (7 * 8) + 6 +(3 + 5 + 8 + 7 * 2) * 2 + 8 * (5 * (3 + 3 * 9 * 3 * 9) * 9 + 5 * (2 + 5 + 8 * 3)) + 4 * 3 +(8 + (6 * 5 * 9 + 3 * 3) * 5) + (4 * 3 + 7) +5 + 6 + 3 + 6 + ((5 + 4 * 2 + 7 * 8 * 3) + 5) +6 * 4 + (2 * 6 * (5 * 4 + 7 + 9 * 5) + 9 * (5 * 7) + 6) * 7 * 8 +5 * 7 * ((7 * 6 * 8) + 5 + 8 * (3 * 3 * 4 * 2 + 7 + 4)) * (9 * (5 * 8) + 3) * 3 +4 + ((7 * 6 * 4 + 3 + 6 + 8) * 7 * 4 * (6 + 3 * 5)) +9 * 8 +((5 * 5) * 7 * 4 * 2 * 9 + (7 * 6 + 6 + 7 * 7)) + 8 * 7 + 6 +3 + (5 * (2 + 4 * 4 + 4) + 5) * 4 + 2 +(4 + 3 + 4) * 3 * 7 + (2 * (6 * 3 * 7 * 8) * 8) +(4 * 9 + 3 * 2 * 5) * 5 + (5 * 4 + 2) +8 + (2 + (2 + 4 + 2) + 8 + 7 + 6) + 9 + 3 * (7 * 4 * 6 + 7) +9 * 7 +9 + 7 * 6 +6 + 7 * 3 + 5 + ((4 * 6 + 9 * 6 * 6) * (8 + 8 + 2 + 8 + 6 * 5)) + 9 +3 * 6 * 3 * (4 + 8 * 6 + 5 * 7) + 8 +7 * (8 + 2 * 6 + 4 * 2) * 7 + 8 * 5 +7 + ((6 * 2 * 9 * 7 * 5 + 5) * 2 + 7 + (3 + 3 + 5 * 6) * 2) * (6 + 8 * (8 + 4 + 4 + 7 * 4 + 9) * 6) * 4 * 3 +6 + 5 * (9 + 2 * 7 + 7 + 4 * 9) * 2 * 8 +3 * 5 + (7 + 5 * 2 + 2 * 8) + 9 * 2 +8 * 8 * 4 + (3 + 7) +(2 * 8) * 2 + 7 * 6 + 5 * (7 + 4) +8 + 5 + (2 + 3 + 7 * 7 * 8 * 2) + 2 + 8 * 6 +(5 * 7) + (7 * 4 + (2 + 9 + 7 * 8) * 7 + 2 * 5) * 2 * (7 + (3 * 7 * 6) + (8 * 6 * 6 + 6)) + 8 * 9 +5 + 9 + 6 * 6 * 8 * (5 + 7 * 8 * 2) +((6 + 2) * (6 + 5 + 5 + 6 + 9) + (4 + 2 + 8 + 9) + (4 + 9 + 6 * 3 + 4 * 9) + 6) + (4 + 2 + 2) +(7 + (4 + 8 * 4 * 9)) + 6 + 8 +9 * 7 + 4 * (6 + 4 + (4 * 4 * 3 + 9) * 9 + 8) + (3 * 5 + (3 * 5 * 6 + 6 * 2 + 4) * 7 * 3) + 8 +6 + 9 * 8 * ((4 + 7 * 9 + 8) + 7) + 7 * 7 +5 * (9 + 9) +(5 + 5) + 2 + 7 * (7 + 5) + 6 +4 + 3 * (8 * 7 + 4 * 3 * (2 * 9 * 4)) * 5 +((6 + 5) * 5 * 6) + 8 + 7 + 4 +9 * 9 + (6 + 6 + (7 * 6 + 2)) +9 + 4 * 6 * 9 + 9 +4 * 9 * 8 + (5 + 5 * 8) + (2 * 6 * 7) +9 + 8 + ((9 + 4 * 6 + 3) * 8 * 8 * 4 + (7 * 5 * 9 * 9 * 4 + 4) * (4 + 6 * 7)) + 5 +5 * 7 * (6 * (2 * 2 * 9 * 3)) + 2 * 7 * 5 +9 * (6 + 7 * 7) * 3 * 2 + 4 +(2 * 3 + (7 * 3 + 7) + 6 * 3 * (4 + 7 + 6 + 2 * 9 * 5)) + 9 * 4 + 2 +9 * (4 * 6 + 8 * (4 + 4)) +(8 * 4 * 4 + 6 + (8 + 9 * 4 * 7 * 3) * 4) * 7 * 4 * 8 + (4 * 3 * 6 * 5) + 5 +(3 * 4 * 6 * 6 + 3) * 6 +9 + (5 * 8 * 8 * (2 + 2 + 7) * 8 * 5) +((5 + 4 + 2 + 9 + 2 * 8) * 2 * 2 + 4 + 7) + 2 + 6 +(5 + (9 * 5 * 9 * 9) * 3 * 7 + 2 + 9) + ((5 + 4) + 4 * (8 + 3 + 4 + 8)) * 6 + 4 * (5 * 3 + 9 + 6) + 6 +((8 + 4) * (4 * 9 * 8) * 7 + 4 + 5 * 6) + (8 * 9 * 4 * 2 + 2) +(8 * 7 + 8 + (6 + 2 + 4 + 8 * 4 * 8) + 7 * 4) * (6 * 2 + 6 + 2 + 3) + ((5 * 8 * 8 + 7 * 5 + 3) + 8 * (6 + 6 * 4)) +5 * 8 + (4 * (3 * 9 * 5 * 5 + 5)) * 7 + 3 +5 * 8 + 3 + 4 +3 + ((9 + 3 + 6) * 4 * 9 * (9 + 8 * 3 * 6) + 7 + 2) + 4 * (5 * (9 * 2 * 2) * 9 * (6 * 8 + 4 * 8)) +((2 * 5) + 5 + 4 + 9 + (4 + 5 * 4) * 6) * 8 + 3 +5 + 7 * (9 + 6 * 7 * 5) +7 * (5 * 3) + 7 * (7 + 6 + 8) +(5 + 7 * (8 + 8 * 3 * 7 * 6) + (6 * 4)) * 2 + 9 +8 * (6 + 5 + 6 + (3 + 7 * 3 + 9 * 8 * 6)) +(6 + 5) + 9 + (8 * 7 + 8) + 4 +6 + 2 + 4 * ((2 + 2 + 5) + (5 + 2 + 6) * 4 + 2) * 5 * 4 +8 + 6 +(6 + (4 * 5) + 8) * 8 * 6 + 2 * 2 + 7 +7 + 4 + ((2 + 7 * 2 + 9 + 9 * 7) + 5) + (9 * 8 + 4 + 7 + 8) + 5 +4 + 2 * 2 * 6 + 7 * ((7 * 2 + 3) + 7 + 6 * (8 + 4 + 2 * 6) + (9 + 7 + 3)) +(4 + 8 * 7 * 8 + 9 * 8) + 6 * 6 * ((9 + 2 * 2 + 7) * 3 + 3 * 9) +6 + (3 + 2 + 2 + 4 + (5 + 9)) * 8 + 4 + 7 +((5 * 4 * 7 * 9) + 7) + 7 + 4 * (8 * 7 * 3) + 3 +5 * (6 * 8) + (3 * 7 * 3 * (8 * 9 + 6 * 2) * 9 + 3) * 7 +6 * 5 + (7 * 4 * 2 * 4 * 6) + (5 + (3 + 3 + 9 + 9 * 4 * 6) + 2 + 9 * 9 * (8 + 5)) +4 * 5 * 5 * 3 + 5 +2 * 6 + (2 + 7 * 6) * (7 + 3 + 3 * 3 * (6 + 7) * 7) + (4 + (8 * 7 * 6) + 4) * 9 +3 * 9 + (8 * 4 + 8 * (6 + 7 * 3 * 3) * (6 + 8)) +2 * 6 * (9 * 6 + 8) + (2 + 3 * 7 * 4 + 3) * 2 * ((8 + 6 * 5 + 8) * 5 + 4 * 8) +6 + 3 * (6 + 3 * 7) + 8 + 7 * 3 +8 + 3 * (3 + 4 * 5 + 6 + 8) + 7 + 5 * 2 +2 * (2 + 7 + 4 + 6) + (4 * (9 * 9) + 8 * 8 + 5) + 7 * 5 * 7 +7 + (5 + (5 * 8 + 2 + 7 * 4) + (9 * 9 + 4 * 3 * 5 + 4) + 4 + 5 * 3) +(8 + 2) * 9 * 6 * 7 +3 * 5 + 5 * ((4 * 3) + 3 * 3 + 8) + 5 * 5 +4 * 7 * 6 + 4 + (4 * (4 * 5) * 3 + 2 + 8 * 4) +2 + 7 * (2 + (7 + 6 + 8 + 3 + 4) * (7 * 9 + 8 * 9) * (2 + 5 * 3 + 9 + 2 + 9)) +6 * (6 + 2 + (8 * 3 + 7 * 5 + 6 + 6) * (4 + 2 * 6 + 5) + (7 * 8 * 8 + 8) + (9 + 4 * 8 * 3 + 4)) * 3 +(6 + 9 + 8 * 6 + 8) + 4 * 7 + 2 + 5 +(9 * (2 * 9 + 8 * 5 * 2 + 3) + 9 * 7) + (6 + (7 * 6 + 9 + 9)) +6 + 6 + (2 + 7 * (5 * 3 + 3) * 7 + (2 + 6 + 8 + 3 * 8 + 4) * 2) * 5 + 5 * 4 +(6 * 7 * 6) * ((4 + 4) + 2 * 6 + 2 + 3 * 8) * 4 * 2 * 7 * 9 +9 + ((3 + 6 + 6 + 2 + 3) * 5 + 6 * 6 + 3 * (4 + 4 * 8 + 4 + 5 * 2)) * 5 * 7 +8 + (7 * 4 * 6 * 4 * 8) * ((4 + 6) * 5 + (9 * 6) + (7 + 9 + 3) * 2) * 5 * (2 * 5 * (2 * 4 * 8 * 5 * 4 * 3) * 9 * 3) + 5 +(7 + 2 + (6 * 7) * 5) * 3 +3 + 5 * 9 + (9 + 9) * 3 +9 * 3 + (9 * 4 * 9) * 8 * 3 +4 * 4 + 6 + (7 * 8 * 6 * (8 * 6) * 6) +(6 + 5 * 7 + 3) + (4 * 8 * (5 * 7 + 9 + 9 + 2)) + 5 +2 + (2 + 9 * (4 * 7 * 3 * 3) + 8) + 9 * 9 + (6 + 9 * (4 * 5 + 6 * 6 + 8)) * 5 +9 * 7 + 9 +7 + 7 * 7 * (5 + 5 + 7 * 7) * 6 +2 + 2 + (6 + (8 + 6 * 9 + 9)) +(7 + 6 + 3 * 3) * 8 +8 + (7 + 9 + 9 * 2 * 5 * 3) + 5 * 7 + 3 +5 + 8 * (5 + 2 * 7 + 4 * 4) + ((8 * 8 + 2 + 5 + 5) * 9 * 3 + 9 * 6 * (4 + 7)) * 2 +8 * 5 * 3 + 2 * (8 * 8 + 8 * 9) + (5 * (9 + 3 * 2 + 7 + 3) * 2) +8 + 4 + 2 + 4 + 8 * 4 +9 + 2 * 8 + 8 * ((2 + 8 * 2) + 2 + (8 * 4 + 7 + 7 + 9)) + 9 +7 * (9 + 6 + 8 * 7) + 5 + (8 * 7 + (4 + 3 + 9 * 6) + 9 + (5 * 7 + 5 + 6 * 2 + 2) + 2) * 4 +7 + (9 * 7 + 5 * 9 + (4 + 9 * 2 + 8 * 8 + 3) * 9) +(5 * 9) + 9 + (7 + 5 * 2 * 2) * (2 + (8 + 4 + 5 * 5 + 2)) * 6 + 6 +9 * (9 * 3) * 2 + (2 + 3 * 6 * (8 * 4) * 4) + (9 + 8 * 3 * (7 + 6 * 7 * 6 * 5) + 3) +6 * 9 * (9 + 9 * 9 * (3 + 2 * 9 * 6 * 6) + (4 + 8) * 3) * 4 + 7 +(8 * 4 + 8 * 3 * 7) + ((9 + 9) + 3 * 3 * 5 + (3 * 7 * 3 * 9 + 4)) + 9 + 9 + ((9 * 6 * 7) * 9 + 8 + 9 * 8) + 9 +(3 * (3 * 2) + 5 + 9) * 6 + 5 * 3 +(5 + 5) + 5 * 8 * 3 * 3 * (9 * 9 * (4 + 5 + 9) + 4) +3 * 8 + 9 + 8 + (6 + (9 * 3 + 7) + 9 * 3 * 6 * 2) + 6 +3 + 9 + 3 * 5 +5 * 7 + 4 * (2 * 7 * 7 * 5 * 7 + 9) * 4 +8 * (3 + (8 * 7 + 8 + 6 * 5 + 5) * 4) +9 * 6 * (8 + 6) * 5 + 7 * 6 +(8 + 2 + (4 * 9 * 9 + 3) + 5) + 4 +(9 * 7 + 3 + 8) * 3 * 5 + 9 + (2 * 9 + 7 + 8 + 8 + 5) +3 * (8 + 9) * 6 +4 + 6 + 6 + ((5 * 5 * 2 + 9 + 7) + 6 * (6 + 4 * 8 * 9 + 8) * 4 + 9 + (9 + 4 * 5)) + 7 +8 + 8 * (9 + 8 * (2 * 7)) + 6 * 9 +(3 + (8 + 2) + 8 + 8 * 6) * 5 +(9 * (2 + 3 + 3 + 5) * 8 * 7) + 6 + 9 + 6 +(8 * (7 * 5)) + 6 * 6 * ((3 * 8 + 7 + 2 * 7) + 6 * 3 + 6 + 9 * 9) * 4 +(6 * (4 + 3 * 3 * 9 * 3 + 6) + (7 * 7 + 6) + 8 * (3 + 2) * 5) + 4 +(5 + 4 * 3 * (8 * 6) * (3 + 6 + 3) + 7) + 8 + ((3 * 7) + 9 + (7 + 4)) * 3 +(9 * 5 * 4 * 6) * 6 * 2 + ((8 + 6 * 5) + 4 + 5) * 9 +(3 * 8 + 8) * 9 + (8 + 4 * 7 + 8 + 7 + (7 + 8)) +6 + ((8 + 9 + 9 * 9) + 2) * 5 + 7 +2 + (8 + (6 * 9 + 6 + 2 + 3 * 8) + 6 * 9 + 3) + 9 + 2 +6 + (5 + 3) * 3 + 9 * 3 +9 * ((9 + 7 * 2 + 5 * 7 + 2) * (9 * 5 + 6)) + ((9 * 7) + 4) * 3 +9 * (6 * 6 + (5 + 7 * 6) * (5 + 3) + 4 + 9) * 5 +(9 * 7 * 9) + 5 * 9 * 8 +7 * ((8 + 9 + 5 * 2 * 2) * 5 * 5 * 8 + 4) * (5 * 7) + 9 * (7 + (8 + 2)) +(3 * 6 * 6) + 7 + 2 + (9 * 2 * 4 + (5 * 8 + 8 * 6) + 8 + 6) * 9 +3 + (6 + 7 * 5 + 4 * 6) * 5 * 4 * 2 * ((3 + 3) * 9 + 9 * 5 * 4) +5 * (5 + 2) * 6 + (4 * 6) + 4 + 9 +(6 + 9) * 2 * 2 + 2 + (3 + 9 * (3 * 7 + 6 + 7 + 9 * 2) + 9 * 5 * (9 + 2)) +9 + (2 + 3 * 8 * 3 + 8 + 8) + 8 +8 * (3 + 4 + 9) + 5 + (2 + 4 + 3 * 4) +(2 + 6 + 4 * 9) * 9 * 3 * (5 + 5 * 9 + (6 * 5 + 7 * 6) * 8 + (7 + 7 * 8 * 8 + 8 + 6)) +6 * 6 * 6 + ((3 * 5 * 6 + 8 + 3 + 7) + 5 * (2 + 3 + 5 * 9 * 5) * 2) + (9 * (7 * 9 + 9) + (8 + 3 + 9 + 5 + 6) + 5 + 9) * 7 +((4 * 3 + 9 * 7 + 3 * 9) * 5) * 5 * 6 * 6 + 7 +((6 * 3 + 8 + 6) * 6 + 4 + (6 + 5 + 6 * 5 + 8 * 2) * 7 + 2) * 9 * 6 +9 + 5 * 2 * (8 + 8 * 9 + 7 * (4 * 8 + 2)) + 8 * 5 +(4 + 7 * 4 * 4) + 5 * 4 * 2 +(8 + 3 * 3 * 6 * 4 * 7) * 7 * 3 + 8 +3 * 8 + (5 + 7 * 7 + 6 * (4 * 6 * 6 * 9 * 6 + 5) * 2) * 7 + 6 * 7 +5 + 2 + (7 + 9 * 3 + 8 * (2 * 4 + 4 * 3 * 9)) * 5 * 9 + (5 * 7 + 6 * 2 + 5 + 9) +9 * 3 * (6 * 7 * 7) * 2 +3 + 8 * (2 + 6 + (8 + 8 + 9) * (3 * 5 * 6 + 7 + 2) + 2 * 9) + 4 * 7 +4 + (7 + 9 * 8 * 7) * (9 + 7) * 7 + 6 * 3 +(5 + 4 * 4) + ((8 + 9 + 4 * 9 * 5) * (3 * 3) * 8 + (6 + 5 + 8 * 7)) * 9 + 8 * 8 +6 + (4 * 9 * 2 + 2 * 2 + 6) + (9 * 7 + (6 + 5)) * (7 * (2 + 5) * 9 + 7 + 5) * 4 +(2 + 4 * 7 * 7 + (2 * 7) + 8) + 5 * 6 * 9 +7 + 7 + (5 + 5) + 7 * 2 +4 * (9 * 5) * 5 * (8 + 4 + (4 + 3) + 3) +4 * ((7 + 5) + 3 * 4) * 5 * 2 + 6 + 3 +(7 + 3 * 2 + (4 * 2 * 5 + 9 * 5) + (8 * 2 + 5 + 9 + 8) + 7) + 8 + (7 + 9 + (4 + 9) * (9 + 6 + 2 + 8) + (4 + 2 + 8 + 9)) + 3 * (9 * 7 * 3) +5 * (6 * 6 * 8 + 6) * 4 + 9 +(4 + (7 * 7 + 2 + 8 * 3 * 3) + 9 + 4 + (9 * 2) + 6) + ((2 + 7 * 2) * 5 + 3) * 8 + 8 +2 * 5 * (6 * 6 + 4 + 5 * 2 + 9) + 5 * 7 + (5 + 8) +9 * (3 * 9 + (8 + 5) + 6 + (6 * 7 * 9 + 3 + 8 * 4) * 9) + (6 + 3 + 9 + 9 * (5 * 3 + 8) * 8) +(6 * 9 * (6 + 5 * 2 + 8 + 9 + 8) + 5 + 6) + 4 +(3 + 5 * 9) + (8 * 2 * 4 + 3 + 9 * 3) * 7 +((3 + 2 * 9 + 7 * 9) * (9 * 7 * 3 + 5 + 6 * 3) + 6 * 8 * (8 + 9 + 9)) * (7 + (7 * 3) * 9 * 3 + 5) * 5 +((9 * 7) * 2 + 5 + 4) + (2 + 5 * 5) +(3 + 6 + 2 * 7) + 6 + 6 +9 * ((4 * 6 + 4 + 5 * 7 * 9) + 9 + 9) + 5 +6 * 8 * 4 + 9 + 4 +5 + (9 * 5) * 6 + (3 * 4 + 7 * 7 + 7) + 7 +(8 * 6 * 8 * 3 * 8 + 7) + 4 + 4 * (4 * 6 * (9 + 5 * 2) + 5) * (4 + 5 * 6 + (6 * 4 * 6 * 5) * 8 + (4 + 5 * 2)) +3 * 8 + 8 +5 * 8 * (9 + (8 + 2 + 4)) +9 + (2 * 5 * 9 + 2) + 3 +(2 + 6 + (3 * 6 + 2 * 4 + 4) * 3 * 7 + 6) * 6 * 6 + 6 +((9 + 3 * 7) + (2 + 8)) * ((2 * 3 + 3 + 4) * 8 + 5 + 9 + 3 * 9) +(3 * 9 + 3 + 6 * 8 * 7) * 3 * 5 + ((6 + 8 + 4) + 8 * (7 * 4 + 6 + 5) * 3 * 9) +9 * 4 + 7 + (8 + (4 + 6 * 6 * 7 + 9) * 7 + 4 * (5 + 7 + 7) + 2) * 4 * 5 +2 * 7 + ((6 + 4 + 3) + (8 * 8 * 7 + 2 + 4) + 3 * 9 * 9 + 7) +4 + 6 * 2 + 8 + (6 * 9 * 6 + 6) * 9 +3 + 3 * 8 + 9 * (7 + (2 + 8 + 5 + 5) * 7 + 3 * 2) * (7 * 7 + 7) +9 + 4 * 9 * 2 * (4 * 9) +9 + 4 * 5 + (4 * (2 * 8 * 5 * 7 * 8) * (3 * 8) + 6) + 3 * 4 +7 + 3 * (8 + 7 * 9 * (2 + 9 + 4) * (3 + 5) + (7 * 9 * 2 * 8 + 9 + 8)) * (9 * (2 * 7 * 9) + (6 * 8 + 9 + 7) + 3 + (2 + 3 + 4) + (5 + 8 + 4 * 9 + 7)) +3 * 9 + 4 * (7 * (5 + 4 + 9 * 3 + 3 * 4) + 6 * 6) +3 + (8 + 8 * 9) + 9 + 5 * (7 + 4 * 3 * (7 * 4 + 2 + 8 * 4)) +(8 * 2 * 4 * 6 + 4) * 5 * 9 * (8 * 5 * 5 + 7 + 8 + 5) +2 + (5 * 2 + (2 * 8 * 3 * 2) * 5 * 5) + 4 + 9 + 2 +7 + (5 + 5 * 3) +4 * 6 * (5 + 2 * 3 * (3 + 8 * 3)) + 9 * 4 +2 * 7 * (8 * (2 * 3 * 8 * 8 * 5) + 2 + 2 + 5) * 7 +2 + ((5 + 2 * 8 * 3 * 4 * 7) + 4 + 3 + 5 * 5 + (5 * 8 + 6)) +3 * 7 * ((9 + 8) * 8 * 3) + (9 * (8 + 8 + 2)) * 9 * 9 +5 + (5 * (7 + 8 * 2 * 9) * (7 + 5 + 2 + 5 + 4 + 2) * 4 * 7) + 2 + ((6 * 7 * 2 + 9) * 6) * 9 +6 * 6 + (2 + (6 + 4) + (4 * 8 + 2 + 6) + 8 * 3) +2 * 3 + 5 + ((7 * 8 + 8 * 5 * 8 * 9) + 2 * 4 + 2 + 8) +(8 + (9 * 9)) + (6 + 2 * 7) +2 + 5 + 4 + 8 + 4 +8 + 2 + ((5 * 5 + 5) + (6 * 8 + 6 * 3) * 8) * 7 + 6 +9 * ((2 + 5) + 2 + 8 * (5 + 7 + 5 * 3) * 6) + 9 +9 + 6 + ((9 * 7 * 7) + 5 * 9 + 8 * (4 * 9 + 3 + 3) * 5) + 7 * 2 +(3 * 3 + 5 + 6 + 5 * 5) + 8 * 4 * 4 + 2 +7 * 2 + 3 + 9 * 4 + 4 +5 + (2 + 9) + 5 + 3 + 8 * 6 +9 * 3 + 5 + 3 * (6 * (4 * 8 + 6 * 9 * 9 + 6) * 7 + (9 * 2 * 3 + 7)) +7 * 8 + 3 + (7 + 3 + 9 + 7 * 2) + (9 + 6 * 3 * 3) +((9 * 7) + 2) + 9 * (4 + 4) +((9 + 5) * 2 + (2 + 4 * 4 * 3 + 9 * 9)) + (7 + (7 * 6 + 4) + (9 + 7) * 9) + 8 + 9 +4 + 7 * 3 + 2 * (7 + 2 * 8 + 9 * 3 * 3) +5 + 3 +(2 + 3 * 5 * 6 * 2 * 2) + (8 * 8 + 3 * 3 + 7 * (7 + 3 + 9 * 8)) + 7 + 5 +(7 + 3 * 5) * 7 +4 * 6 + (6 + 7 + 9 * (3 + 4 * 4) + 3 + 2) * (6 + 8 * 9 * 6 * 5 + (2 * 5 * 8 + 8 + 5 * 2)) +8 * (7 + 5 * 8 * 7 + 6) * ((4 + 5) * 9 + 9 * 2 * 7) * 5 + 8 +6 + 8 * 5 +(8 * (7 * 4) + 5 * 9 * 9 + 3) * 7 +8 + 5 + 7 + (8 + (6 + 5) + 7 + (7 * 9 * 2 * 6 + 4) * 8) * 2 +((4 + 3 * 9 + 9) + 4 * (9 + 2 + 4 + 8 + 9) + 5 + 7 * 4) + 6 * 9 +9 + (9 * 8 * 3) * (8 * 6 * 7 * 8 * 6) +5 * 7 * (9 * 3 + 6 + 8 + 8 + 5) +2 + (2 + 7 * (5 * 7 * 3 + 2 * 7 * 8) + 7 + (5 + 8 * 5)) * 8 * 3 * 3 + ((6 * 5 * 8 + 8 + 9) + 6 * (8 + 3) * 6) +9 * 5 * 9 * 8 +6 + 5 + 7 + 2 + (8 + (5 * 5 * 7 * 3 + 7 + 7) + 2 + 7) +4 + 4 * 2 + 3 * 7 + 6 +4 + (5 + 3 + 2 * 8 * 5) + 2 +2 * 2 * 8 + (6 + 9 * 4 * 7 * (4 + 7 * 7 * 2) + 2) + 9 +4 * 7 * 8 + (3 * (9 * 2 + 4 * 4 * 5 * 5) + 5 * 2 * 7 + 7) + 8 + 5 +(8 + (7 + 9)) * 6 +9 + ((8 * 7 + 5 * 3) + 7 + (6 * 4 * 6 + 8)) * 5 +3 + (6 + 5 * 7 + 4 * 2) * (3 * 3 + 7 * 6 + 4 * (6 + 7 * 3)) * (4 + 8 * 9) +7 * (7 + (4 * 3) + 4 + 5 * 4) +8 * 2 * (9 * 7 + 5 + 8) + 4 * 8 + (3 * 3) +7 * (3 + 2 * 3) + ((2 * 8) * 4) * 8 +((8 + 3 + 4 + 7 * 5 * 6) + (3 + 2) * (8 + 6 * 9 * 4 + 9 + 2)) + 3 + 8 * (8 + (4 + 9 * 2 + 8 + 6 + 9) * 9 * 3 * 3 + 3) + 9 +4 * (7 * 4 * 8 * 5) + 7 * 8 * (2 * 4 * 5 * 4) +(3 + 8 + 6 * 6 * 4) * (4 * 6 + 8 + 3 * 6) * 5 +2 + (3 + (6 + 9 + 6 * 3) * 7 + (9 + 7 + 8)) + 9 * 7 +9 + 7 * (4 * 8 + 3 * 2 * 9 + 4) + ((6 * 8) + 3 + 7 + 7 * 8 * (9 + 5)) * 9 + ((3 * 9 * 8 * 8) + (5 + 2) + 2 * 4 * 3 + 8) +6 * 3 + 3 * (8 * 7 + (2 * 8 + 4 + 6 + 5 * 6) + 3 + 3 * (9 * 9 * 8 + 2 * 5)) + (3 + (3 + 5 + 6) + 8 + 9 * 4) + 8 +9 * ((7 * 6) * 9 * 2) * ((8 * 9 * 3 + 8 * 2) * 6 + 8 + 9 * 5 + 3) + (5 * 4) * (7 + 4) * 7 +(4 * 7 + 8 * 9) + (7 + (3 + 9 * 2 * 9 * 4) * 9 * 3 * 4 * 7) * 4 * 6 + 2 +6 + 9 * 6 + (2 + 9 * 4) * 8 +3 * (6 * 5 + (7 * 6 * 5 * 8) + 7 * 5 * 4) + (3 * (6 * 5 + 7 * 9) + (4 * 9 + 2 * 3) * 7 * 8 * 3) + 9 + 5 + 9 +3 + (2 + (6 * 3 * 8 + 3) + 4) * (8 * 9) * 7 + 6 +(2 * (7 * 9)) * 6 + 7 * 2 + 9 * 4 +((5 + 4 * 2) + (3 * 2 * 6 + 3 + 5 * 5) * 4 + (2 + 5 * 9 * 8 + 3 * 5) * (7 * 2 * 8 * 2) + (5 * 4)) + 7 * 8 + 9 +(8 + 4 + (5 * 4 * 6) * 2 * 8) * (6 + (9 * 4 * 5) * 7 * 5 * 4) + 3 + ((2 + 2) + 7 + 5 * 7 * 2 + 4) * 5 + (9 * 3 * (9 + 3 * 4 * 8 * 7 + 9)) +6 * 7 * 3 * (7 * 2 + (6 * 4 * 5) * (5 * 3 * 8 + 8 + 3 + 9)) * (7 * 9 + 7 * 5) +4 + 2 + (3 * (9 + 7) * 6) +(8 + (8 * 4)) + (7 + 3 * 5) + 4 + 4 + 7 +(7 + 7 * 4 * 4 * 4) * 4 + 3 \ No newline at end of file From 7b97178ded733b0aa9eab1a083a206213976b988 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Fri, 18 Dec 2020 17:55:58 +0100 Subject: [PATCH 57/60] refactor(day18): implement tokenizer --- day18/calc.ts | 15 ++- day18/calcToken.spec.ts | 30 +++++ day18/calcTokens.ts | 27 +++++ day18/solution.spec.ts | 50 +++++++++ day18/tokenize.spec.ts | 241 ++++++++++++++++++++++++++++++++++++++++ day18/tokenize.ts | 63 +++++++++++ 6 files changed, 420 insertions(+), 6 deletions(-) create mode 100644 day18/calcToken.spec.ts create mode 100644 day18/calcTokens.ts create mode 100644 day18/solution.spec.ts create mode 100644 day18/tokenize.spec.ts create mode 100644 day18/tokenize.ts diff --git a/day18/calc.ts b/day18/calc.ts index 85c226a..80da934 100644 --- a/day18/calc.ts +++ b/day18/calc.ts @@ -1,10 +1,10 @@ -const isNumber = (s: string): boolean => /^[0-9]$/.test(s) -const isSpace = (s: string): boolean => /^ $/.test(s) -const isOperator = (s: string): boolean => /^[+*]$/.test(s) -const isOpeningParenthesis = (s: string): boolean => /^\($/.test(s) -const isClosingParenthesis = (s: string): boolean => /^\)$/.test(s) +export const isNumber = (s: string): boolean => /^[0-9]$/.test(s) +export const isSpace = (s: string): boolean => /^ $/.test(s) +export const isOperator = (s: string): boolean => /^[+*]$/.test(s) +export const isOpeningParenthesis = (s: string): boolean => /^\($/.test(s) +export const isClosingParenthesis = (s: string): boolean => /^\)$/.test(s) -const findClosing = (expr: string, start: number) => { +export const findClosing = (expr: string, start: number): number => { let level = 0 for (let i = start; i < expr.length; i++) { if (isOpeningParenthesis(expr[i])) level++ @@ -16,6 +16,9 @@ const findClosing = (expr: string, start: number) => { ) } +/** + * @deprecated see calcToken + */ export const calc = (expr: string): number => { let a = 0 let op = '' diff --git a/day18/calcToken.spec.ts b/day18/calcToken.spec.ts new file mode 100644 index 0000000..b348e66 --- /dev/null +++ b/day18/calcToken.spec.ts @@ -0,0 +1,30 @@ +import { calcTokens } from './calcTokens' +import { loader } from '../lib/loader' + +const load = loader(18) +const input = load('input') + +describe('calcToken should calculate using the tokenized expression', () => { + it.each([ + ['1 + 2', 3], + ['3 * 3', 9], + ['1 + 2 + 3', 6], + ['1 + 2 * 3', 9], + ['1 + 2 * 3 + 4 * 5 + 6', 71], + ['(2 * 3)', 6], + ['1 + (2 * 3)', 7], + ['1 + (2 * 3) + 4', 11], + ['(2 * 3) + (3 * 4)', 18], + ['1 + (2 * 3) + (4 * (5 + 6))', 51], + ['2 * 3 + (4 * 5)', 26], + ['5 + (8 * 3 + 9 + 3 * 4 * 3)', 437], + ['5 * 9 * (7 * 3 * 3 + 9 * 3 + (8 + 6 * 4))', 12240], + ['((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2', 13632], + ])('%s = %d', (expression, expected) => + expect(calcTokens(expression)).toEqual(expected), + ) + it('should solve the puzzle input', () => + expect(input.map(calcTokens).reduce((total, n) => total + n, 0)).toEqual( + 7293529867931, + )) +}) diff --git a/day18/calcTokens.ts b/day18/calcTokens.ts new file mode 100644 index 0000000..b03df49 --- /dev/null +++ b/day18/calcTokens.ts @@ -0,0 +1,27 @@ +import { Token, tokenize } from './tokenize' + +const calc = (token: Token): number => { + switch (token.type) { + case 'op': + switch (token.op) { + case '*': + return calc(token.left) * calc(token.right) + case '+': + return calc(token.left) + calc(token.right) + default: + throw new Error(`Unexpected operation ${token.op}!`) + } + case 'value': + return token.value + case 'group': + return calc(token.group) + default: + throw new Error(`Unexpected type ${token.type}`) + } +} + +/** + * Calculate the expresssion using the tokenizer + */ +export const calcTokens = (expression: string): number => + calc(tokenize(expression)) diff --git a/day18/solution.spec.ts b/day18/solution.spec.ts new file mode 100644 index 0000000..092617a --- /dev/null +++ b/day18/solution.spec.ts @@ -0,0 +1,50 @@ +import { loader } from '../lib/loader' +import { calcTokens } from './calcTokens' + +const load = loader(18) +const input = load('input') + +describe('Day 18: Operation Order', () => { + describe('calc', () => { + it.each([ + ['1 + 2', 3], + ['3 * 3', 9], + ['1 + 2 + 3', 6], + ['1 + 2 * 3', 9], + ['1 + 2 * 3 + 4 * 5 + 6', 71], + ['(2 * 3)', 6], + ['1 + (2 * 3)', 7], + ['1 + (2 * 3) + 4', 11], + ['(2 * 3) + (3 * 4)', 18], + ['1 + (2 * 3) + (4 * (5 + 6))', 51], + ['2 * 3 + (4 * 5)', 26], + ['5 + (8 * 3 + 9 + 3 * 4 * 3)', 437], + ['5 * 9 * (7 * 3 * 3 + 9 * 3 + (8 + 6 * 4))', 12240], + ['((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2', 13632], + ])('%s = %d', (expression, expected) => + expect(calcTokens(expression)).toEqual(expected), + ) + }) + + describe('Part 1', () => { + it('should solve', () => + expect(input.map(calcTokens).reduce((total, n) => total + n, 0)).toEqual( + 7293529867931, + )) + }) + + describe.skip('Part 2', () => { + describe('calc (addition is evaluated before multiplication)', () => { + it.each([ + ['1 + 2 * 3 + 4 * 5 + 6', 231], + ['1 + (2 * 3) + (4 * (5 + 6))', 51], + ['2 * 3 + (4 * 5)', 46], + ['5 + (8 * 3 + 9 + 3 * 4 * 3)', 1445], + ['5 * 9 * (7 * 3 * 3 + 9 * 3 + (8 + 6 * 4))', 669060], + ['((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2', 23340], + ])('%s = %d', (expression, expected) => + expect(calcTokens(expression)).toEqual(expected), + ) + }) + }) +}) diff --git a/day18/tokenize.spec.ts b/day18/tokenize.spec.ts new file mode 100644 index 0000000..608b518 --- /dev/null +++ b/day18/tokenize.spec.ts @@ -0,0 +1,241 @@ +import { tokenize } from './tokenize' + +describe('tokenize', () => { + it.each([ + [ + '1 + 2', + { + type: 'op', + op: '+', + left: { + type: 'value', + value: 1, + }, + right: { + type: 'value', + value: 2, + }, + }, + ], + [ + '3 * 3', + { + type: 'op', + op: '*', + left: { + type: 'value', + value: 3, + }, + right: { + type: 'value', + value: 3, + }, + }, + ], + [ + '1 + 2 + 3', + { + type: 'op', + op: '+', + left: { + type: 'op', + op: '+', + left: { + type: 'value', + value: 1, + }, + right: { + type: 'value', + value: 2, + }, + }, + right: { + type: 'value', + value: 3, + }, + }, + ], + [ + '1 + 2 * 3', + { + type: 'op', + op: '*', + left: { + type: 'op', + op: '+', + left: { + type: 'value', + value: 1, + }, + right: { + type: 'value', + value: 2, + }, + }, + right: { + type: 'value', + value: 3, + }, + }, + ], + [ + '(2 * 3)', + { + type: 'group', + group: { + type: 'op', + op: '*', + left: { + type: 'value', + value: 2, + }, + right: { + type: 'value', + value: 3, + }, + }, + }, + ], + [ + '1 + (2 * 3)', + { + type: 'op', + op: '+', + left: { + type: 'value', + value: 1, + }, + right: { + type: 'group', + group: { + type: 'op', + op: '*', + left: { + type: 'value', + value: 2, + }, + right: { + type: 'value', + value: 3, + }, + }, + }, + }, + ], + [ + '1 + (2 * 3) + 4', + { + type: 'op', + op: '+', + left: { + type: 'op', + op: '+', + left: { + type: 'value', + value: 1, + }, + right: { + type: 'group', + group: { + type: 'op', + op: '*', + left: { + type: 'value', + value: 2, + }, + right: { + type: 'value', + value: 3, + }, + }, + }, + }, + right: { + type: 'value', + value: 4, + }, + }, + ], + [ + '(2 * 3) + (3 * 4)', + { + type: 'op', + op: '+', + left: { + type: 'group', + group: { + type: 'op', + op: '*', + left: { + type: 'value', + value: 2, + }, + right: { + type: 'value', + value: 3, + }, + }, + }, + right: { + type: 'group', + group: { + type: 'op', + op: '*', + left: { + type: 'value', + value: 3, + }, + right: { + type: 'value', + value: 4, + }, + }, + }, + }, + ], + [ + '1 + (2 * 3) + (4 * (5 + 6))', + { + type: 'op', + op: '+', + left: { + type: 'op', + op: '+', + left: { type: 'value', value: 1 }, + right: { + type: 'group', + group: { + type: 'op', + op: '*', + left: { type: 'value', value: 2 }, + right: { type: 'value', value: 3 }, + }, + }, + }, + right: { + type: 'group', + group: { + type: 'op', + op: '*', + left: { type: 'value', value: 4 }, + right: { + type: 'group', + group: { + type: 'op', + op: '+', + left: { type: 'value', value: 5 }, + right: { type: 'value', value: 6 }, + }, + }, + }, + }, + }, + ], + //['2 * 3 + (4 * 5)', 26], + //['5 + (8 * 3 + 9 + 3 * 4 * 3)', 437], + //['5 * 9 * (7 * 3 * 3 + 9 * 3 + (8 + 6 * 4))', 12240], + //['((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2', 13632], + ])('should tokenize %s', (expression, expected) => + expect(tokenize(expression)).toEqual(expected), + ) +}) diff --git a/day18/tokenize.ts b/day18/tokenize.ts new file mode 100644 index 0000000..94f8907 --- /dev/null +++ b/day18/tokenize.ts @@ -0,0 +1,63 @@ +import { + isNumber, + isOpeningParenthesis, + isOperator, + isSpace, + findClosing, +} from './calc' + +type Noop = { type: 'noop' } +export type Value = { type: 'value'; value: number } +export type Group = { type: 'group'; group: Token } +export type Op = { type: 'op'; op: '+' | '*'; left: Token; right: Token } +export type Token = Noop | Value | Op | Group + +const findNextToken = (expression: string): Token => { + let i = 0 + let token: Token = { type: 'noop' } + while (i < expression.length) { + const c = expression[i] + if (isNumber(c)) { + if (token.type === 'op') { + token.right = { type: 'value', value: parseInt(c, 10) } + } else { + token = { type: 'value', value: parseInt(c, 10) } + } + i++ + } else if (isSpace(c)) { + // pass + i++ + } else if (isOperator(c)) { + token = { + type: 'op', + op: c as '+' | '*', + left: token, + right: { type: 'noop' }, + } + i++ + } else if (isOpeningParenthesis(c)) { + const closing = findClosing(expression, i) + if (token.type === 'op') { + token.right = { + type: 'group', + group: findNextToken(expression.substr(i + 1, closing - i - 1)), + } + } else { + token = { + type: 'group', + group: findNextToken(expression.substr(i + 1, closing - i - 1)), + } + } + + i = closing + 1 + } else { + throw new Error(`Unexpected token ${c} at position ${i}!`) + } + } + return token +} + +export const tokenize = (expression: string): Token => { + const nextToken = findNextToken(expression) + return nextToken +} From 9dbbb30915fc17cd82aad841fdd80b46408f48fe Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Sat, 19 Dec 2020 14:22:09 +0100 Subject: [PATCH 58/60] feat(day18): part 2 try 2 --- day18/calcTokens.ts | 2 +- day18/groupAdditions.spec.ts | 17 ++++++++++ day18/solution.spec.ts | 5 +-- day18/toExpression.ts | 16 ++++++++++ day18/tokenize.ts | 60 +++++++++++++++++++++++++++++------- 5 files changed, 86 insertions(+), 14 deletions(-) create mode 100644 day18/groupAdditions.spec.ts create mode 100644 day18/toExpression.ts diff --git a/day18/calcTokens.ts b/day18/calcTokens.ts index b03df49..a710a94 100644 --- a/day18/calcTokens.ts +++ b/day18/calcTokens.ts @@ -1,6 +1,6 @@ import { Token, tokenize } from './tokenize' -const calc = (token: Token): number => { +export const calc = (token: Token): number => { switch (token.type) { case 'op': switch (token.op) { diff --git a/day18/groupAdditions.spec.ts b/day18/groupAdditions.spec.ts new file mode 100644 index 0000000..91e4f65 --- /dev/null +++ b/day18/groupAdditions.spec.ts @@ -0,0 +1,17 @@ +import { toExpression } from './toExpression' +import { tokenize } from './tokenize' + +describe.skip('groupAdditions', () => { + it.each([ + ['1 + 2', '(1 + 2)'], + ['1 + 2 * 3', '(1 + 2) * 3'], + ['1 + 2 * 3 + 4 * 5 + 6', '(1 + 2) * (3 + 4) * (5 + 6)'], + //['1 + (2 * 3) + (4 * (5 + 6))', 51], + //['2 * 3 + (4 * 5)', 46], + //['5 + (8 * 3 + 9 + 3 * 4 * 3)', 1445], + //['5 * 9 * (7 * 3 * 3 + 9 * 3 + (8 + 6 * 4))', 669060], + //['((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2', 23340], + ])(`should group %s to %s`, (expression, expected) => + expect(toExpression(tokenize(expression))).toEqual(expected), + ) +}) diff --git a/day18/solution.spec.ts b/day18/solution.spec.ts index 092617a..1a5802f 100644 --- a/day18/solution.spec.ts +++ b/day18/solution.spec.ts @@ -1,5 +1,6 @@ import { loader } from '../lib/loader' -import { calcTokens } from './calcTokens' +import { calc, calcTokens } from './calcTokens' +import { tokenize } from './tokenize' const load = loader(18) const input = load('input') @@ -43,7 +44,7 @@ describe('Day 18: Operation Order', () => { ['5 * 9 * (7 * 3 * 3 + 9 * 3 + (8 + 6 * 4))', 669060], ['((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2', 23340], ])('%s = %d', (expression, expected) => - expect(calcTokens(expression)).toEqual(expected), + expect(calc(tokenize(expression))).toEqual(expected), ) }) }) diff --git a/day18/toExpression.ts b/day18/toExpression.ts new file mode 100644 index 0000000..e6b2f91 --- /dev/null +++ b/day18/toExpression.ts @@ -0,0 +1,16 @@ +import { Token } from './tokenize' + +export const toExpression = (token: Token): string => { + switch (token.type) { + case 'value': + return `${token.value}` + case 'op': + return `${toExpression(token.left)} ${token.op} ${toExpression( + token.right, + )}` + case 'group': + return `(${toExpression(token.group)})` + default: + throw new Error(`Unexpected token ${token.type}`) + } +} diff --git a/day18/tokenize.ts b/day18/tokenize.ts index 94f8907..7b6350e 100644 --- a/day18/tokenize.ts +++ b/day18/tokenize.ts @@ -12,13 +12,20 @@ export type Group = { type: 'group'; group: Token } export type Op = { type: 'op'; op: '+' | '*'; left: Token; right: Token } export type Token = Noop | Value | Op | Group -const findNextToken = (expression: string): Token => { +const findNextToken = (expression: string, groupAdditions: boolean): Token => { let i = 0 let token: Token = { type: 'noop' } while (i < expression.length) { const c = expression[i] if (isNumber(c)) { - if (token.type === 'op') { + if ( + groupAdditions && + token.type === 'group' && + token.group.type === 'op' && + token.group.op === '+' + ) { + token.group.right = { type: 'value', value: parseInt(c, 10) } + } else if (token.type === 'op') { token.right = { type: 'value', value: parseInt(c, 10) } } else { token = { type: 'value', value: parseInt(c, 10) } @@ -28,11 +35,36 @@ const findNextToken = (expression: string): Token => { // pass i++ } else if (isOperator(c)) { - token = { - type: 'op', - op: c as '+' | '*', - left: token, - right: { type: 'noop' }, + if (groupAdditions && c === '+') { + console.dir(token) + if (token.type === 'op' && token.right.type === 'value') { + token.right = { + type: 'group', + group: { + type: 'op', + op: '+', + left: token.right, + right: token, + }, + } + } else { + token = { + type: 'group', + group: { + type: 'op', + op: '+', + left: token, + right: { type: 'noop' }, + }, + } + } + } else { + token = { + type: 'op', + op: c as '+' | '*', + left: token, + right: { type: 'noop' }, + } } i++ } else if (isOpeningParenthesis(c)) { @@ -40,12 +72,18 @@ const findNextToken = (expression: string): Token => { if (token.type === 'op') { token.right = { type: 'group', - group: findNextToken(expression.substr(i + 1, closing - i - 1)), + group: findNextToken( + expression.substr(i + 1, closing - i - 1), + groupAdditions, + ), } } else { token = { type: 'group', - group: findNextToken(expression.substr(i + 1, closing - i - 1)), + group: findNextToken( + expression.substr(i + 1, closing - i - 1), + groupAdditions, + ), } } @@ -57,7 +95,7 @@ const findNextToken = (expression: string): Token => { return token } -export const tokenize = (expression: string): Token => { - const nextToken = findNextToken(expression) +export const tokenize = (expression: string, groupAdditions = false): Token => { + const nextToken = findNextToken(expression, groupAdditions) return nextToken } From 1871ee193842c4dd3593490c23f13b00c9cad5f2 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Sat, 19 Dec 2020 15:48:35 +0100 Subject: [PATCH 59/60] WIP --- day18/groupAdditions.spec.ts | 69 ++++++++-- day18/tokenize.spec.ts | 241 ----------------------------------- 2 files changed, 55 insertions(+), 255 deletions(-) delete mode 100644 day18/tokenize.spec.ts diff --git a/day18/groupAdditions.spec.ts b/day18/groupAdditions.spec.ts index 91e4f65..95e959f 100644 --- a/day18/groupAdditions.spec.ts +++ b/day18/groupAdditions.spec.ts @@ -1,17 +1,58 @@ -import { toExpression } from './toExpression' -import { tokenize } from './tokenize' +import { isNumber } from './calc' +import { calcTokens } from './calcTokens' -describe.skip('groupAdditions', () => { +const reverse = (s: string): string => s.split('').reverse().join('') + +const addOpeningParen = (exp: string): string => { + let rev = reverse(exp) + let len = rev.length + let parenCount = 0 + for (let i = 0; i < len; i++) { + const c = rev[i] + if (c === ')') parenCount++ + if (c === '(') parenCount++ + if (isNumber(c)) { + rev = `${rev}(` + i++ + len++ + } + } + return reverse(rev) +} +const addClosingParen = (exp: string): string => exp + +const groupAdditions = (expression: string): string => { + console.log(expression) + let res = expression + for (let i = 0; i < expression.length; i++) { + if (res[i] === '+') { + const left = addOpeningParen(res.substr(0, i - 1)) + const right = addClosingParen(res.substr(i + 2)) + console.log({ left, right }) + res = `${left} + ${right}` + } + } + return res +} + +describe('groupAdditions', () => { it.each([ - ['1 + 2', '(1 + 2)'], - ['1 + 2 * 3', '(1 + 2) * 3'], - ['1 + 2 * 3 + 4 * 5 + 6', '(1 + 2) * (3 + 4) * (5 + 6)'], - //['1 + (2 * 3) + (4 * (5 + 6))', 51], - //['2 * 3 + (4 * 5)', 46], - //['5 + (8 * 3 + 9 + 3 * 4 * 3)', 1445], - //['5 * 9 * (7 * 3 * 3 + 9 * 3 + (8 + 6 * 4))', 669060], - //['((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2', 23340], - ])(`should group %s to %s`, (expression, expected) => - expect(toExpression(tokenize(expression))).toEqual(expected), - ) + ['1 + 2 * 3 + 4 * 5 + 6', '(1 + 2) * (3 + 4) * (5 + 6)', 231], + //['1 + (2 * 3) + (4 * (5 + 6))', '((1 + (2 * 3)) + (4 * (5 + 6)))', 51], + //['2 * 3 + (4 * 5)', '2 * (3 + (4 * 5))', 46], + //['5 + (8 * 3 + 9 + 3 * 4 * 3)', '(5 + (8 * ((3 + 9) + 3) * 4 * 3))', 1445], + //[ + // '5 * 9 * (7 * 3 * 3 + 9 * 3 + (8 + 6 * 4))', + // '5 * 9 * (7 * 3 * (3 + 9) * (3 + ((8 + 6) * 4)))', + // 669060, + // ], + // [ + // '((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2', + // '(((((2 + 4) * 9) * (((6 + 9) * (8 + 6)) + 6)) + 2) + 4) * 2', + // 23340, + // ], + ])(`should group %s to %s and equal %d`, (expression, escaped, expected) => { + expect(groupAdditions(expression)).toEqual(escaped) + expect(calcTokens(groupAdditions(expression))).toEqual(expected) + }) }) diff --git a/day18/tokenize.spec.ts b/day18/tokenize.spec.ts deleted file mode 100644 index 608b518..0000000 --- a/day18/tokenize.spec.ts +++ /dev/null @@ -1,241 +0,0 @@ -import { tokenize } from './tokenize' - -describe('tokenize', () => { - it.each([ - [ - '1 + 2', - { - type: 'op', - op: '+', - left: { - type: 'value', - value: 1, - }, - right: { - type: 'value', - value: 2, - }, - }, - ], - [ - '3 * 3', - { - type: 'op', - op: '*', - left: { - type: 'value', - value: 3, - }, - right: { - type: 'value', - value: 3, - }, - }, - ], - [ - '1 + 2 + 3', - { - type: 'op', - op: '+', - left: { - type: 'op', - op: '+', - left: { - type: 'value', - value: 1, - }, - right: { - type: 'value', - value: 2, - }, - }, - right: { - type: 'value', - value: 3, - }, - }, - ], - [ - '1 + 2 * 3', - { - type: 'op', - op: '*', - left: { - type: 'op', - op: '+', - left: { - type: 'value', - value: 1, - }, - right: { - type: 'value', - value: 2, - }, - }, - right: { - type: 'value', - value: 3, - }, - }, - ], - [ - '(2 * 3)', - { - type: 'group', - group: { - type: 'op', - op: '*', - left: { - type: 'value', - value: 2, - }, - right: { - type: 'value', - value: 3, - }, - }, - }, - ], - [ - '1 + (2 * 3)', - { - type: 'op', - op: '+', - left: { - type: 'value', - value: 1, - }, - right: { - type: 'group', - group: { - type: 'op', - op: '*', - left: { - type: 'value', - value: 2, - }, - right: { - type: 'value', - value: 3, - }, - }, - }, - }, - ], - [ - '1 + (2 * 3) + 4', - { - type: 'op', - op: '+', - left: { - type: 'op', - op: '+', - left: { - type: 'value', - value: 1, - }, - right: { - type: 'group', - group: { - type: 'op', - op: '*', - left: { - type: 'value', - value: 2, - }, - right: { - type: 'value', - value: 3, - }, - }, - }, - }, - right: { - type: 'value', - value: 4, - }, - }, - ], - [ - '(2 * 3) + (3 * 4)', - { - type: 'op', - op: '+', - left: { - type: 'group', - group: { - type: 'op', - op: '*', - left: { - type: 'value', - value: 2, - }, - right: { - type: 'value', - value: 3, - }, - }, - }, - right: { - type: 'group', - group: { - type: 'op', - op: '*', - left: { - type: 'value', - value: 3, - }, - right: { - type: 'value', - value: 4, - }, - }, - }, - }, - ], - [ - '1 + (2 * 3) + (4 * (5 + 6))', - { - type: 'op', - op: '+', - left: { - type: 'op', - op: '+', - left: { type: 'value', value: 1 }, - right: { - type: 'group', - group: { - type: 'op', - op: '*', - left: { type: 'value', value: 2 }, - right: { type: 'value', value: 3 }, - }, - }, - }, - right: { - type: 'group', - group: { - type: 'op', - op: '*', - left: { type: 'value', value: 4 }, - right: { - type: 'group', - group: { - type: 'op', - op: '+', - left: { type: 'value', value: 5 }, - right: { type: 'value', value: 6 }, - }, - }, - }, - }, - }, - ], - //['2 * 3 + (4 * 5)', 26], - //['5 + (8 * 3 + 9 + 3 * 4 * 3)', 437], - //['5 * 9 * (7 * 3 * 3 + 9 * 3 + (8 + 6 * 4))', 12240], - //['((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2', 13632], - ])('should tokenize %s', (expression, expected) => - expect(tokenize(expression)).toEqual(expected), - ) -}) From 6b9ebe2053f664c95169654a62bbe3cc4a398c5f Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Sun, 20 Dec 2020 13:26:42 +0100 Subject: [PATCH 60/60] feat(day18): part 2 --- day18/groupAdditions.spec.ts | 63 +++++++++--------------------------- day18/groupAdditions.ts | 45 ++++++++++++++++++++++++++ day18/solution.spec.ts | 15 ++++++--- 3 files changed, 71 insertions(+), 52 deletions(-) create mode 100644 day18/groupAdditions.ts diff --git a/day18/groupAdditions.spec.ts b/day18/groupAdditions.spec.ts index 95e959f..faabb67 100644 --- a/day18/groupAdditions.spec.ts +++ b/day18/groupAdditions.spec.ts @@ -1,56 +1,23 @@ -import { isNumber } from './calc' import { calcTokens } from './calcTokens' - -const reverse = (s: string): string => s.split('').reverse().join('') - -const addOpeningParen = (exp: string): string => { - let rev = reverse(exp) - let len = rev.length - let parenCount = 0 - for (let i = 0; i < len; i++) { - const c = rev[i] - if (c === ')') parenCount++ - if (c === '(') parenCount++ - if (isNumber(c)) { - rev = `${rev}(` - i++ - len++ - } - } - return reverse(rev) -} -const addClosingParen = (exp: string): string => exp - -const groupAdditions = (expression: string): string => { - console.log(expression) - let res = expression - for (let i = 0; i < expression.length; i++) { - if (res[i] === '+') { - const left = addOpeningParen(res.substr(0, i - 1)) - const right = addClosingParen(res.substr(i + 2)) - console.log({ left, right }) - res = `${left} + ${right}` - } - } - return res -} +import { groupAdditions } from './groupAdditions' describe('groupAdditions', () => { it.each([ + ['1 + 2', '(1 + 2)', 3], ['1 + 2 * 3 + 4 * 5 + 6', '(1 + 2) * (3 + 4) * (5 + 6)', 231], - //['1 + (2 * 3) + (4 * (5 + 6))', '((1 + (2 * 3)) + (4 * (5 + 6)))', 51], - //['2 * 3 + (4 * 5)', '2 * (3 + (4 * 5))', 46], - //['5 + (8 * 3 + 9 + 3 * 4 * 3)', '(5 + (8 * ((3 + 9) + 3) * 4 * 3))', 1445], - //[ - // '5 * 9 * (7 * 3 * 3 + 9 * 3 + (8 + 6 * 4))', - // '5 * 9 * (7 * 3 * (3 + 9) * (3 + ((8 + 6) * 4)))', - // 669060, - // ], - // [ - // '((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2', - // '(((((2 + 4) * 9) * (((6 + 9) * (8 + 6)) + 6)) + 2) + 4) * 2', - // 23340, - // ], + ['1 + (2 * 3) + (4 * (5 + 6))', '((1 + (2 * 3)) + (4 * ((5 + 6))))', 51], + ['2 * 3 + (4 * 5)', '2 * (3 + (4 * 5))', 46], + ['5 + (8 * 3 + 9 + 3 * 4 * 3)', '(5 + (8 * ((3 + 9) + 3) * 4 * 3))', 1445], + [ + '5 * 9 * (7 * 3 * 3 + 9 * 3 + (8 + 6 * 4))', + '5 * 9 * (7 * 3 * (3 + 9) * (3 + ((8 + 6) * 4)))', + 669060, + ], + [ + '((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2', + '(((((2 + 4) * 9) * (((6 + 9) * (8 + 6)) + 6)) + 2) + 4) * 2', + 23340, + ], ])(`should group %s to %s and equal %d`, (expression, escaped, expected) => { expect(groupAdditions(expression)).toEqual(escaped) expect(calcTokens(groupAdditions(expression))).toEqual(expected) diff --git a/day18/groupAdditions.ts b/day18/groupAdditions.ts new file mode 100644 index 0000000..f8702fd --- /dev/null +++ b/day18/groupAdditions.ts @@ -0,0 +1,45 @@ +import { isNumber } from './calc' + +const reverse = (s: string): string => s.split('').reverse().join('') + +const addParen = (paren: '(' | ')', exp: string): string => { + let parenCount = 0 + for (let i = exp.length - 1; i >= 0; i--) { + const c = exp[i] + if (['(', ')'].includes(c) && c !== paren) parenCount++ + if (c === paren) { + parenCount-- + if (parenCount === 0) { + return `${exp.substr(0, i)}${paren}${exp.substr(i)}` + } + } + if (isNumber(c) && parenCount === 0) { + return `${exp.substr(0, i)}${paren}${exp.substr(i)}` + } + } + + throw new Error(`Could not add parenthesis "${paren}" to "${exp}"!`) +} + +const addOpeningParen = (exp: string): string => addParen('(', exp) + +const addClosingParen = (exp: string): string => + reverse(addParen(')', reverse(exp))) + +/** + * Groups all aditions in the expression, e.g. `1 + 2 * 2` => `(1 + 2) * 3` + **/ +export const groupAdditions = (expression: string): string => { + let res = expression + for (let i = 0; i < res.length; i++) { + if (res[i] === '+') { + const l = res.substr(0, i - 1) + const r = res.substr(i + 2) + const left = addOpeningParen(l) + const right = addClosingParen(r) + res = `${left} + ${right}` + i += 2 + } + } + return res +} diff --git a/day18/solution.spec.ts b/day18/solution.spec.ts index 1a5802f..b59fd3f 100644 --- a/day18/solution.spec.ts +++ b/day18/solution.spec.ts @@ -1,6 +1,6 @@ import { loader } from '../lib/loader' -import { calc, calcTokens } from './calcTokens' -import { tokenize } from './tokenize' +import { calcTokens } from './calcTokens' +import { groupAdditions } from './groupAdditions' const load = loader(18) const input = load('input') @@ -34,7 +34,7 @@ describe('Day 18: Operation Order', () => { )) }) - describe.skip('Part 2', () => { + describe('Part 2', () => { describe('calc (addition is evaluated before multiplication)', () => { it.each([ ['1 + 2 * 3 + 4 * 5 + 6', 231], @@ -44,8 +44,15 @@ describe('Day 18: Operation Order', () => { ['5 * 9 * (7 * 3 * 3 + 9 * 3 + (8 + 6 * 4))', 669060], ['((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2', 23340], ])('%s = %d', (expression, expected) => - expect(calc(tokenize(expression))).toEqual(expected), + expect(calcTokens(groupAdditions(expression))).toEqual(expected), ) }) + it('should solve', () => + expect( + input + .map(groupAdditions) + .map(calcTokens) + .reduce((total, n) => total + n, 0), + ).toEqual(60807587180737)) }) })