From 4f75ef88f02374e3d053015cd049ebef07c84a9c Mon Sep 17 00:00:00 2001 From: im1 Date: Tue, 24 Nov 2020 15:30:01 +0900 Subject: [PATCH 01/29] feat: setup baseball game project From 66991345ebea369702c23029dc22d2f000ad3f46 Mon Sep 17 00:00:00 2001 From: gxxrxn Date: Thu, 19 May 2022 15:43:28 +0900 Subject: [PATCH 02/29] =?UTF-8?q?docs:=20=EC=9A=94=EA=B5=AC=EC=82=AC?= =?UTF-8?q?=ED=95=AD=20=EB=AA=A9=EB=A1=9D=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 docs/README.md diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..197d26b6 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,24 @@ +

+ +

+

숫자 야구 게임

+ +## 게임 설명 + +1부터 9까지 서로 다른 수로 이루어진 3자리의 수를 맞추는 게임이다. + +## 기능 요구사항 + +- [ ] 1 ~ 9까지 서로 다른 임의의 수 3개를 랜덤으로 선택하여 정답으로 설정한다. +- [ ] 3자리의 수를 입력받는다. +- 입력받은 수와 정답을 비교해서 힌트를 띄운다. + - [ ] 숫자가 같은 위치에 있는 경우 `스트라이크` 힌트를 띄운다. + - [ ] 숫자가 다른 위치에 있는 경우 `볼` 힌트를 띄운다. + - [ ] 숫자가 존재하지 않는 경우 `낫싱` 힌트를 띄운다. + - [ ] 힌트는 볼, 스트라이크 순서로 띄운다. +- [ ] 입력받은 수와 정답이 같으면 게임이 종료되고, 게임을 재시작할 수 있다. +- [ ] 잘못된 값을 입력한 경우, 에러 메시지가 뜨고 값을 재입력할 수 있다. + - [ ] 수를 중복해서 입력한 경우 + - [ ] 입력한 수가 3자리가 아닌 경우 + - [ ] 숫자가 아닌 문자 등을 입력한 경우 + - [ ] 공백이 입력된 경우 From e5bbfd23fed56d888fd5f91d54e9caeb70cfaa34 Mon Sep 17 00:00:00 2001 From: gxxrxn Date: Sun, 22 May 2022 17:03:54 +0900 Subject: [PATCH 03/29] =?UTF-8?q?chore:=20prettier,=20eslint=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintrc.yml | 6 + .prettierrc.yml | 12 + package-lock.json | 1342 +++++++++++++++++++++++++++++++++++++++++++++ package.json | 8 +- 4 files changed, 1367 insertions(+), 1 deletion(-) create mode 100644 .eslintrc.yml create mode 100644 .prettierrc.yml diff --git a/.eslintrc.yml b/.eslintrc.yml new file mode 100644 index 00000000..689032b3 --- /dev/null +++ b/.eslintrc.yml @@ -0,0 +1,6 @@ +env: + browser: true + es6: true + node: true +extends: + - airbnb diff --git a/.prettierrc.yml b/.prettierrc.yml new file mode 100644 index 00000000..5605e3fe --- /dev/null +++ b/.prettierrc.yml @@ -0,0 +1,12 @@ +arrowParens: 'always' +bracketSpacing: true +jsxBracketSameLine: false +jsxSingleQuote: false +printWidth: 80 +proseWrap: 'always' +quoteProps: 'as-needed' +semi: true +singleQuote: true +tabWidth: 2 +trailingComma: 'es5' +useTabs: false diff --git a/package-lock.json b/package-lock.json index ba108683..73b68f96 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,25 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@babel/runtime": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.0.tgz", + "integrity": "sha512-YMQvx/6nKEaucl0MY56mwIG483xk8SDNdlUwb2Ts6FUpr7fm85DxEmsY18LXBNhcTz6tO6JwZV8w1W06v8UKeg==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/runtime-corejs3": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.18.0.tgz", + "integrity": "sha512-G5FaGZOWORq9zthDjIrjib5XlcddeqLbIiDO3YQsut6j7aGf76xn0umUC/pA6+nApk3hQJF4JzLzg5PCl6ewJg==", + "dev": true, + "requires": { + "core-js-pure": "^3.20.2", + "regenerator-runtime": "^0.13.4" + } + }, "@cypress/request": { "version": "2.88.7", "resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.7.tgz", @@ -52,6 +71,57 @@ } } }, + "@eslint/eslintrc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", + "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.3.2", + "globals": "^13.15.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "@humanwhocodes/config-array": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", + "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, "@types/node": { "version": "14.17.34", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.34.tgz", @@ -80,6 +150,18 @@ "@types/node": "*" } }, + "acorn": { + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", + "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true + }, "aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", @@ -138,6 +220,59 @@ "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", "dev": true }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "aria-query": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", + "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.10.2", + "@babel/runtime-corejs3": "^7.10.2" + } + }, + "array-includes": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz", + "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.7" + } + }, + "array.prototype.flat": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", + "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.2", + "es-shim-unscopables": "^1.0.0" + } + }, + "array.prototype.flatmap": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.0.tgz", + "integrity": "sha512-PZC9/8TKAIxcWKdyeb77EzULHPrIX/tIZebLJUQOMR1OwYosT8yggdfWScfTBCDj5utONvOuPQQumYsU2ULbkg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.2", + "es-shim-unscopables": "^1.0.0" + } + }, "asn1": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", @@ -153,6 +288,12 @@ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true }, + "ast-types-flow": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", + "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==", + "dev": true + }, "astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", @@ -189,6 +330,18 @@ "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", "dev": true }, + "axe-core": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.4.2.tgz", + "integrity": "sha512-LVAaGp/wkkgYJcjmHsoKx4juT1aQvJyPcW09MLCjVTh3V2cc6PnyempiLMNH5iMdfIX/zdbjUx2KDjMLCTdPeA==", + "dev": true + }, + "axobject-query": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", + "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==", + "dev": true + }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -238,6 +391,22 @@ "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==", "dev": true }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", @@ -374,6 +543,18 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "confusing-browser-globals": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", + "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", + "dev": true + }, + "core-js-pure": { + "version": "3.22.5", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.22.5.tgz", + "integrity": "sha512-8xo9R00iYD7TcV7OrC98GwxiUEAabVWO3dix+uyWjnYrx9fyASLlIX+f/3p5dW5qByaP2bcZ8X/T47s55et/tA==", + "dev": true + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -441,6 +622,12 @@ "yauzl": "^2.10.0" } }, + "damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true + }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -473,12 +660,37 @@ } } }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "define-properties": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "dev": true, + "requires": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.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 }, + "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" + } + }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -513,12 +725,404 @@ "ansi-colors": "^4.1.1" } }, + "es-abstract": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz", + "integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "regexp.prototype.flags": "^1.4.3", + "string.prototype.trimend": "^1.0.5", + "string.prototype.trimstart": "^1.0.5", + "unbox-primitive": "^1.0.2" + } + }, + "es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, "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 }, + "eslint": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.16.0.tgz", + "integrity": "sha512-MBndsoXY/PeVTDJeWsYj7kLZ5hQpJOfMYLsF6LicLHQWbRDG19lK5jOix4DPl8yY4SUFcE3txy86OzFLWT+yoA==", + "dev": true, + "requires": { + "@eslint/eslintrc": "^1.3.0", + "@humanwhocodes/config-array": "^0.9.2", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.2", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.15.0", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "eslint-config-airbnb": { + "version": "19.0.4", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-19.0.4.tgz", + "integrity": "sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew==", + "dev": true, + "requires": { + "eslint-config-airbnb-base": "^15.0.0", + "object.assign": "^4.1.2", + "object.entries": "^1.1.5" + } + }, + "eslint-config-airbnb-base": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz", + "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==", + "dev": true, + "requires": { + "confusing-browser-globals": "^1.0.10", + "object.assign": "^4.1.2", + "object.entries": "^1.1.5", + "semver": "^6.3.0" + } + }, + "eslint-import-resolver-node": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "dev": true, + "requires": { + "debug": "^3.2.7", + "resolve": "^1.20.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-module-utils": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", + "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", + "dev": true, + "requires": { + "debug": "^3.2.7", + "find-up": "^2.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-plugin-import": { + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", + "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", + "dev": true, + "requires": { + "array-includes": "^3.1.4", + "array.prototype.flat": "^1.2.5", + "debug": "^2.6.9", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.7.3", + "has": "^1.0.3", + "is-core-module": "^2.8.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.values": "^1.1.5", + "resolve": "^1.22.0", + "tsconfig-paths": "^3.14.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" + } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-plugin-jsx-a11y": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.5.1.tgz", + "integrity": "sha512-sVCFKX9fllURnXT2JwLN5Qgo24Ug5NF6dxhkmxsMEUZhXRcGg+X3e1JbJ84YePQKBl5E0ZjAH5Q4rkdcGY99+g==", + "dev": true, + "requires": { + "@babel/runtime": "^7.16.3", + "aria-query": "^4.2.2", + "array-includes": "^3.1.4", + "ast-types-flow": "^0.0.7", + "axe-core": "^4.3.5", + "axobject-query": "^2.2.0", + "damerau-levenshtein": "^1.0.7", + "emoji-regex": "^9.2.2", + "has": "^1.0.3", + "jsx-ast-utils": "^3.2.1", + "language-tags": "^1.0.5", + "minimatch": "^3.0.4" + }, + "dependencies": { + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + } + } + }, + "eslint-plugin-react": { + "version": "7.30.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.30.0.tgz", + "integrity": "sha512-RgwH7hjW48BleKsYyHK5vUAvxtE9SMPDKmcPRQgtRCYaZA0XQPt5FSkrU3nhz5ifzMZcA8opwmRJ2cmOO8tr5A==", + "dev": true, + "requires": { + "array-includes": "^3.1.5", + "array.prototype.flatmap": "^1.3.0", + "doctrine": "^2.1.0", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.5", + "object.fromentries": "^2.0.5", + "object.hasown": "^1.1.1", + "object.values": "^1.1.5", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.3", + "semver": "^6.3.0", + "string.prototype.matchall": "^4.0.7" + }, + "dependencies": { + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "resolve": { + "version": "2.0.0-next.3", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz", + "integrity": "sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==", + "dev": true, + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + } + } + }, + "eslint-plugin-react-hooks": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.5.0.tgz", + "integrity": "sha512-8k1gRt7D7h03kd+SAAlzXkQwWK22BnK6GKZG+FJA6BAGy22CFvl8kCIXKpVux0cCxMWDQUPqSok0LKaZ0aOcCw==", + "dev": true + }, + "eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true + }, + "espree": { + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", + "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", + "dev": true, + "requires": { + "acorn": "^8.7.1", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + } + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + } + }, + "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" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "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 + }, "eventemitter2": { "version": "6.4.5", "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.5.tgz", @@ -587,6 +1191,12 @@ "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 + }, "fd-slicer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", @@ -605,6 +1215,40 @@ "escape-string-regexp": "^1.0.5" } }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", + "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", + "dev": true + }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -640,6 +1284,47 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": 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 + }, + "function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + } + }, + "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 + }, + "functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true + }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, "get-stream": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", @@ -649,6 +1334,16 @@ "pump": "^3.0.0" } }, + "get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + } + }, "getos": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz", @@ -681,6 +1376,15 @@ "path-is-absolute": "^1.0.0" } }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, "global-dirs": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", @@ -690,6 +1394,23 @@ "ini": "2.0.0" } }, + "globals": { + "version": "13.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", + "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + }, + "dependencies": { + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } + } + }, "graceful-fs": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", @@ -712,12 +1433,51 @@ "har-schema": "^2.0.0" } }, + "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-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "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 }, + "has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.1" + } + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true + }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -735,6 +1495,28 @@ "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", "dev": true }, + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "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", @@ -763,6 +1545,42 @@ "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", "dev": true }, + "internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + } + }, + "is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "requires": { + "has-bigints": "^1.0.1" + } + }, + "is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "dev": true + }, "is-ci": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", @@ -772,12 +1590,45 @@ "ci-info": "^3.2.0" } }, + "is-core-module": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", + "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "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-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, "is-installed-globally": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", @@ -788,18 +1639,70 @@ "is-path-inside": "^3.0.2" } }, + "is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true + }, + "is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, "is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true }, + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, "is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true }, + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -812,6 +1715,15 @@ "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true }, + "is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -824,6 +1736,21 @@ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", "dev": true }, + "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": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", @@ -842,12 +1769,27 @@ "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": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, "jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -870,12 +1812,47 @@ "verror": "1.10.0" } }, + "jsx-ast-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.0.tgz", + "integrity": "sha512-XzO9luP6L0xkxwhIJMTJQpZo/eeN60K08jHdexfD569AGxeNug6UketeHXEhROoM8aR7EcUoOQmIhcJQjcuq8Q==", + "dev": true, + "requires": { + "array-includes": "^3.1.4", + "object.assign": "^4.1.2" + } + }, + "language-subtag-registry": { + "version": "0.3.21", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz", + "integrity": "sha512-L0IqwlIXjilBVVYKFT37X9Ih11Um5NEl9cbJIuU/SwP/zEEAbBPOnEeeuxVMf45ydWQRDQN3Nqc96OgbH1K+Pg==", + "dev": true + }, + "language-tags": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", + "integrity": "sha1-0yHbxNowuovzAk4ED6XBRmH5GTo=", + "dev": true, + "requires": { + "language-subtag-registry": "~0.3.2" + } + }, "lazy-ass": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", "integrity": "sha1-eZllXoZGwX8In90YfRUNMyTVRRM=", "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" + } + }, "listr2": { "version": "3.13.4", "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.13.4.tgz", @@ -892,12 +1869,28 @@ "wrap-ansi": "^7.0.0" } }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, "lodash.once": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", @@ -950,6 +1943,15 @@ } } }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, "merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -998,6 +2000,12 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, + "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 + }, "npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -1013,6 +2021,73 @@ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true }, + "object-inspect": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.1.tgz", + "integrity": "sha512-Y/jF6vnvEtOPGiKD1+q+X0CiUYRQtEHp89MLLUJ7TUivtH8Ugn2+3A7Rynqk7BRsAoqeOQWnFnjpDrKSxDgIGA==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "object.entries": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz", + "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + } + }, + "object.fromentries": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.5.tgz", + "integrity": "sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + } + }, + "object.hasown": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.1.tgz", + "integrity": "sha512-LYLe4tivNQzq4JdaWW6WO3HMZZJWzkkH8fnI6EebWl0VZth2wL2Lovm74ep2/gZzlaTdV62JZHEqHQ2yVn8Q/A==", + "dev": true, + "requires": { + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + } + }, + "object.values": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", + "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -1031,12 +2106,44 @@ "mimic-fn": "^2.1.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" + } + }, "ospath": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz", "integrity": "sha1-EnZjl3Sj+O8lcvf+QoDg6kVQwHs=", "dev": true }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, "p-map": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", @@ -1046,6 +2153,27 @@ "aggregate-error": "^3.0.0" } }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "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" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -1058,6 +2186,12 @@ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, "pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -1076,12 +2210,29 @@ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, + "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 + }, "pretty-bytes": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", "dev": true }, + "prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, "proxy-from-env": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", @@ -1128,6 +2279,35 @@ "integrity": "sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw==", "dev": true }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + }, + "regenerator-runtime": { + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", + "dev": true + }, + "regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + } + }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true + }, "request-progress": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", @@ -1137,6 +2317,23 @@ "throttleit": "^1.0.0" } }, + "resolve": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "dev": true, + "requires": { + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "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 + }, "restore-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", @@ -1177,6 +2374,12 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -1192,6 +2395,17 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, "signal-exit": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", @@ -1237,6 +2451,44 @@ "strip-ansi": "^6.0.1" } }, + "string.prototype.matchall": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz", + "integrity": "sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1", + "get-intrinsic": "^1.1.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "regexp.prototype.flags": "^1.4.1", + "side-channel": "^1.0.4" + } + }, + "string.prototype.trimend": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", + "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + } + }, + "string.prototype.trimstart": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", + "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + } + }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -1246,12 +2498,24 @@ "ansi-regex": "^5.0.1" } }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "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-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": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -1261,6 +2525,18 @@ "has-flag": "^4.0.0" } }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "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 + }, "throttleit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", @@ -1292,6 +2568,26 @@ "punycode": "^2.1.1" } }, + "tsconfig-paths": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", + "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "dev": true + } + } + }, "tslib": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", @@ -1313,12 +2609,33 @@ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", "dev": true }, + "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" + } + }, "type-fest": { "version": "0.21.3", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true }, + "unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + } + }, "universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", @@ -1364,6 +2681,12 @@ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", @@ -1384,6 +2707,25 @@ "isexe": "^2.0.0" } }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "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": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", diff --git a/package.json b/package.json index 2d71d942..cbdad8d1 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,13 @@ "description": "우아한테크코스 프리코스 숫자 야구 게임 미션", "dependencies": {}, "devDependencies": { - "cypress": "8.7.0" + "cypress": "8.7.0", + "eslint": "^8.16.0", + "eslint-config-airbnb": "^19.0.4", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-jsx-a11y": "^6.5.1", + "eslint-plugin-react": "^7.30.0", + "eslint-plugin-react-hooks": "^4.5.0" }, "scripts": { "test": "cypress run --browser chrome" From 3e8078a8b4cac353d8b7aa129c9a9c855314d6e0 Mon Sep 17 00:00:00 2001 From: gxxrxn Date: Sun, 22 May 2022 18:30:14 +0900 Subject: [PATCH 04/29] =?UTF-8?q?feat:=20BaseballGame=20computerInputNumbe?= =?UTF-8?q?r=20=EC=83=9D=EC=84=B1=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - document에서 선택자로 필요태그 저장 - index.js에서 BaseballGame 객체 생성 - BaseballGame에서 submitBtn 이벤트핸들러 연결 --- src/domain/BaseballGame.js | 26 ++++++++++++++++++++++++++ src/index.js | 7 +++++++ 2 files changed, 33 insertions(+) create mode 100644 src/domain/BaseballGame.js create mode 100644 src/index.js diff --git a/src/domain/BaseballGame.js b/src/domain/BaseballGame.js new file mode 100644 index 00000000..912fc5bc --- /dev/null +++ b/src/domain/BaseballGame.js @@ -0,0 +1,26 @@ +import { HINT } from '../constants.js'; + +const pickNumberInRange = MissionUtils.Random; + +export default class BaseballGame { + constructor(input, result, submitBtn) { + this.input = input; + this.result = result; + this.submitBtn = submitBtn; + + this.submitBtn.addEventListener('click', (event) => { + event.preventDefault(); + const userInputNumbers = this.input.value; + }); + } + + get computerInputNumbers() { + let result = new Set(); + + while (result.length < 3) { + result.add(pickNumberInRange(1, 9).toString()); + } + + return Array.from(result).join(''); + } +} diff --git a/src/index.js b/src/index.js new file mode 100644 index 00000000..00d778c7 --- /dev/null +++ b/src/index.js @@ -0,0 +1,7 @@ +import BaseballGame from './domain/BaseballGame.js'; + +const input = document.querySelector('#user-input'); +const result = document.querySelector('#result'); +const submitBtn = document.querySelector('#submit'); + +new BaseballGame(input, result, submitBtn); From 8ea0a98224d0029af261df3855e2ed3d8200947e Mon Sep 17 00:00:00 2001 From: gxxrxn Date: Sun, 22 May 2022 18:30:54 +0900 Subject: [PATCH 05/29] =?UTF-8?q?chore:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20html=20=ED=85=8D=EC=8A=A4=ED=8A=B8=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 49 +++++++++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/index.html b/index.html index c85d50be..46dc0373 100644 --- a/index.html +++ b/index.html @@ -1,30 +1,27 @@ + + + 숫자 야구 게임 + - - - 숫자 야구 게임 - - - -
-

⚾ 숫자 야구 게임

-

- 1~9까지의 수를 중복없이 - 3개 입력해주세요.
- 올바른 예) 139
- 틀린 예) 122 -

-
- - -
-

📄 결과

-
1볼 1스트라이크
- -
- - - - + +
+

⚾ 숫자 야구 게임

+

+ 1~9까지의 수를 중복없이 + 3개 입력해주세요.
+ 올바른 예) 139
+ 틀린 예) 122 +

+
+ + +
+

📄 결과

+
+
+ + + From 1bbc30ed901018151cd9dfc41c6b3d29c3328ff1 Mon Sep 17 00:00:00 2001 From: gxxrxn Date: Sun, 22 May 2022 18:33:33 +0900 Subject: [PATCH 06/29] =?UTF-8?q?docs:=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EC=9A=94=EA=B5=AC?= =?UTF-8?q?=EC=82=AC=ED=95=AD=20=EB=AA=A9=EB=A1=9D=20=EC=97=85=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 1 ~ 9까지 서로 다른 임의의 수 3개를 랜덤으로 선택하여 정답으로 설정한다. - 3자리의 수를 입력받는다. --- docs/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index 197d26b6..6699fed7 100644 --- a/docs/README.md +++ b/docs/README.md @@ -9,8 +9,8 @@ ## 기능 요구사항 -- [ ] 1 ~ 9까지 서로 다른 임의의 수 3개를 랜덤으로 선택하여 정답으로 설정한다. -- [ ] 3자리의 수를 입력받는다. +- [x] 1 ~ 9까지 서로 다른 임의의 수 3개를 랜덤으로 선택하여 정답으로 설정한다. +- [x] 3자리의 수를 입력받는다. - 입력받은 수와 정답을 비교해서 힌트를 띄운다. - [ ] 숫자가 같은 위치에 있는 경우 `스트라이크` 힌트를 띄운다. - [ ] 숫자가 다른 위치에 있는 경우 `볼` 힌트를 띄운다. From 7db0f0091bb15452b8e6a74ecb3c7785ecb543a9 Mon Sep 17 00:00:00 2001 From: gxxrxn Date: Sun, 22 May 2022 18:52:19 +0900 Subject: [PATCH 07/29] =?UTF-8?q?fix:=20BaseballGame=20computerInputNumber?= =?UTF-8?q?=20=EC=83=9D=EC=84=B1=20=EA=B8=B0=EB=8A=A5=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - set size - MissionUtil 불러오는 부분 수정 --- src/domain/BaseballGame.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/domain/BaseballGame.js b/src/domain/BaseballGame.js index 912fc5bc..4d5e82ae 100644 --- a/src/domain/BaseballGame.js +++ b/src/domain/BaseballGame.js @@ -1,24 +1,26 @@ import { HINT } from '../constants.js'; -const pickNumberInRange = MissionUtils.Random; +const { pickNumberInRange } = MissionUtils.Random; export default class BaseballGame { constructor(input, result, submitBtn) { this.input = input; this.result = result; this.submitBtn = submitBtn; - + this.computerInputNumbers = this.getComputerInputNumbers(); this.submitBtn.addEventListener('click', (event) => { event.preventDefault(); const userInputNumbers = this.input.value; + const playResult = this.play(this.computerInputNumbers, userInputNumbers); }); } - get computerInputNumbers() { + getComputerInputNumbers() { let result = new Set(); - while (result.length < 3) { - result.add(pickNumberInRange(1, 9).toString()); + while (result.size < 3) { + const pickedNumber = pickNumberInRange(1, 9); + result.add(pickedNumber.toString()); } return Array.from(result).join(''); From f20b09211cc83f6add3c19938480582a53f221ec Mon Sep 17 00:00:00 2001 From: gxxrxn Date: Sun, 22 May 2022 19:03:00 +0900 Subject: [PATCH 08/29] =?UTF-8?q?feat:=20BaseballGame=20=EC=A0=95=EB=8B=B5?= =?UTF-8?q?=20=EB=B9=84=EA=B5=90=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 입력받은 수와 정답을 비교해서 힌트를 return하는 play 함수 구현 - constants.js 생성 후 상수 분리 --- src/constants.js | 10 ++++++++++ src/domain/BaseballGame.js | 28 +++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 src/constants.js diff --git a/src/constants.js b/src/constants.js new file mode 100644 index 00000000..41c6a300 --- /dev/null +++ b/src/constants.js @@ -0,0 +1,10 @@ +const HINT = { + BALL: '볼', + STRIKE: '스트라이크', + CORRECT: '🎉정답을 맞추셨습니다🎉', + NOTHING: '낫싱', +}; + +const EMPTY_STR = ''; + +export { HINT, EMPTY_STR }; diff --git a/src/domain/BaseballGame.js b/src/domain/BaseballGame.js index 4d5e82ae..48569be2 100644 --- a/src/domain/BaseballGame.js +++ b/src/domain/BaseballGame.js @@ -1,4 +1,4 @@ -import { HINT } from '../constants.js'; +import { HINT, EMPTY_STR } from '../constants.js'; const { pickNumberInRange } = MissionUtils.Random; @@ -25,4 +25,30 @@ export default class BaseballGame { return Array.from(result).join(''); } + + play(computerInputNumbers, userInputNumbers) { + if (computerInputNumbers == userInputNumbers) { + return HINT.CORRECT; + } + + let strike = 0; + let ball = 0; + + for (let i = 0; i < computerInputNumbers.length; i++) { + if (computerInputNumbers[i] === userInputNumbers[i]) { + strike++; + } else if (userInputNumbers.indexOf(computerInputNumbers[i]) !== -1) { + ball++; + } + } + + if (!strike && !ball) { + return HINT.NOTHING; + } + + let ballStr = ball ? `${ball}${HINT.BALL}` : `${EMPTY_STR}`; + let strikeStr = strike ? `${strike}${HINT.STRIKE}` : `${EMPTY_STR}`; + + return ballStr + strikeStr; + } } From 85c99596788cac505684ed2479ecc8d3d723e7bb Mon Sep 17 00:00:00 2001 From: gxxrxn Date: Sun, 22 May 2022 19:03:10 +0900 Subject: [PATCH 09/29] =?UTF-8?q?docs:=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EC=9A=94=EA=B5=AC?= =?UTF-8?q?=EC=82=AC=ED=95=AD=20=EB=AA=A9=EB=A1=9D=20=EC=97=85=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=8A=B8=20=EB=B0=8F=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 숫자가 같은 위치에 있는 경우 스트라이크 힌트를 전달한다. - 숫자가 다른 위치에 있는 경우 볼 힌트를 전달한다. - 숫자가 존재하지 않는 경우 낫싱 힌트를 전달한다. - 힌트는 볼, 스트라이크 순서로 전달한다. --- docs/README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/README.md b/docs/README.md index 6699fed7..71ceca61 100644 --- a/docs/README.md +++ b/docs/README.md @@ -12,10 +12,11 @@ - [x] 1 ~ 9까지 서로 다른 임의의 수 3개를 랜덤으로 선택하여 정답으로 설정한다. - [x] 3자리의 수를 입력받는다. - 입력받은 수와 정답을 비교해서 힌트를 띄운다. - - [ ] 숫자가 같은 위치에 있는 경우 `스트라이크` 힌트를 띄운다. - - [ ] 숫자가 다른 위치에 있는 경우 `볼` 힌트를 띄운다. - - [ ] 숫자가 존재하지 않는 경우 `낫싱` 힌트를 띄운다. - - [ ] 힌트는 볼, 스트라이크 순서로 띄운다. + - [x] 숫자가 같은 위치에 있는 경우 `스트라이크` 힌트를 전달한다. + - [x] 숫자가 다른 위치에 있는 경우 `볼` 힌트를 전달한다. + - [x] 숫자가 존재하지 않는 경우 `낫싱` 힌트를 전달한다. + - [x] 힌트는 볼, 스트라이크 순서로 전달한다. + - [ ] 힌트를 출력한다. - [ ] 입력받은 수와 정답이 같으면 게임이 종료되고, 게임을 재시작할 수 있다. - [ ] 잘못된 값을 입력한 경우, 에러 메시지가 뜨고 값을 재입력할 수 있다. - [ ] 수를 중복해서 입력한 경우 From 3f2a562d958614f092c50d98b597960242b1a616 Mon Sep 17 00:00:00 2001 From: gxxrxn Date: Sun, 22 May 2022 19:07:55 +0900 Subject: [PATCH 10/29] =?UTF-8?q?feat:=20BaseballGame=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EA=B2=B0=EA=B3=BC=EB=A5=BC=20=ED=99=94=EB=A9=B4=EC=97=90=20?= =?UTF-8?q?=EB=9D=84=EC=9A=B0=EB=8A=94=20render=ED=95=A8=EC=88=98=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/domain/BaseballGame.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/domain/BaseballGame.js b/src/domain/BaseballGame.js index 48569be2..72c5fea2 100644 --- a/src/domain/BaseballGame.js +++ b/src/domain/BaseballGame.js @@ -7,11 +7,14 @@ export default class BaseballGame { this.input = input; this.result = result; this.submitBtn = submitBtn; + this.computerInputNumbers = this.getComputerInputNumbers(); + this.submitBtn.addEventListener('click', (event) => { event.preventDefault(); const userInputNumbers = this.input.value; const playResult = this.play(this.computerInputNumbers, userInputNumbers); + this.render(playResult); }); } @@ -51,4 +54,8 @@ export default class BaseballGame { return ballStr + strikeStr; } + + render(resultStr) { + this.result.innerHTML = resultStr; + } } From 144843afc746f7990bd9071654675415e59f3809 Mon Sep 17 00:00:00 2001 From: gxxrxn Date: Sun, 22 May 2022 19:08:46 +0900 Subject: [PATCH 11/29] =?UTF-8?q?docs:=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EC=9A=94=EA=B5=AC?= =?UTF-8?q?=EC=82=AC=ED=95=AD=20=EB=AA=A9=EB=A1=9D=20=EC=97=85=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 힌트를 출력한다. --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 71ceca61..6dd28faa 100644 --- a/docs/README.md +++ b/docs/README.md @@ -16,7 +16,7 @@ - [x] 숫자가 다른 위치에 있는 경우 `볼` 힌트를 전달한다. - [x] 숫자가 존재하지 않는 경우 `낫싱` 힌트를 전달한다. - [x] 힌트는 볼, 스트라이크 순서로 전달한다. - - [ ] 힌트를 출력한다. + - [x] 힌트를 출력한다. - [ ] 입력받은 수와 정답이 같으면 게임이 종료되고, 게임을 재시작할 수 있다. - [ ] 잘못된 값을 입력한 경우, 에러 메시지가 뜨고 값을 재입력할 수 있다. - [ ] 수를 중복해서 입력한 경우 From 77e984c8f56f423ace537607958c36608f6db722 Mon Sep 17 00:00:00 2001 From: gxxrxn Date: Sun, 22 May 2022 19:22:55 +0900 Subject: [PATCH 12/29] =?UTF-8?q?feat:=20=EC=A0=95=EB=8B=B5=EC=9D=84=20?= =?UTF-8?q?=EB=A7=9E=EC=B6=94=EB=A9=B4=20=EA=B2=8C=EC=9E=84=20=EC=A2=85?= =?UTF-8?q?=EB=A3=8C=20=EB=B0=8F=20=EC=9E=AC=EC=8B=9C=EC=9E=91=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 재시작을 위한 html template constants.js에 분리 - 정답이면 재시작 template을 결과에 출력 - 재시작 button 이벤트핸들러 연결 --- src/constants.js | 4 +++- src/domain/BaseballGame.js | 18 ++++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/constants.js b/src/constants.js index 41c6a300..1652cd74 100644 --- a/src/constants.js +++ b/src/constants.js @@ -7,4 +7,6 @@ const HINT = { const EMPTY_STR = ''; -export { HINT, EMPTY_STR }; +const RESTART_TEMPLATE = `

게임을 새로 시작하겠습니까?

`; + +export { HINT, EMPTY_STR, RESTART_TEMPLATE }; diff --git a/src/domain/BaseballGame.js b/src/domain/BaseballGame.js index 72c5fea2..2c5dbb83 100644 --- a/src/domain/BaseballGame.js +++ b/src/domain/BaseballGame.js @@ -1,4 +1,4 @@ -import { HINT, EMPTY_STR } from '../constants.js'; +import { HINT, EMPTY_STR, RESTART_TEMPLATE } from '../constants.js'; const { pickNumberInRange } = MissionUtils.Random; @@ -10,7 +10,7 @@ export default class BaseballGame { this.computerInputNumbers = this.getComputerInputNumbers(); - this.submitBtn.addEventListener('click', (event) => { + this.submitBtn = this.submitBtn.addEventListener('click', (event) => { event.preventDefault(); const userInputNumbers = this.input.value; const playResult = this.play(this.computerInputNumbers, userInputNumbers); @@ -18,6 +18,15 @@ export default class BaseballGame { }); } + bindRestartEvent() { + const restartBtn = document.querySelector('#restart'); + restartBtn.addEventListener('click', (event) => { + this.computerInputNumbers = this.getComputerInputNumbers(); + this.input.value = EMPTY_STR; + this.result.innerHTML = EMPTY_STR; + }); + } + getComputerInputNumbers() { let result = new Set(); @@ -57,5 +66,10 @@ export default class BaseballGame { render(resultStr) { this.result.innerHTML = resultStr; + + if (resultStr === HINT.CORRECT) { + this.result.innerHTML += RESTART_TEMPLATE; + this.bindRestartEvent(); + } } } From fc656a95a7d51b317baaf91aa24c5706a8ec293d Mon Sep 17 00:00:00 2001 From: gxxrxn Date: Sun, 22 May 2022 19:23:41 +0900 Subject: [PATCH 13/29] =?UTF-8?q?docs:=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EC=9A=94=EA=B5=AC?= =?UTF-8?q?=EC=82=AC=ED=95=AD=20=EB=AA=A9=EB=A1=9D=20=EC=97=85=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 입력받은 수와 정답이 같으면 게임이 종료되고, 게임을 재시작할 수 있다. --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 6dd28faa..cb8dfdf0 100644 --- a/docs/README.md +++ b/docs/README.md @@ -17,7 +17,7 @@ - [x] 숫자가 존재하지 않는 경우 `낫싱` 힌트를 전달한다. - [x] 힌트는 볼, 스트라이크 순서로 전달한다. - [x] 힌트를 출력한다. -- [ ] 입력받은 수와 정답이 같으면 게임이 종료되고, 게임을 재시작할 수 있다. +- [x] 입력받은 수와 정답이 같으면 게임이 종료되고, 게임을 재시작할 수 있다. - [ ] 잘못된 값을 입력한 경우, 에러 메시지가 뜨고 값을 재입력할 수 있다. - [ ] 수를 중복해서 입력한 경우 - [ ] 입력한 수가 3자리가 아닌 경우 From d3ae8a9db3e3da991c06b224cbadf19e8518acc9 Mon Sep 17 00:00:00 2001 From: gxxrxn Date: Sun, 22 May 2022 21:16:41 +0900 Subject: [PATCH 14/29] =?UTF-8?q?feat:=20BaseballGame=20user=20input=20?= =?UTF-8?q?=EC=9C=A0=ED=9A=A8=EC=84=B1=20=EA=B2=80=EC=82=AC=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - alert message 상수로 분리 - validator.js에 유효성 검사 관련 함수 작성 - BaseballGame에서 user input 유효성 검사 후, 관련된 에러메시지 출력 --- src/constants.js | 13 ++++++++--- src/domain/BaseballGame.js | 44 +++++++++++++++++++++++++++++++++++--- src/domain/validator.js | 5 +++++ 3 files changed, 56 insertions(+), 6 deletions(-) create mode 100644 src/domain/validator.js diff --git a/src/constants.js b/src/constants.js index 1652cd74..394ad4d0 100644 --- a/src/constants.js +++ b/src/constants.js @@ -1,3 +1,5 @@ +const EMPTY_STR = ''; + const HINT = { BALL: '볼', STRIKE: '스트라이크', @@ -5,8 +7,13 @@ const HINT = { NOTHING: '낫싱', }; -const EMPTY_STR = ''; - const RESTART_TEMPLATE = `

게임을 새로 시작하겠습니까?

`; -export { HINT, EMPTY_STR, RESTART_TEMPLATE }; +const ALERT_MESSAGE = { + DUPLICATE: '중복된 숫자가 있습니다.', + INVALID_LENGTH: '3자리 숫자를 입력해주세요.', + SPACE: '공백을 제외해주세요.', + NAN: '숫자만 입력해주세요.', +}; + +export { HINT, EMPTY_STR, RESTART_TEMPLATE, ALERT_MESSAGE }; diff --git a/src/domain/BaseballGame.js b/src/domain/BaseballGame.js index 2c5dbb83..35d781a0 100644 --- a/src/domain/BaseballGame.js +++ b/src/domain/BaseballGame.js @@ -1,4 +1,10 @@ -import { HINT, EMPTY_STR, RESTART_TEMPLATE } from '../constants.js'; +import { isDuplicated, isInvalidLength, includeSpace } from './validator.js'; +import { + HINT, + EMPTY_STR, + RESTART_TEMPLATE, + ALERT_MESSAGE, +} from '../constants.js'; const { pickNumberInRange } = MissionUtils.Random; @@ -13,17 +19,49 @@ export default class BaseballGame { this.submitBtn = this.submitBtn.addEventListener('click', (event) => { event.preventDefault(); const userInputNumbers = this.input.value; + if (!this.validateInput(userInputNumbers)) { + this.initInput(); + return; + } + const playResult = this.play(this.computerInputNumbers, userInputNumbers); this.render(playResult); }); } + validateInput(inputNumbers) { + let message = []; + + if (isNaN(inputNumbers)) { + message.push(ALERT_MESSAGE.NAN); + } + if (includeSpace(inputNumbers)) { + message.push(ALERT_MESSAGE.SPACE); + } + if (isDuplicated(inputNumbers)) { + message.push(ALERT_MESSAGE.DUPLICATE); + } + if (isInvalidLength(inputNumbers)) { + message.push(ALERT_MESSAGE.INVALID_LENGTH); + } + + if (message.length > 0) { + alert(message.join('\n')); + } + + return message.length === 0; + } + + initInput() { + this.input.value = EMPTY_STR; + this.result.innerHTML = EMPTY_STR; + } + bindRestartEvent() { const restartBtn = document.querySelector('#restart'); restartBtn.addEventListener('click', (event) => { this.computerInputNumbers = this.getComputerInputNumbers(); - this.input.value = EMPTY_STR; - this.result.innerHTML = EMPTY_STR; + this.initInput(); }); } diff --git a/src/domain/validator.js b/src/domain/validator.js new file mode 100644 index 00000000..87cd0223 --- /dev/null +++ b/src/domain/validator.js @@ -0,0 +1,5 @@ +const isDuplicated = (number) => new Set(number).size !== number.length; +const isInvalidLength = (number) => number.length !== 3; +const includeSpace = (number) => (number.match(/ /gi) ? true : false); + +export { isDuplicated, isInvalidLength, includeSpace }; From 8981f4e5858fd8c6f0619774a9c57b9bdc11b3c7 Mon Sep 17 00:00:00 2001 From: gxxrxn Date: Sun, 22 May 2022 21:17:27 +0900 Subject: [PATCH 15/29] =?UTF-8?q?docs:=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EC=9A=94=EA=B5=AC?= =?UTF-8?q?=EC=82=AC=ED=95=AD=20=EB=AA=A9=EB=A1=9D=20=EC=97=85=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 잘못된 값을 입력한 경우, 에러 메시지가 뜨고 값을 재입력할 수 있다. --- docs/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/README.md b/docs/README.md index cb8dfdf0..735fae12 100644 --- a/docs/README.md +++ b/docs/README.md @@ -18,8 +18,8 @@ - [x] 힌트는 볼, 스트라이크 순서로 전달한다. - [x] 힌트를 출력한다. - [x] 입력받은 수와 정답이 같으면 게임이 종료되고, 게임을 재시작할 수 있다. -- [ ] 잘못된 값을 입력한 경우, 에러 메시지가 뜨고 값을 재입력할 수 있다. - - [ ] 수를 중복해서 입력한 경우 - - [ ] 입력한 수가 3자리가 아닌 경우 - - [ ] 숫자가 아닌 문자 등을 입력한 경우 - - [ ] 공백이 입력된 경우 +- [x] 잘못된 값을 입력한 경우, 에러 메시지가 뜨고 값을 재입력할 수 있다. + - [x] 수를 중복해서 입력한 경우 + - [x] 입력한 수가 3자리가 아닌 경우 + - [x] 숫자가 아닌 문자 등을 입력한 경우 + - [x] 공백이 입력된 경우 From 7bae84e2aa606a99fe7dcc0466c13ed19f9d2dbc Mon Sep 17 00:00:00 2001 From: gxxrxn Date: Sun, 22 May 2022 21:31:16 +0900 Subject: [PATCH 16/29] Merge branch 'upstream/main' into greantea --- package-lock.json | 2 +- package.json | 2 +- src/constants.js | 2 +- src/domain/BaseballGame.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 73b68f96..923ec4a3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2754,4 +2754,4 @@ } } } -} +} \ No newline at end of file diff --git a/package.json b/package.json index cbdad8d1..e0621c94 100644 --- a/package.json +++ b/package.json @@ -31,4 +31,4 @@ "npm": ">=6.0.0", "node": ">=14.0.0" } -} +} \ No newline at end of file diff --git a/src/constants.js b/src/constants.js index 394ad4d0..d13e9389 100644 --- a/src/constants.js +++ b/src/constants.js @@ -7,7 +7,7 @@ const HINT = { NOTHING: '낫싱', }; -const RESTART_TEMPLATE = `

게임을 새로 시작하겠습니까?

`; +const RESTART_TEMPLATE = `

게임을 새로 시작하겠습니까?

`; const ALERT_MESSAGE = { DUPLICATE: '중복된 숫자가 있습니다.', diff --git a/src/domain/BaseballGame.js b/src/domain/BaseballGame.js index 35d781a0..9465af87 100644 --- a/src/domain/BaseballGame.js +++ b/src/domain/BaseballGame.js @@ -58,7 +58,7 @@ export default class BaseballGame { } bindRestartEvent() { - const restartBtn = document.querySelector('#restart'); + const restartBtn = document.querySelector('#game-restart-button'); restartBtn.addEventListener('click', (event) => { this.computerInputNumbers = this.getComputerInputNumbers(); this.initInput(); From 998e089a42037d3aac8a1caadc8b706526024f38 Mon Sep 17 00:00:00 2001 From: MINJOO-KIM Date: Wed, 25 May 2022 23:34:12 +0900 Subject: [PATCH 17/29] =?UTF-8?q?chore(eslint):=20eslint=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/{constants.js => constants.mjs} | 3 ++- .../{BaseballGame.js => BaseballGame.mjs} | 25 ++++++++++--------- src/domain/{validator.js => validator.mjs} | 2 +- src/index.js | 2 +- 4 files changed, 17 insertions(+), 15 deletions(-) rename src/{constants.js => constants.mjs} (76%) rename src/domain/{BaseballGame.js => BaseballGame.mjs} (82%) rename src/domain/{validator.js => validator.mjs} (72%) diff --git a/src/constants.js b/src/constants.mjs similarity index 76% rename from src/constants.js rename to src/constants.mjs index d13e9389..7db62144 100644 --- a/src/constants.js +++ b/src/constants.mjs @@ -7,7 +7,8 @@ const HINT = { NOTHING: '낫싱', }; -const RESTART_TEMPLATE = `

게임을 새로 시작하겠습니까?

`; +const RESTART_TEMPLATE = + '

게임을 새로 시작하겠습니까?

'; const ALERT_MESSAGE = { DUPLICATE: '중복된 숫자가 있습니다.', diff --git a/src/domain/BaseballGame.js b/src/domain/BaseballGame.mjs similarity index 82% rename from src/domain/BaseballGame.js rename to src/domain/BaseballGame.mjs index 9465af87..85734283 100644 --- a/src/domain/BaseballGame.js +++ b/src/domain/BaseballGame.mjs @@ -1,11 +1,12 @@ -import { isDuplicated, isInvalidLength, includeSpace } from './validator.js'; +import { isDuplicated, isInvalidLength, includeSpace } from './validator.mjs'; import { HINT, EMPTY_STR, RESTART_TEMPLATE, ALERT_MESSAGE, -} from '../constants.js'; +} from '../constants.mjs'; +/* global MissionUtils */ const { pickNumberInRange } = MissionUtils.Random; export default class BaseballGame { @@ -30,9 +31,9 @@ export default class BaseballGame { } validateInput(inputNumbers) { - let message = []; + const message = []; - if (isNaN(inputNumbers)) { + if (Number.isNaN(inputNumbers)) { message.push(ALERT_MESSAGE.NAN); } if (includeSpace(inputNumbers)) { @@ -59,14 +60,14 @@ export default class BaseballGame { bindRestartEvent() { const restartBtn = document.querySelector('#game-restart-button'); - restartBtn.addEventListener('click', (event) => { + restartBtn.addEventListener('click', () => { this.computerInputNumbers = this.getComputerInputNumbers(); this.initInput(); }); } getComputerInputNumbers() { - let result = new Set(); + const result = new Set(); while (result.size < 3) { const pickedNumber = pickNumberInRange(1, 9); @@ -77,18 +78,18 @@ export default class BaseballGame { } play(computerInputNumbers, userInputNumbers) { - if (computerInputNumbers == userInputNumbers) { + if (computerInputNumbers === userInputNumbers) { return HINT.CORRECT; } let strike = 0; let ball = 0; - for (let i = 0; i < computerInputNumbers.length; i++) { + for (let i = 0; i < computerInputNumbers.length; i += 1) { if (computerInputNumbers[i] === userInputNumbers[i]) { - strike++; + strike += 1; } else if (userInputNumbers.indexOf(computerInputNumbers[i]) !== -1) { - ball++; + ball += 1; } } @@ -96,8 +97,8 @@ export default class BaseballGame { return HINT.NOTHING; } - let ballStr = ball ? `${ball}${HINT.BALL}` : `${EMPTY_STR}`; - let strikeStr = strike ? `${strike}${HINT.STRIKE}` : `${EMPTY_STR}`; + const ballStr = ball ? `${ball}${HINT.BALL}` : `${EMPTY_STR}`; + const strikeStr = strike ? `${strike}${HINT.STRIKE}` : `${EMPTY_STR}`; return ballStr + strikeStr; } diff --git a/src/domain/validator.js b/src/domain/validator.mjs similarity index 72% rename from src/domain/validator.js rename to src/domain/validator.mjs index 87cd0223..8851b67a 100644 --- a/src/domain/validator.js +++ b/src/domain/validator.mjs @@ -1,5 +1,5 @@ const isDuplicated = (number) => new Set(number).size !== number.length; const isInvalidLength = (number) => number.length !== 3; -const includeSpace = (number) => (number.match(/ /gi) ? true : false); +const includeSpace = (number) => !!number.match(/ /gi); export { isDuplicated, isInvalidLength, includeSpace }; diff --git a/src/index.js b/src/index.js index 00d778c7..628f0f8f 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,4 @@ -import BaseballGame from './domain/BaseballGame.js'; +import BaseballGame from './domain/BaseballGame.mjs'; const input = document.querySelector('#user-input'); const result = document.querySelector('#result'); From 453dbade49d4b481ce093626b2c5a55fc4789bff Mon Sep 17 00:00:00 2001 From: MINJOO-KIM Date: Wed, 25 May 2022 23:49:32 +0900 Subject: [PATCH 18/29] =?UTF-8?q?refactor(validator):=20isNaN=20=ED=95=A8?= =?UTF-8?q?=EC=88=98=20=EC=83=9D=EC=84=B1=20=ED=9B=84=20validator=EB=A1=9C?= =?UTF-8?q?=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/domain/BaseballGame.mjs | 9 +++++++-- src/domain/validator.mjs | 3 ++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/domain/BaseballGame.mjs b/src/domain/BaseballGame.mjs index 85734283..516754cb 100644 --- a/src/domain/BaseballGame.mjs +++ b/src/domain/BaseballGame.mjs @@ -1,4 +1,9 @@ -import { isDuplicated, isInvalidLength, includeSpace } from './validator.mjs'; +import { + isDuplicated, + isInvalidLength, + includeSpace, + isNaN, +} from './validator.mjs'; import { HINT, EMPTY_STR, @@ -33,7 +38,7 @@ export default class BaseballGame { validateInput(inputNumbers) { const message = []; - if (Number.isNaN(inputNumbers)) { + if (isNaN(inputNumbers)) { message.push(ALERT_MESSAGE.NAN); } if (includeSpace(inputNumbers)) { diff --git a/src/domain/validator.mjs b/src/domain/validator.mjs index 8851b67a..4ec3ba7d 100644 --- a/src/domain/validator.mjs +++ b/src/domain/validator.mjs @@ -1,5 +1,6 @@ const isDuplicated = (number) => new Set(number).size !== number.length; const isInvalidLength = (number) => number.length !== 3; const includeSpace = (number) => !!number.match(/ /gi); +const isNaN = (number) => Number.isNaN(Number(number)); -export { isDuplicated, isInvalidLength, includeSpace }; +export { isDuplicated, isInvalidLength, includeSpace, isNaN }; From fd45671f270dda918e51dc212956c32728d90e3e Mon Sep 17 00:00:00 2001 From: MINJOO-KIM Date: Wed, 25 May 2022 23:59:59 +0900 Subject: [PATCH 19/29] =?UTF-8?q?refactor(event):=20submit=20=EC=9D=B4?= =?UTF-8?q?=EB=B2=A4=ED=8A=B8=20=ED=95=B8=EB=93=A4=EB=9F=AC=20=ED=95=A8?= =?UTF-8?q?=EC=88=98=EB=A1=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - bindSubmitEvent 함수 분리 --- src/domain/BaseballGame.mjs | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/domain/BaseballGame.mjs b/src/domain/BaseballGame.mjs index 516754cb..c8bf2f05 100644 --- a/src/domain/BaseballGame.mjs +++ b/src/domain/BaseballGame.mjs @@ -22,19 +22,26 @@ export default class BaseballGame { this.computerInputNumbers = this.getComputerInputNumbers(); - this.submitBtn = this.submitBtn.addEventListener('click', (event) => { - event.preventDefault(); - const userInputNumbers = this.input.value; - if (!this.validateInput(userInputNumbers)) { - this.initInput(); - return; - } - - const playResult = this.play(this.computerInputNumbers, userInputNumbers); - this.render(playResult); + this.submitBtn.addEventListener('click', (event) => { + this.bindSubmitEvent(event); }); } + bindSubmitEvent(event) { + event.preventDefault(); + + const userInputNumbers = this.input.value; + + if (!this.validateInput(userInputNumbers)) { + this.initInput(); + return; + } + + const playResult = this.play(this.computerInputNumbers, userInputNumbers); + + this.render(playResult); + } + validateInput(inputNumbers) { const message = []; From 299d98352f174139d29d6dc89d86af0a14d6c1e8 Mon Sep 17 00:00:00 2001 From: MINJOO-KIM Date: Sun, 29 May 2022 22:34:34 +0900 Subject: [PATCH 20/29] =?UTF-8?q?refactor(BaseballGame):=20BaseballGame?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EB=B6=84=EB=A6=AC=EA=B0=80=EB=8A=A5?= =?UTF-8?q?=ED=95=9C=20=ED=95=A8=EC=88=98=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - validator.mjs로 validateUserInput 분리 - pickComputerInputNumbers, joinHint 메소드 유틸로 분리 --- src/domain/BaseballGame.mjs | 72 ++++++------------------------------- src/domain/validator.mjs | 37 ++++++++++++++++--- src/utils.mjs | 23 ++++++++++++ 3 files changed, 66 insertions(+), 66 deletions(-) create mode 100644 src/utils.mjs diff --git a/src/domain/BaseballGame.mjs b/src/domain/BaseballGame.mjs index c8bf2f05..bb0753fd 100644 --- a/src/domain/BaseballGame.mjs +++ b/src/domain/BaseballGame.mjs @@ -1,18 +1,6 @@ -import { - isDuplicated, - isInvalidLength, - includeSpace, - isNaN, -} from './validator.mjs'; -import { - HINT, - EMPTY_STR, - RESTART_TEMPLATE, - ALERT_MESSAGE, -} from '../constants.mjs'; - -/* global MissionUtils */ -const { pickNumberInRange } = MissionUtils.Random; +import { HINT, EMPTY_STR, RESTART_TEMPLATE } from '../constants.mjs'; +import { pickComputerInputNumbers, joinHint } from '../utils.mjs'; +import { validateUserInput } from './validator.mjs'; export default class BaseballGame { constructor(input, result, submitBtn) { @@ -20,51 +8,27 @@ export default class BaseballGame { this.result = result; this.submitBtn = submitBtn; - this.computerInputNumbers = this.getComputerInputNumbers(); + this.computerInputNumbers = pickComputerInputNumbers(); - this.submitBtn.addEventListener('click', (event) => { - this.bindSubmitEvent(event); - }); + this.submitBtn.addEventListener('click', this.inputSubmitEvent.bind(this)); } - bindSubmitEvent(event) { + inputSubmitEvent(event) { event.preventDefault(); const userInputNumbers = this.input.value; + const validateResult = validateUserInput(userInputNumbers); - if (!this.validateInput(userInputNumbers)) { + if (validateResult.isError) { + alert(validateResult.message.join('\n')); this.initInput(); return; } const playResult = this.play(this.computerInputNumbers, userInputNumbers); - this.render(playResult); } - validateInput(inputNumbers) { - const message = []; - - if (isNaN(inputNumbers)) { - message.push(ALERT_MESSAGE.NAN); - } - if (includeSpace(inputNumbers)) { - message.push(ALERT_MESSAGE.SPACE); - } - if (isDuplicated(inputNumbers)) { - message.push(ALERT_MESSAGE.DUPLICATE); - } - if (isInvalidLength(inputNumbers)) { - message.push(ALERT_MESSAGE.INVALID_LENGTH); - } - - if (message.length > 0) { - alert(message.join('\n')); - } - - return message.length === 0; - } - initInput() { this.input.value = EMPTY_STR; this.result.innerHTML = EMPTY_STR; @@ -73,22 +37,11 @@ export default class BaseballGame { bindRestartEvent() { const restartBtn = document.querySelector('#game-restart-button'); restartBtn.addEventListener('click', () => { - this.computerInputNumbers = this.getComputerInputNumbers(); + this.computerInputNumbers = pickComputerInputNumbers(); this.initInput(); }); } - getComputerInputNumbers() { - const result = new Set(); - - while (result.size < 3) { - const pickedNumber = pickNumberInRange(1, 9); - result.add(pickedNumber.toString()); - } - - return Array.from(result).join(''); - } - play(computerInputNumbers, userInputNumbers) { if (computerInputNumbers === userInputNumbers) { return HINT.CORRECT; @@ -109,10 +62,7 @@ export default class BaseballGame { return HINT.NOTHING; } - const ballStr = ball ? `${ball}${HINT.BALL}` : `${EMPTY_STR}`; - const strikeStr = strike ? `${strike}${HINT.STRIKE}` : `${EMPTY_STR}`; - - return ballStr + strikeStr; + return joinHint(ball, strike); } render(resultStr) { diff --git a/src/domain/validator.mjs b/src/domain/validator.mjs index 4ec3ba7d..c459e31c 100644 --- a/src/domain/validator.mjs +++ b/src/domain/validator.mjs @@ -1,6 +1,33 @@ -const isDuplicated = (number) => new Set(number).size !== number.length; -const isInvalidLength = (number) => number.length !== 3; -const includeSpace = (number) => !!number.match(/ /gi); -const isNaN = (number) => Number.isNaN(Number(number)); +import { ALERT_MESSAGE } from '../constants.mjs'; -export { isDuplicated, isInvalidLength, includeSpace, isNaN }; +const isDuplicated = (value) => new Set(value).size !== value.length; +const isInvalidLength = (value) => value.length !== 3; +const includeSpace = (value) => !!value.match(/ /gi); +const isNaN = (value) => Number.isNaN(Number(value)); + +const validateUserInput = (value) => { + const message = []; + + if (isNaN(value)) { + message.push(ALERT_MESSAGE.NAN); + } + if (includeSpace(value)) { + message.push(ALERT_MESSAGE.SPACE); + } + if (isDuplicated(value)) { + message.push(ALERT_MESSAGE.DUPLICATE); + } + if (isInvalidLength(value)) { + message.push(ALERT_MESSAGE.INVALID_LENGTH); + } + + return { isError: message.length !== 0, message }; +}; + +export { + isDuplicated, + isInvalidLength, + includeSpace, + isNaN, + validateUserInput, +}; diff --git a/src/utils.mjs b/src/utils.mjs new file mode 100644 index 00000000..0c4696c2 --- /dev/null +++ b/src/utils.mjs @@ -0,0 +1,23 @@ +import { HINT, EMPTY_STR } from './constants.mjs'; + +const pickComputerInputNumbers = () => { + /* global MissionUtils */ + const { pickNumberInRange } = MissionUtils.Random; + const result = new Set(); + + while (result.size < 3) { + const pickedNumber = pickNumberInRange(1, 9); + result.add(pickedNumber.toString()); + } + + return Array.from(result).join(''); +}; + +const joinHint = (ball, strike) => { + const ballStr = ball ? `${ball}${HINT.BALL}` : `${EMPTY_STR}`; + const strikeStr = strike ? `${strike}${HINT.STRIKE}` : `${EMPTY_STR}`; + + return ballStr + strikeStr; +}; + +export { pickComputerInputNumbers, joinHint }; From 219f8d84f7284bb87d4497e77d50c7c11c7c5283 Mon Sep 17 00:00:00 2001 From: MINJOO-KIM Date: Sun, 29 May 2022 22:42:26 +0900 Subject: [PATCH 21/29] =?UTF-8?q?refactor(selector):=20dom=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5=20=EB=B3=80=EC=88=98=20=EC=9D=B4=EB=A6=84=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - input -> inputView - result -> resultView --- src/domain/BaseballGame.mjs | 6 +++--- src/index.js | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/domain/BaseballGame.mjs b/src/domain/BaseballGame.mjs index bb0753fd..b1316262 100644 --- a/src/domain/BaseballGame.mjs +++ b/src/domain/BaseballGame.mjs @@ -3,9 +3,9 @@ import { pickComputerInputNumbers, joinHint } from '../utils.mjs'; import { validateUserInput } from './validator.mjs'; export default class BaseballGame { - constructor(input, result, submitBtn) { - this.input = input; - this.result = result; + constructor(inputView, resultView, submitBtn) { + this.inputView = inputView; + this.resultView = resultView; this.submitBtn = submitBtn; this.computerInputNumbers = pickComputerInputNumbers(); diff --git a/src/index.js b/src/index.js index 628f0f8f..9a4eb18b 100644 --- a/src/index.js +++ b/src/index.js @@ -1,7 +1,7 @@ import BaseballGame from './domain/BaseballGame.mjs'; -const input = document.querySelector('#user-input'); -const result = document.querySelector('#result'); +const inputView = document.querySelector('#user-input'); +const resultView = document.querySelector('#result'); const submitBtn = document.querySelector('#submit'); -new BaseballGame(input, result, submitBtn); +new BaseballGame(inputView, resultView, submitBtn); From 8a5be44486b2bbdbe48daca86d12b238e9d02ede Mon Sep 17 00:00:00 2001 From: MINJOO-KIM Date: Sun, 29 May 2022 23:18:41 +0900 Subject: [PATCH 22/29] =?UTF-8?q?refactor(selector):=20DOM=5FID=20?= =?UTF-8?q?=EC=83=81=EC=88=98=EB=A1=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/constants.mjs | 11 +++++++++-- src/index.js | 7 ++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/constants.mjs b/src/constants.mjs index 7db62144..aeab1bc6 100644 --- a/src/constants.mjs +++ b/src/constants.mjs @@ -1,4 +1,9 @@ -const EMPTY_STR = ''; +const DOM_ID = { + INPUT: 'user-input', + SUBMIT: 'submit', + RESULT: 'result', + RESTART: 'game-restart-button', +}; const HINT = { BALL: '볼', @@ -17,4 +22,6 @@ const ALERT_MESSAGE = { NAN: '숫자만 입력해주세요.', }; -export { HINT, EMPTY_STR, RESTART_TEMPLATE, ALERT_MESSAGE }; +const EMPTY_STR = ''; + +export { DOM_ID, HINT, EMPTY_STR, RESTART_TEMPLATE, ALERT_MESSAGE }; diff --git a/src/index.js b/src/index.js index 9a4eb18b..76cee6d1 100644 --- a/src/index.js +++ b/src/index.js @@ -1,7 +1,8 @@ import BaseballGame from './domain/BaseballGame.mjs'; +import { DOM_ID } from './constants.mjs'; -const inputView = document.querySelector('#user-input'); -const resultView = document.querySelector('#result'); -const submitBtn = document.querySelector('#submit'); +const inputView = document.getElementById(DOM_ID.INPUT); +const resultView = document.getElementById(DOM_ID.RESULT); +const submitBtn = document.getElementById(DOM_ID.SUBMIT); new BaseballGame(inputView, resultView, submitBtn); From 749a3646d0b29dbc576455644ec75a85e6a89065 Mon Sep 17 00:00:00 2001 From: MINJOO-KIM Date: Sun, 29 May 2022 23:23:26 +0900 Subject: [PATCH 23/29] =?UTF-8?q?refactor(BaseballGame):=20resultView?= =?UTF-8?q?=EC=97=90=20click=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - game-restart-button에 있던 click이벤트를 resultView로 이동 - initInputView와 initResultView로 분리 - userInput이 유효하지 않은 경우, 이전결과는 남아있도록 수정 --- src/domain/BaseballGame.mjs | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/domain/BaseballGame.mjs b/src/domain/BaseballGame.mjs index b1316262..ea6ab172 100644 --- a/src/domain/BaseballGame.mjs +++ b/src/domain/BaseballGame.mjs @@ -1,4 +1,4 @@ -import { HINT, EMPTY_STR, RESTART_TEMPLATE } from '../constants.mjs'; +import { DOM_ID, HINT, EMPTY_STR, RESTART_TEMPLATE } from '../constants.mjs'; import { pickComputerInputNumbers, joinHint } from '../utils.mjs'; import { validateUserInput } from './validator.mjs'; @@ -7,21 +7,21 @@ export default class BaseballGame { this.inputView = inputView; this.resultView = resultView; this.submitBtn = submitBtn; - this.computerInputNumbers = pickComputerInputNumbers(); this.submitBtn.addEventListener('click', this.inputSubmitEvent.bind(this)); + this.resultView.addEventListener('click', this.restartEvent.bind(this)); } inputSubmitEvent(event) { event.preventDefault(); - const userInputNumbers = this.input.value; + const userInputNumbers = this.inputView.value; const validateResult = validateUserInput(userInputNumbers); if (validateResult.isError) { alert(validateResult.message.join('\n')); - this.initInput(); + this.initInputView(); return; } @@ -29,17 +29,20 @@ export default class BaseballGame { this.render(playResult); } - initInput() { - this.input.value = EMPTY_STR; - this.result.innerHTML = EMPTY_STR; + restartEvent(event) { + if (event.target.id === DOM_ID.RESTART) { + this.computerInputNumbers = pickComputerInputNumbers(); + this.initInputView(); + } + } + + initInputView() { + this.inputView.value = EMPTY_STR; + this.inputView.focus(); } - bindRestartEvent() { - const restartBtn = document.querySelector('#game-restart-button'); - restartBtn.addEventListener('click', () => { - this.computerInputNumbers = pickComputerInputNumbers(); - this.initInput(); - }); + initResultView() { + this.resultView.innerHTML = EMPTY_STR; } play(computerInputNumbers, userInputNumbers) { @@ -66,11 +69,10 @@ export default class BaseballGame { } render(resultStr) { - this.result.innerHTML = resultStr; + this.resultView.innerHTML = resultStr; if (resultStr === HINT.CORRECT) { - this.result.innerHTML += RESTART_TEMPLATE; - this.bindRestartEvent(); + this.resultView.innerHTML += RESTART_TEMPLATE; } } } From 58cc765f7da691acd9bdf948415145098bfc12ce Mon Sep 17 00:00:00 2001 From: MINJOO-KIM Date: Sun, 29 May 2022 23:29:50 +0900 Subject: [PATCH 24/29] =?UTF-8?q?refactor(constants):=20STRING=EC=97=90=20?= =?UTF-8?q?=EB=B9=88=EB=AC=B8=EC=9E=90=EC=97=B4,=20=EA=B0=9C=ED=96=89=20?= =?UTF-8?q?=EC=84=A0=EC=96=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 그에 따른 변수명 변경 --- src/constants.mjs | 7 +++++-- src/domain/BaseballGame.mjs | 10 +++++----- src/utils.mjs | 6 +++--- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/constants.mjs b/src/constants.mjs index aeab1bc6..e884cd40 100644 --- a/src/constants.mjs +++ b/src/constants.mjs @@ -22,6 +22,9 @@ const ALERT_MESSAGE = { NAN: '숫자만 입력해주세요.', }; -const EMPTY_STR = ''; +const STRING = { + EMPTY: '', + NEW_LINE: '\n', +}; -export { DOM_ID, HINT, EMPTY_STR, RESTART_TEMPLATE, ALERT_MESSAGE }; +export { DOM_ID, HINT, RESTART_TEMPLATE, ALERT_MESSAGE, STRING }; diff --git a/src/domain/BaseballGame.mjs b/src/domain/BaseballGame.mjs index ea6ab172..13f6a1ae 100644 --- a/src/domain/BaseballGame.mjs +++ b/src/domain/BaseballGame.mjs @@ -1,4 +1,4 @@ -import { DOM_ID, HINT, EMPTY_STR, RESTART_TEMPLATE } from '../constants.mjs'; +import { DOM_ID, HINT, RESTART_TEMPLATE, STRING } from '../constants.mjs'; import { pickComputerInputNumbers, joinHint } from '../utils.mjs'; import { validateUserInput } from './validator.mjs'; @@ -20,7 +20,7 @@ export default class BaseballGame { const validateResult = validateUserInput(userInputNumbers); if (validateResult.isError) { - alert(validateResult.message.join('\n')); + alert(validateResult.message.join(STRING.NEW_LINE)); this.initInputView(); return; } @@ -37,12 +37,12 @@ export default class BaseballGame { } initInputView() { - this.inputView.value = EMPTY_STR; + this.inputView.value = STRING.EMPTY; this.inputView.focus(); } initResultView() { - this.resultView.innerHTML = EMPTY_STR; + this.resultView.innerHTML = STRING.EMPTY; } play(computerInputNumbers, userInputNumbers) { @@ -50,8 +50,8 @@ export default class BaseballGame { return HINT.CORRECT; } - let strike = 0; let ball = 0; + let strike = 0; for (let i = 0; i < computerInputNumbers.length; i += 1) { if (computerInputNumbers[i] === userInputNumbers[i]) { diff --git a/src/utils.mjs b/src/utils.mjs index 0c4696c2..617362a3 100644 --- a/src/utils.mjs +++ b/src/utils.mjs @@ -1,4 +1,4 @@ -import { HINT, EMPTY_STR } from './constants.mjs'; +import { HINT, STRING } from './constants.mjs'; const pickComputerInputNumbers = () => { /* global MissionUtils */ @@ -14,8 +14,8 @@ const pickComputerInputNumbers = () => { }; const joinHint = (ball, strike) => { - const ballStr = ball ? `${ball}${HINT.BALL}` : `${EMPTY_STR}`; - const strikeStr = strike ? `${strike}${HINT.STRIKE}` : `${EMPTY_STR}`; + const ballStr = ball ? `${ball}${HINT.BALL}` : `${STRING.EMPTY}`; + const strikeStr = strike ? `${strike}${HINT.STRIKE}` : `${STRING.EMPTY}`; return ballStr + strikeStr; }; From 43f4ee8a6af70a969781cecf19136e22c7fbebc5 Mon Sep 17 00:00:00 2001 From: MINJOO-KIM Date: Sun, 29 May 2022 23:35:31 +0900 Subject: [PATCH 25/29] =?UTF-8?q?refactor(BaseballGame):=20strike,=20ball?= =?UTF-8?q?=20=EA=B4=80=EB=A0=A8=20=EB=B3=80=EC=88=98=EB=AA=85=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ball, strike -> ballCount, strikeCount - ballStr, strikeStr -> ballHint, strikeHint --- src/domain/BaseballGame.mjs | 12 ++++++------ src/utils.mjs | 10 ++++++---- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/domain/BaseballGame.mjs b/src/domain/BaseballGame.mjs index 13f6a1ae..c11c1ab2 100644 --- a/src/domain/BaseballGame.mjs +++ b/src/domain/BaseballGame.mjs @@ -50,22 +50,22 @@ export default class BaseballGame { return HINT.CORRECT; } - let ball = 0; - let strike = 0; + let ballCount = 0; + let strikeCount = 0; for (let i = 0; i < computerInputNumbers.length; i += 1) { if (computerInputNumbers[i] === userInputNumbers[i]) { - strike += 1; + strikeCount += 1; } else if (userInputNumbers.indexOf(computerInputNumbers[i]) !== -1) { - ball += 1; + ballCount += 1; } } - if (!strike && !ball) { + if (!strikeCount && !ballCount) { return HINT.NOTHING; } - return joinHint(ball, strike); + return joinHint(ballCount, strikeCount); } render(resultStr) { diff --git a/src/utils.mjs b/src/utils.mjs index 617362a3..91af1fe3 100644 --- a/src/utils.mjs +++ b/src/utils.mjs @@ -13,11 +13,13 @@ const pickComputerInputNumbers = () => { return Array.from(result).join(''); }; -const joinHint = (ball, strike) => { - const ballStr = ball ? `${ball}${HINT.BALL}` : `${STRING.EMPTY}`; - const strikeStr = strike ? `${strike}${HINT.STRIKE}` : `${STRING.EMPTY}`; +const joinHint = (ballCount, strikeCount) => { + const ballHint = ballCount ? `${ballCount}${HINT.BALL}` : `${STRING.EMPTY}`; + const strikeHint = strikeCount + ? `${strikeCount}${HINT.STRIKE}` + : `${STRING.EMPTY}`; - return ballStr + strikeStr; + return `${ballHint} ${strikeHint}`; }; export { pickComputerInputNumbers, joinHint }; From c51edf24a46d5cbf402f894cb8c8a911b188fb0f Mon Sep 17 00:00:00 2001 From: MINJOO-KIM Date: Sun, 29 May 2022 23:37:45 +0900 Subject: [PATCH 26/29] =?UTF-8?q?refactor(BaseballGame):=20render=20?= =?UTF-8?q?=ED=95=A8=EC=88=98=20=EB=A7=A4=EA=B0=9C=EB=B3=80=EC=88=98?= =?UTF-8?q?=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - resultStr -> result --- src/domain/BaseballGame.mjs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/domain/BaseballGame.mjs b/src/domain/BaseballGame.mjs index c11c1ab2..5f6d4bb8 100644 --- a/src/domain/BaseballGame.mjs +++ b/src/domain/BaseballGame.mjs @@ -68,10 +68,10 @@ export default class BaseballGame { return joinHint(ballCount, strikeCount); } - render(resultStr) { - this.resultView.innerHTML = resultStr; + render(result) { + this.resultView.innerHTML = result; - if (resultStr === HINT.CORRECT) { + if (result === HINT.CORRECT) { this.resultView.innerHTML += RESTART_TEMPLATE; } } From 86f305592951561f34832522d3ffcc228f58f69d Mon Sep 17 00:00:00 2001 From: MINJOO-KIM Date: Sun, 29 May 2022 23:43:52 +0900 Subject: [PATCH 27/29] =?UTF-8?q?refactor(validator):=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20=ED=95=A8=EC=88=98=20?= =?UTF-8?q?export=20=EC=A0=9C=EC=99=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - validateUserInput만 default로 export --- src/domain/BaseballGame.mjs | 3 ++- src/domain/validator.mjs | 13 +++---------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/domain/BaseballGame.mjs b/src/domain/BaseballGame.mjs index 5f6d4bb8..735b3cdd 100644 --- a/src/domain/BaseballGame.mjs +++ b/src/domain/BaseballGame.mjs @@ -1,6 +1,7 @@ import { DOM_ID, HINT, RESTART_TEMPLATE, STRING } from '../constants.mjs'; import { pickComputerInputNumbers, joinHint } from '../utils.mjs'; -import { validateUserInput } from './validator.mjs'; + +import validateUserInput from './validator.mjs'; export default class BaseballGame { constructor(inputView, resultView, submitBtn) { diff --git a/src/domain/validator.mjs b/src/domain/validator.mjs index c459e31c..12f14e5c 100644 --- a/src/domain/validator.mjs +++ b/src/domain/validator.mjs @@ -1,10 +1,9 @@ import { ALERT_MESSAGE } from '../constants.mjs'; +const isNaN = (value) => Number.isNaN(Number(value)); +const includeSpace = (value) => !!value.match(/ /gi); const isDuplicated = (value) => new Set(value).size !== value.length; const isInvalidLength = (value) => value.length !== 3; -const includeSpace = (value) => !!value.match(/ /gi); -const isNaN = (value) => Number.isNaN(Number(value)); - const validateUserInput = (value) => { const message = []; @@ -24,10 +23,4 @@ const validateUserInput = (value) => { return { isError: message.length !== 0, message }; }; -export { - isDuplicated, - isInvalidLength, - includeSpace, - isNaN, - validateUserInput, -}; +export default validateUserInput; From 30489fb4c7be3241f15b18c132d617e3eba6f01a Mon Sep 17 00:00:00 2001 From: MINJOO-KIM Date: Mon, 30 May 2022 16:41:19 +0900 Subject: [PATCH 28/29] =?UTF-8?q?refactor(BaseballGame):=20=EB=B3=BC,=20?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=EB=9D=BC=EC=9D=B4=ED=81=AC=20=EC=B9=B4?= =?UTF-8?q?=EC=9A=B4=ED=8C=85=20=EB=A1=9C=EC=A7=81=20util=EB=A1=9C=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - utils.mjs에 countBallandStrike 메서드 추가 --- src/domain/BaseballGame.mjs | 20 +++++++++----------- src/utils.mjs | 17 ++++++++++++++++- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/domain/BaseballGame.mjs b/src/domain/BaseballGame.mjs index 735b3cdd..ad4a5a89 100644 --- a/src/domain/BaseballGame.mjs +++ b/src/domain/BaseballGame.mjs @@ -1,5 +1,9 @@ import { DOM_ID, HINT, RESTART_TEMPLATE, STRING } from '../constants.mjs'; -import { pickComputerInputNumbers, joinHint } from '../utils.mjs'; +import { + pickComputerInputNumbers, + countBallandStrike, + joinHint, +} from '../utils.mjs'; import validateUserInput from './validator.mjs'; @@ -51,16 +55,10 @@ export default class BaseballGame { return HINT.CORRECT; } - let ballCount = 0; - let strikeCount = 0; - - for (let i = 0; i < computerInputNumbers.length; i += 1) { - if (computerInputNumbers[i] === userInputNumbers[i]) { - strikeCount += 1; - } else if (userInputNumbers.indexOf(computerInputNumbers[i]) !== -1) { - ballCount += 1; - } - } + const { ballCount, strikeCount } = countBallandStrike( + computerInputNumbers, + userInputNumbers + ); if (!strikeCount && !ballCount) { return HINT.NOTHING; diff --git a/src/utils.mjs b/src/utils.mjs index 91af1fe3..26e2494d 100644 --- a/src/utils.mjs +++ b/src/utils.mjs @@ -13,6 +13,21 @@ const pickComputerInputNumbers = () => { return Array.from(result).join(''); }; +const countBallandStrike = (computerInputNumbers, userInputNumbers) => { + let ballCount = 0; + let strikeCount = 0; + + for (let i = 0; i < computerInputNumbers.length; i += 1) { + if (computerInputNumbers[i] === userInputNumbers[i]) { + strikeCount += 1; + } else if (userInputNumbers.indexOf(computerInputNumbers[i]) !== -1) { + ballCount += 1; + } + } + + return { ballCount, strikeCount }; +}; + const joinHint = (ballCount, strikeCount) => { const ballHint = ballCount ? `${ballCount}${HINT.BALL}` : `${STRING.EMPTY}`; const strikeHint = strikeCount @@ -22,4 +37,4 @@ const joinHint = (ballCount, strikeCount) => { return `${ballHint} ${strikeHint}`; }; -export { pickComputerInputNumbers, joinHint }; +export { pickComputerInputNumbers, countBallandStrike, joinHint }; From 5cfb200b35d770187637e9127576ec3a5fb6938d Mon Sep 17 00:00:00 2001 From: MINJOO-KIM Date: Mon, 30 May 2022 16:46:54 +0900 Subject: [PATCH 29/29] =?UTF-8?q?refactor(validation):=20=EC=9C=A0?= =?UTF-8?q?=ED=9A=A8=EC=84=B1=20=EA=B2=80=EC=82=AC=20=EB=94=94=EB=A0=89?= =?UTF-8?q?=ED=86=A0=EB=A6=AC=20=EC=9C=84=EC=B9=98=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - validator.mjs -> validation.mjs --- src/domain/BaseballGame.mjs | 2 +- src/{domain/validator.mjs => validation.mjs} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename src/{domain/validator.mjs => validation.mjs} (93%) diff --git a/src/domain/BaseballGame.mjs b/src/domain/BaseballGame.mjs index ad4a5a89..a4567005 100644 --- a/src/domain/BaseballGame.mjs +++ b/src/domain/BaseballGame.mjs @@ -5,7 +5,7 @@ import { joinHint, } from '../utils.mjs'; -import validateUserInput from './validator.mjs'; +import validateUserInput from '../validation.mjs'; export default class BaseballGame { constructor(inputView, resultView, submitBtn) { diff --git a/src/domain/validator.mjs b/src/validation.mjs similarity index 93% rename from src/domain/validator.mjs rename to src/validation.mjs index 12f14e5c..f711d8ac 100644 --- a/src/domain/validator.mjs +++ b/src/validation.mjs @@ -1,4 +1,4 @@ -import { ALERT_MESSAGE } from '../constants.mjs'; +import { ALERT_MESSAGE } from './constants.mjs'; const isNaN = (value) => Number.isNaN(Number(value)); const includeSpace = (value) => !!value.match(/ /gi);