From 89e70f75c6fafaf7ccfa1ac5d3842d56cada7f49 Mon Sep 17 00:00:00 2001 From: song Date: Thu, 10 Dec 2020 00:05:37 +0900 Subject: [PATCH 01/28] initial setting: Create .eslintr, .prettierrc and .gitignore --- .eslintrc.json | 24 + .gitignore | 2 + .prettierrc.json | 7 + package-lock.json | 1828 +++++++++++++++++++++++++++++++++++++++++++++ package.json | 37 + 5 files changed, 1898 insertions(+) create mode 100644 .eslintrc.json create mode 100644 .gitignore create mode 100644 .prettierrc.json create mode 100644 package-lock.json create mode 100644 package.json diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 000000000..7e8044666 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,24 @@ +{ "plugins":["prettier","html"], + + "env": { + "browser": true, + "es2021": true + + }, + "extends": [ + "airbnb-base", + "eslint:recommended", + "plugin:prettier/recommended" + ], + "parserOptions": { + "ecmaVersion": 12, + "sourceType": "module" + }, + "rules": { + "prettier/prettier": "error", + "no-var": "error", + "no-self-assign": "error", + "object-shorthand": "error" + + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..55371e5c8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +.vscode \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 000000000..62e269533 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,7 @@ +{ + "trailingComma": "es5", + "semi": true, + "useTabs":false + + +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..6fffae487 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1828 @@ +{ + "name": "javascript-subway-map-precourse", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + } + } + }, + "@eslint/eslintrc": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.2.tgz", + "integrity": "sha512-EfB5OHNYp1F4px/LI/FEnGylop7nOqkQ1LRzCM0KccA2U8tvV8w01KBv37LbO7nW4H+YhKyo2LcJhRwjjV17QQ==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "lodash": "^4.17.19", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + } + }, + "@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "dev": true + }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "dev": true + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "dev": true, + "requires": { + "type-fest": "^0.11.0" + }, + "dependencies": { + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "dev": true + } + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "call-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.0.tgz", + "integrity": "sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.0" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "requires": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "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 + }, + "slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + } + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "commander": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.0.tgz", + "integrity": "sha512-zP4jEKbe8SHzKJYQmq8Y9gYjtO/POJLgIdKgV7B9qNmABVFVc+ctqSX6iXh4mCpJfRBOabiZ2YKPg8ciDw6C+Q==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "confusing-browser-globals": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.10.tgz", + "integrity": "sha512-gNld/3lySHwuhaVluJUKLePYirM3QNCKzVxqAdhJII9/WXKVX5PURzMVJspS1jTslSqjeuG4KMVTSouit5YPHA==" + }, + "cosmiconfig": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", + "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", + "dev": true, + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "requires": { + "object-keys": "^1.0.12" + } + }, + "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" + } + }, + "dom-serializer": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.2.0.tgz", + "integrity": "sha512-n6kZFH/KlCrqs/1GHMOd5i2fd/beQHuehKdWvNNffbGHTr/almdhuVvTVFb3V7fglz+nC50fFusu3lY33h12pA==", + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "entities": "^2.0.0" + }, + "dependencies": { + "domhandler": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.0.0.tgz", + "integrity": "sha512-KPTbnGQ1JeEMQyO1iYXoagsI6so/C96HZiFyByU3T6iAzpXn8EGEvct6unm1ZGoed8ByO2oirxgwxBmqKF9haA==", + "requires": { + "domelementtype": "^2.1.0" + } + } + } + }, + "domelementtype": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.1.0.tgz", + "integrity": "sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w==" + }, + "domhandler": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-3.3.0.tgz", + "integrity": "sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA==", + "requires": { + "domelementtype": "^2.0.1" + } + }, + "domutils": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.4.4.tgz", + "integrity": "sha512-jBC0vOsECI4OMdD0GC9mGn7NXPLb+Qt6KW1YDQzeQYRUFKmNG8lh7mO5HiELfr+lLQE7loDVI4QcAxV80HS+RA==", + "requires": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0" + }, + "dependencies": { + "domhandler": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.0.0.tgz", + "integrity": "sha512-KPTbnGQ1JeEMQyO1iYXoagsI6so/C96HZiFyByU3T6iAzpXn8EGEvct6unm1ZGoed8ByO2oirxgwxBmqKF9haA==", + "requires": { + "domelementtype": "^2.1.0" + } + } + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, + "entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==" + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "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": "7.15.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.15.0.tgz", + "integrity": "sha512-Vr64xFDT8w30wFll643e7cGrIkPEU50yIiI36OdSIDoSGguIeaLzBo0vpGvzo9RECUqq7htURfwEtKqwytkqzA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@eslint/eslintrc": "^0.2.2", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.2.0", + "esutils": "^2.0.2", + "file-entry-cache": "^6.0.0", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash": "^4.17.19", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + } + }, + "eslint-config-airbnb": { + "version": "18.2.1", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-18.2.1.tgz", + "integrity": "sha512-glZNDEZ36VdlZWoxn/bUR1r/sdFKPd1mHPbqUtkctgNG4yT2DLLtJ3D+yCV+jzZCc2V1nBVkmdknOJBZ5Hc0fg==", + "requires": { + "eslint-config-airbnb-base": "^14.2.1", + "object.assign": "^4.1.2", + "object.entries": "^1.1.2" + } + }, + "eslint-config-airbnb-base": { + "version": "14.2.1", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz", + "integrity": "sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA==", + "requires": { + "confusing-browser-globals": "^1.0.10", + "object.assign": "^4.1.2", + "object.entries": "^1.1.2" + } + }, + "eslint-config-prettier": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-7.0.0.tgz", + "integrity": "sha512-8Y8lGLVPPZdaNA7JXqnvETVC7IiVRgAP6afQu9gOQRn90YY3otMNh+x7Vr2vMePQntF+5erdSUBqSzCmU/AxaQ==", + "dev": true + }, + "eslint-plugin-html": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-6.1.1.tgz", + "integrity": "sha512-JSe3ZDb7feKMnQM27XWGeoIjvP4oWQMJD9GZ6wW67J7/plVL87NK72RBwlvfc3tTZiYUchHhxAwtgEd1GdofDA==", + "requires": { + "htmlparser2": "^5.0.1" + } + }, + "eslint-plugin-prettier": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.2.0.tgz", + "integrity": "sha512-kOUSJnFjAUFKwVxuzy6sA5yyMx6+o9ino4gCdShzBNx4eyFRudWRYKCFolKjoM40PEiuU6Cn7wBLfq3WsGg7qg==", + "dev": true, + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", + "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "dev": true + }, + "espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "requires": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", + "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.0.tgz", + "integrity": "sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "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.1.0", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.0.tgz", + "integrity": "sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "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==" + }, + "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 + }, + "get-intrinsic": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.1.tgz", + "integrity": "sha512-ZnWP+AmS1VUaLgTRy47+zKtjTxz+0xMpx3I52i+aalBK1QP19ggLF3Db89KJX7kjfOfP2eoa01qc++GwPgufPg==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", + "dev": true + }, + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" + }, + "htmlparser2": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-5.0.1.tgz", + "integrity": "sha512-vKZZra6CSe9qsJzh0BjBGXo8dvzNsq/oGvsjfRdOrrryfeD9UOBEEQdeoqCRmKZchF5h2zOBMQ6YuQ0uRUmdbQ==", + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^3.3.0", + "domutils": "^2.4.2", + "entities": "^2.0.0" + } + }, + "human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "import-fresh": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.2.tgz", + "integrity": "sha512-cTPNrlvJT6twpYy+YmKUKrTSjWFs3bjYjAhCwm+z4EOCubZxAuO+hHpRN64TqjEaYSHs7tJAE0w1CKMGmsG/lw==", + "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", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-callable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==" + }, + "is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" + }, + "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": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==" + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + }, + "is-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", + "dev": true + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "requires": { + "has-symbols": "^1.0.1" + } + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "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": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "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" + } + }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "lint-staged": { + "version": "10.5.3", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-10.5.3.tgz", + "integrity": "sha512-TanwFfuqUBLufxCc3RUtFEkFraSPNR3WzWcGF39R3f2J7S9+iF9W0KTVLfSy09lYGmZS5NDCxjNvhGMSJyFCWg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "cli-truncate": "^2.1.0", + "commander": "^6.2.0", + "cosmiconfig": "^7.0.0", + "debug": "^4.2.0", + "dedent": "^0.7.0", + "enquirer": "^2.3.6", + "execa": "^4.1.0", + "listr2": "^3.2.2", + "log-symbols": "^4.0.0", + "micromatch": "^4.0.2", + "normalize-path": "^3.0.0", + "please-upgrade-node": "^3.2.0", + "string-argv": "0.3.1", + "stringify-object": "^3.3.0" + } + }, + "listr2": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.2.3.tgz", + "integrity": "sha512-vUb80S2dSUi8YxXahO8/I/s29GqnOL8ozgHVLjfWQXa03BNEeS1TpBLjh2ruaqq5ufx46BRGvfymdBSuoXET5w==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "cli-truncate": "^2.1.0", + "figures": "^3.2.0", + "indent-string": "^4.0.0", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rxjs": "^6.6.3", + "through": "^2.3.8" + } + }, + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "dev": true + }, + "log-symbols": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "dev": true, + "requires": { + "chalk": "^4.0.0" + } + }, + "log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "requires": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "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 + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + } + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "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 + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "object-inspect": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", + "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==" + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + }, + "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==", + "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.3", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.3.tgz", + "integrity": "sha512-ym7h7OZebNS96hn5IJeyUmaWhaSM4SVtAPPfNLQEI2MYWCO2egsITb9nab2+i/Pwibx+R0mtn+ltKJXRSeTMGg==", + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1", + "has": "^1.0.3" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "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" + } + }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz", + "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, + "please-upgrade-node": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", + "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", + "dev": true, + "requires": { + "semver-compare": "^1.0.0" + } + }, + "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 + }, + "prettier": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", + "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", + "dev": true + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "requires": { + "fast-diff": "^1.1.2" + } + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "dev": true + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "rxjs": { + "version": "6.6.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.3.tgz", + "integrity": "sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "string-argv": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", + "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "string.prototype.trimend": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz", + "integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==", + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz", + "integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==", + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + } + }, + "stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dev": true, + "requires": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "strip-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": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + } + }, + "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 + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "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.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + }, + "uri-js": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", + "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "v8-compile-cache": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz", + "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "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 + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "yaml": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz", + "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==", + "dev": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 000000000..5068c3853 --- /dev/null +++ b/package.json @@ -0,0 +1,37 @@ +{ + "name": "javascript-subway-map-precourse", + "version": "1.0.0", + "description": "## 🚀 기능 요구사항", + "main": ".eslintrc.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/songrammer/javascript-subway-map-precourse.git" + }, + "keywords": [], + "author": "", + "license": "ISC", + "bugs": { + "url": "https://github.com/songrammer/javascript-subway-map-precourse/issues" + }, + "homepage": "https://github.com/songrammer/javascript-subway-map-precourse#readme", + "devDependencies": { + "eslint": "7.15.0", + "eslint-config-prettier": "7.0.0", + "eslint-plugin-prettier": "3.2.0", + "lint-staged": "10.5.3", + "prettier": "2.2.1" + }, + "lint-staged": { + "*.js": [ + "eslint -- fix", + "git add" + ] + }, + "dependencies": { + "eslint-config-airbnb": "18.2.1", + "eslint-plugin-html": "6.1.1" + } +} From f18006bae2259cab1d4851b104db1fd88f53d7c7 Mon Sep 17 00:00:00 2001 From: song Date: Thu, 10 Dec 2020 20:16:07 +0900 Subject: [PATCH 02/28] docs: Update List of Functions --- README.md | 170 ++++++++++++++++++------------------------------------ 1 file changed, 56 insertions(+), 114 deletions(-) diff --git a/README.md b/README.md index e97a1d649..c47be19af 100644 --- a/README.md +++ b/README.md @@ -1,114 +1,56 @@ -# 🚇 지하철 노선도 미션 - -## 🚀 기능 요구사항 - -### 지하철 역 관련 기능 -- 지하철 역을 등록하고 삭제할 수 있다. (단, 노선에 등록된 역은 삭제할 수 없다) -- 중복된 지하철 역 이름이 등록될 수 없다. -- 지하철 역은 2글자 이상이어야 한다. -- 지하철 역의 목록을 조회할 수 있다. - -### 지하철 노선 관련 기능 -- 지하철 노선을 등록하고 삭제할 수 있다. -- 중복된 지하철 노선 이름이 등록될 수 없다. -- 노선 등록 시 상행 종점역과 하행 종점역을 입력받는다. -- 지하철 노선의 목록을 조회할 수 있다. - -### 지하철 구간 추가 기능 -- 지하철 노선에 구간을 추가하는 기능은 노선에 역을 추가하는 기능이라고도 할 수 있다. - - 역과 역사이를 구간이라 하고 이 구간들의 모음이 노선이다. -- 하나의 역은 여러개의 노선에 추가될 수 있다. -- 역과 역 사이에 새로운 역이 추가 될 수 있다. -- 노선에서 갈래길은 생길 수 없다. - - - -### 지하철 구간 삭제 기능 -- 노선에 등록된 역을 제거할 수 있다. -- 종점을 제거할 경우 다음 역이 종점이 된다. -- 노선에 포함된 역이 두개 이하일 때는 역을 제거할 수 없다. - - - -### 지하철 노선에 등록된 역 조회 기능 -- 노선의 상행 종점부터 하행 종점까지 연결된 순서대로 역 목록을 조회할 수 있다. - -
- -## 💻 프로그램 실행 결과 - -### 역관리 - - -### 노선관리 - - -### 구간관리 - - -### 노선도 출력 - - - -## ✅ 프로그래밍 요구사항 - -### 메뉴 버튼 -- 역 관리 button 태그는 `#station-manager-button` id값을 가진다. -- 노선 관리 button 태그는 `#line-manager-button` id값을 가진다. -- 구간 관리 button 태그는 `#section-manager-button` id값을 가진다. -- 지하철 노선도 출력 관리 button 태그는 `#map-print-manager-button` id값을 가진다. - -### 지하철 역 관련 기능 -- 지하철 역을 입력하는 input 태그는 `#station-name-input` id값을 가진다. -- 지하철 역을 추가하는 button 태그는 `#station-add-button` id값을 가진다. -- 지하철 역을 삭제하는 button 태그는 `.station-delete-button` class값을 가진다. - -### 지하철 노선 관련 기능 -- 지하철 노선의 이름을 입력하는 input 태그는 `#line-name-input` id값을 가진다. -- 지하철 노선의 상행 종점을 선택하는 select 태그는 `#line-start-station-selector` id값을 가진다. -- 지하철 노선의 하행 종점을 선택하는 select 태그는 `#line-end-station-selector` id값을 가진다. -- 지하철 노선을 추가하는 button 태그는 `#line-add-button` id값을 가진다. -- 지하철 노선을 삭제하는 button 태그는 `.line-delete-button` class값을 가진다. - -### 지하철 구간 추가 기능 -- 지하철 노선을 선택하는 button 태그는 `.section-line-menu-button` class값을 가진다. -- 지하철 구간을 설정할 역 select 태그는 `#section-station-selector` id값을 가진다. -- 지하철 구간의 순서를 입력하는 input 태그는 `#section-order-input` id값을 가진다. -- 지하철 구간을 등록하는 button 태그는 `#section-add-button` id값을 가진다. -- 지하철 구간을 제거하는 button 태그는 `.section-delete-button` class값을 가진다. - -### 지하철 노선도 출력 기능 -- 지하철 노선도 출력 버튼을 누르면 `
` 태그를 만들고 해당 태그 내부에 노선도를 출력한다. - -### 기존 요구사항 - -- 사용자가 잘못된 입력 값을 작성한 경우 `alert`을 이용해 메시지를 보여주고, 재입력할 수 있게 한다. -- 외부 라이브러리(jQuery, Lodash 등)를 사용하지 않고, 순수 Vanilla JS로만 구현한다. -- **자바스크립트 코드 컨벤션을 지키면서 프로그래밍** 한다 - - [https://google.github.io/styleguide/jsguide.html](https://google.github.io/styleguide/jsguide.html) - - [https://ui.toast.com/fe-guide/ko_CODING-CONVENSION/](https://ui.toast.com/fe-guide/ko_CODING-CONVENTION) -- **indent(인덴트, 들여쓰기) depth를 3이 넘지 않도록 구현한다. 2까지만 허용**한다. - - 예를 들어 while문 안에 if문이 있으면 들여쓰기는 2이다. - - 힌트: indent(인덴트, 들여쓰기) depth를 줄이는 좋은 방법은 함수(또는 메소드)를 분리하면 된다. -- **함수(또는 메소드)의 길이가 15라인을 넘어가지 않도록 구현한다.** - - 함수(또는 메소드)가 한 가지 일만 잘 하도록 구현한다. -- 변수 선언시 `var` 를 사용하지 않는다. `const` 와 `let` 을 사용한다. - - [const](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/const) - - [let](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/let) -- `import` 문을 이용해 스크립트를 모듈화하고 불러올 수 있게 만든다. - - [https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/import](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/import) -- `template literal`을 이용해 데이터와 html string을 가독성 좋게 표현한다. - - [https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Template_literals](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Template_literals) - -### 추가된 요구사항 -- [data](https://developer.mozilla.org/ko/docs/Learn/HTML/Howto/%EB%8D%B0%EC%9D%B4%ED%84%B0_%EC%86%8D%EC%84%B1_%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0)속성을 활용하여 html 태그에 역, 노선, 구간의 유일한 데이터 값들을 관리한다. -- [localStorage](https://developer.mozilla.org/ko/docs/Web/API/Window/localStorage)를 이용하여, 새로고침하더라도 가장 최근에 작업한 정보들을 불러올 수 있도록 한다. - -
- -## 📝 미션 저장소 및 진행 요구사항 - -- 미션은 [https://github.com/woowacourse/javascript-subway-map-precours](https://github.com/woowacourse/javascript-subway-map-precourse) 저장소를 fork/clone해 시작한다. -- **기능을 구현하기 전에 javascript-subway-precourse/docs/README.md 파일에 구현할 기능 목록**을 정리해 추가한다. -- **git의 commit 단위는 앞 단계에서 README.md 파일에 정리한 기능 목록 단위로 추가**한다. -- [프리코스 과제 제출](https://github.com/woowacourse/woowacourse-docs/tree/master/precourse) 문서 절차를 따라 미션을 제출한다. +# 🚇 지하철 노선도 미션_조혜송 + +### 구현기능 +1. 지하철 역 관리 기능 + - 지하철 역 등록 + - 지하철 역은 1~2 글자 이어야한다. + - 중복된 이름은 등록할 수 없다. + - 지하철 역 삭제 + - 노선에 이미 등록된 역은 삭제할 수 없다. + - 지하철 역 조회 + - 등록 된 역 목록을 출력한다. + +2. 지하털 노선 관리 기능 + - 지하철 노선 등록 + - 중복된 이름은 등록할 수 없다. + - 상행 종점과 하행 종점 역 두개를 입력해야 한다. + - 지하철 노선 삭제 + - 등록 된 노선을 삭제한다. + - 지하철 노선 조회 + - 등록 된 노선 목록을 출력한다. + +3. 지하철 구간 관리 기능 + - 지하철 구간 조회 + - 노선 이름 버튼을 클릭 하면, 관련 구간 정보를 수정 할 수 있다. + - 지하철 구간 추가 + - 어떠한 위치든 추가할 수 있다. + - 길래 길은 생길 수 없다.(구간은 일직선이다.) + - 지하철 구간 삭제 + - 종점을 제거하면, 상행 의 경우 다음 역이, 하행의 경우 그 전 역이 종점이 된다. + - 노선에 포함된 역이 두개 이하일 경우에는 제거할 수 없다. + +3. 지하철 노선 출력 기능 + - 모든 노선의 상행 종점 부터 하행 종점까지 출력한다. + + +#### 예외 상황에 대한 대응 + +- 지하철 역 등록 + - 지하철 역의 이름 길이가 1~2 글자 이외일 경우 + - 중복된 이름을 시도할 경우 + :loudspeaker: alert로 메세지 출력 및 재입력 유도 + +- 지하철 역 삭제 + - 노선에 이미 등록된 역을 삭제 하려고 할 경우 + :loudspeaker: alert로 메세지 출력 + +- 지하철 노선 등록 + - 중복된 이름을 시도할 경우 + :loudspeaker: alert로 메세지 출력 및 재입력 유도 + +- 지하철 구간 삭제 + - 2개 이하가 남았을 시에, 구간 삭제를 시도할 경우 + :loudspeaker: alert로 메세지 출력 + + + \ No newline at end of file From a83f2a4b2222ef739ee5df825a8c10e4547fe2ea Mon Sep 17 00:00:00 2001 From: song Date: Fri, 11 Dec 2020 01:35:10 +0900 Subject: [PATCH 03/28] feat: Add elements and ids in index.html --- index.html | 63 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 11 deletions(-) diff --git a/index.html b/index.html index fc99deac2..a87005f22 100644 --- a/index.html +++ b/index.html @@ -1,13 +1,54 @@ - - - 지하철 노선도 관리 - - -
-

🚇 지하철 노선도 관리

-
- - - + + + + 지하철 노선도 관리 + + + +
+

🚇 지하철 노선도 관리

+
+ + + + +
+
+
+ 역 이름 + + +

🚉지하철 역 목록

+
+
+ 노선 이름 + +
+
+ + +
+ + +
+
+ +

🚉지하철 노선 목록

+
+
+
+

구간을 수정할 노선을 선택해주세요

+
+
+

구간 등록

+ + + +
+
+
+ + + \ No newline at end of file From 5a8bca2eba86a8e11e3f4b8a97fdc5f5d26abd91 Mon Sep 17 00:00:00 2001 From: song Date: Sun, 13 Dec 2020 01:41:13 +0900 Subject: [PATCH 04/28] docs: Update Functions about clearDisplay & localStorage --- README.md | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index c47be19af..8829b437c 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,23 @@ # 🚇 지하철 노선도 미션_조혜송 ### 구현기능 -1. 지하철 역 관리 기능 + +0. 일시적으로 태그를 숨기는 기능 + - 버튼 클릭 전 관련 없는 화면을 지워준다. +1. 로컬스트로지 데이터 저장 + - 로컬 스트로지로 부터 데이터를 가져온다. + - 로컬 스트로지로 데이터를 저장한다. +2. 전체 버튼 이벤트 + - 역 관리,노선관리,구간관리,지하철 노선도 출력 이벤트를 만들어준다. +3. 지하철 역 관리 기능 - 지하철 역 등록 - 지하철 역은 1~2 글자 이어야한다. - 중복된 이름은 등록할 수 없다. - 지하철 역 삭제 - 노선에 이미 등록된 역은 삭제할 수 없다. - 지하철 역 조회 - - 등록 된 역 목록을 출력한다. - -2. 지하털 노선 관리 기능 + - 등록 된 역 목록을 출력한다. +4. 지하털 노선 관리 기능 - 지하철 노선 등록 - 중복된 이름은 등록할 수 없다. - 상행 종점과 하행 종점 역 두개를 입력해야 한다. @@ -19,7 +26,7 @@ - 지하철 노선 조회 - 등록 된 노선 목록을 출력한다. -3. 지하철 구간 관리 기능 +5. 지하철 구간 관리 기능 - 지하철 구간 조회 - 노선 이름 버튼을 클릭 하면, 관련 구간 정보를 수정 할 수 있다. - 지하철 구간 추가 @@ -29,7 +36,7 @@ - 종점을 제거하면, 상행 의 경우 다음 역이, 하행의 경우 그 전 역이 종점이 된다. - 노선에 포함된 역이 두개 이하일 경우에는 제거할 수 없다. -3. 지하철 노선 출력 기능 +6. 지하철 노선 출력 기능 - 모든 노선의 상행 종점 부터 하행 종점까지 출력한다. @@ -38,19 +45,19 @@ - 지하철 역 등록 - 지하철 역의 이름 길이가 1~2 글자 이외일 경우 - 중복된 이름을 시도할 경우 - :loudspeaker: alert로 메세지 출력 및 재입력 유도 + :loudspeaker: alert로 메세지 출력 및 재입력 유도 - 지하철 역 삭제 - 노선에 이미 등록된 역을 삭제 하려고 할 경우 - :loudspeaker: alert로 메세지 출력 + :loudspeaker: alert로 메세지 출력 - 지하철 노선 등록 - 중복된 이름을 시도할 경우 - :loudspeaker: alert로 메세지 출력 및 재입력 유도 + :loudspeaker: alert로 메세지 출력 및 재입력 유도 - 지하철 구간 삭제 - 2개 이하가 남았을 시에, 구간 삭제를 시도할 경우 - :loudspeaker: alert로 메세지 출력 + :loudspeaker: alert로 메세지 출력 \ No newline at end of file From 8a658f5a6f46cca5a45d21c56d21535d49efa0d6 Mon Sep 17 00:00:00 2001 From: song Date: Sun, 13 Dec 2020 01:58:14 +0900 Subject: [PATCH 05/28] feat: Add Function about cleanView --- src/utils/cleanView.js | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/utils/cleanView.js diff --git a/src/utils/cleanView.js b/src/utils/cleanView.js new file mode 100644 index 000000000..b29de9f2a --- /dev/null +++ b/src/utils/cleanView.js @@ -0,0 +1,8 @@ +export const cleanView = () => { + const parent = document.getElementById("app").children; + for (let i = 0; i < parent.length; i += 1) { + if (i >= 3) { + parent[i].style.display = "none"; + } + } +}; From 6cc179789429639e3fe60845ea0b2890e3132edc Mon Sep 17 00:00:00 2001 From: song Date: Sun, 13 Dec 2020 02:00:00 +0900 Subject: [PATCH 06/28] feat: Add Function about getLocalStorageData --- src/utils/getDataFromLocalStorage.js | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/utils/getDataFromLocalStorage.js diff --git a/src/utils/getDataFromLocalStorage.js b/src/utils/getDataFromLocalStorage.js new file mode 100644 index 000000000..b8ed34ea7 --- /dev/null +++ b/src/utils/getDataFromLocalStorage.js @@ -0,0 +1,8 @@ +const SUB_WAY_INFO = "SUB_WAY_INFO"; +export const getDataFromLocalStorage = (subwayInfo) => { + const dataFromStorage = localStorage.getItem(SUB_WAY_INFO); + console.log(dataFromStorage); + if (dataFromStorage !== null) { + subwayInfo = JSON.parse(dataFromStorage); + } +}; From 1710d5752f03032c0677f5e2f3f0eb4bd7887e74 Mon Sep 17 00:00:00 2001 From: song Date: Sun, 13 Dec 2020 02:10:47 +0900 Subject: [PATCH 07/28] feat: Add constructorFunction about Subway --- src/Subway.js | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/Subway.js diff --git a/src/Subway.js b/src/Subway.js new file mode 100644 index 000000000..2e22916b6 --- /dev/null +++ b/src/Subway.js @@ -0,0 +1,4 @@ +export default function Subway() { + this.station = []; + this.line = []; +} From 3bf6f6088790ab44549298f25094b956043b12c5 Mon Sep 17 00:00:00 2001 From: song Date: Sun, 13 Dec 2020 02:13:45 +0900 Subject: [PATCH 08/28] docs: Add Functions about Menu EventHandler --- src/index.js | 32 ++++++++++++++++++++++++++++++++ src/utils/eventHandler.js | 13 +++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 src/utils/eventHandler.js diff --git a/src/index.js b/src/index.js index e69de29bb..0fd3de259 100644 --- a/src/index.js +++ b/src/index.js @@ -0,0 +1,32 @@ +import Subway from "./Subway.js"; +import { cleanView } from "./utils/cleanView.js"; +import { getDataFromLocalStorage } from "./utils/getDataFromLocalStorage.js"; +import { + stationEventHandler, + lineEventHandler, + sectionEventHandler, + mapPrintHandler, +} from "./utils/eventHandler.js"; + +const stationManagerButton = document.getElementById("station-manager-button"); +const lineManagerButton = document.getElementById("line-manager-button"); +const sectionManagerButton = document.getElementById("section-manager-button"); +const mapPrintManageButton = document.getElementById("map-print-manage-button"); + +const init = () => { + cleanView(); + let subway = new Subway(); + getDataFromLocalStorage(subway); + stationManagerButton.addEventListener( + "click", + stationEventHandler.bind(subway) + ); + sectionManagerButton.addEventListener( + "click", + sectionEventHandler.bind(subway) + ); + lineManagerButton.addEventListener("click", lineEventHandler.bind(subway)); + mapPrintManageButton.addEventListener("click", mapPrintHandler.bind(subway)); +}; + +init(); diff --git a/src/utils/eventHandler.js b/src/utils/eventHandler.js new file mode 100644 index 000000000..58040949d --- /dev/null +++ b/src/utils/eventHandler.js @@ -0,0 +1,13 @@ +export function stationEventHandler(e) { + console.log("clickStation"); + console.log(this); +} +export function lineEventHandler(e) { + console.log("lineEventHandler"); +} +export function sectionEventHandler(e) { + console.log("sectionEventHandler"); +} +export function mapPrintHandler() { + console.log("mapPrintHandler"); +} From 6988f05f1bb886bf3f980bc25b1dbdf3e7fe5f17 Mon Sep 17 00:00:00 2001 From: song Date: Sun, 13 Dec 2020 17:28:48 +0900 Subject: [PATCH 09/28] refactor: Fix cleanView & eventHandler and Add constants --- src/constant.js | 4 ++++ src/utils/cleanView.js | 8 -------- src/utils/controlView.js | 20 ++++++++++++++++++++ src/utils/eventHandler.js | 20 +++++++++++++++----- src/utils/getDataFromLocalStorage.js | 3 +-- 5 files changed, 40 insertions(+), 15 deletions(-) create mode 100644 src/constant.js delete mode 100644 src/utils/cleanView.js create mode 100644 src/utils/controlView.js diff --git a/src/constant.js b/src/constant.js new file mode 100644 index 000000000..0339d8290 --- /dev/null +++ b/src/constant.js @@ -0,0 +1,4 @@ +export const STATION_DIV = 3; +export const LINE_DIV = 4; +export const SELECTION_DIV = 5; +export const SUB_WAY_INFO = "SUB_WAY_INFO"; diff --git a/src/utils/cleanView.js b/src/utils/cleanView.js deleted file mode 100644 index b29de9f2a..000000000 --- a/src/utils/cleanView.js +++ /dev/null @@ -1,8 +0,0 @@ -export const cleanView = () => { - const parent = document.getElementById("app").children; - for (let i = 0; i < parent.length; i += 1) { - if (i >= 3) { - parent[i].style.display = "none"; - } - } -}; diff --git a/src/utils/controlView.js b/src/utils/controlView.js new file mode 100644 index 000000000..cea46e979 --- /dev/null +++ b/src/utils/controlView.js @@ -0,0 +1,20 @@ +import { STATION_DIV } from "../constant.js"; +export const cleanView = () => { + const children = document.getElementById("app").children; + for (let i = STATION_DIV; i < children.length; i += 1) { + children[i].style.display = "none"; + } +}; + +export const cleanPreView = (num) => { + const children = document.getElementById("app").children; + for (let i = STATION_DIV; i < children.length; i += 1) { + if (i !== num) children[i].style.display = "none"; + } +}; + +export const controlDisplay = (child) => { + child.style.display === "none" + ? (child.style.display = "") + : (child.style.display = "none"); +}; diff --git a/src/utils/eventHandler.js b/src/utils/eventHandler.js index 58040949d..1a4a68bf2 100644 --- a/src/utils/eventHandler.js +++ b/src/utils/eventHandler.js @@ -1,13 +1,23 @@ +import { STATION_DIV, LINE_DIV, SELECTION_DIV } from "../constant.js"; +import { controlDisplay, cleanPreView, cleanView } from "./controlView.js"; +import { getDataFromLocalStorage } from "./getDataFromLocalStorage.js"; + export function stationEventHandler(e) { - console.log("clickStation"); - console.log(this); + getDataFromLocalStorage(this); + cleanPreView(STATION_DIV); + controlDisplay(document.getElementById("app").children[STATION_DIV]); } export function lineEventHandler(e) { - console.log("lineEventHandler"); + getDataFromLocalStorage(this); + cleanPreView(LINE_DIV); + controlDisplay(document.getElementById("app").children[LINE_DIV]); } export function sectionEventHandler(e) { - console.log("sectionEventHandler"); + getDataFromLocalStorage(this); + cleanPreView(SELECTION_DIV); + controlDisplay(document.getElementById("app").children[SELECTION_DIV]); } export function mapPrintHandler() { - console.log("mapPrintHandler"); + getDataFromLocalStorage(this); + cleanView(); } diff --git a/src/utils/getDataFromLocalStorage.js b/src/utils/getDataFromLocalStorage.js index b8ed34ea7..83a3c9fe2 100644 --- a/src/utils/getDataFromLocalStorage.js +++ b/src/utils/getDataFromLocalStorage.js @@ -1,7 +1,6 @@ -const SUB_WAY_INFO = "SUB_WAY_INFO"; +import { SUB_WAY_INFO } from "../constant.js"; export const getDataFromLocalStorage = (subwayInfo) => { const dataFromStorage = localStorage.getItem(SUB_WAY_INFO); - console.log(dataFromStorage); if (dataFromStorage !== null) { subwayInfo = JSON.parse(dataFromStorage); } From c1fb799ffba467a9f6965fdd4b4af26bfa3c58cc Mon Sep 17 00:00:00 2001 From: song Date: Sun, 13 Dec 2020 18:04:19 +0900 Subject: [PATCH 10/28] fix: id Error and favicon.ico Error --- index.html | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index a87005f22..308c90cf3 100644 --- a/index.html +++ b/index.html @@ -4,6 +4,7 @@ 지하철 노선도 관리 + @@ -19,7 +20,7 @@

🚇 지하철 노선도 관리

역 이름 - +

🚉지하철 역 목록

@@ -44,7 +45,7 @@

구간을 수정할 노선을 선택해주세요

구간 등록

- +
From ceb4ba12d1088a5e5c20e0c57bb2c071c2c17929 Mon Sep 17 00:00:00 2001 From: song Date: Sun, 13 Dec 2020 19:25:02 +0900 Subject: [PATCH 11/28] feat: Add stationAddHandler & isValidStation Functions --- README.md | 2 +- src/Subway.js | 8 ++++++++ src/constant.js | 5 ++++- src/utils/eventHandler.js | 13 +++++++++++++ 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8829b437c..81d8781c1 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ - 역 관리,노선관리,구간관리,지하철 노선도 출력 이벤트를 만들어준다. 3. 지하철 역 관리 기능 - 지하철 역 등록 - - 지하철 역은 1~2 글자 이어야한다. + - 지하철 역은 2 글자 이상어야 한다. - 중복된 이름은 등록할 수 없다. - 지하철 역 삭제 - 노선에 이미 등록된 역은 삭제할 수 없다. diff --git a/src/Subway.js b/src/Subway.js index 2e22916b6..2fec53f8d 100644 --- a/src/Subway.js +++ b/src/Subway.js @@ -1,4 +1,12 @@ +import { STATION_NAME_LIMIT } from "./constant.js"; export default function Subway() { this.station = []; this.line = []; } + +Subway.prototype.isValidStation = function (stationInput) { + return ( + stationInput.trim().length >= STATION_NAME_LIMIT && + this.station.every((v) => v.name !== stationInput) + ); +}; diff --git a/src/constant.js b/src/constant.js index 0339d8290..09a01d1f8 100644 --- a/src/constant.js +++ b/src/constant.js @@ -1,4 +1,7 @@ -export const STATION_DIV = 3; export const LINE_DIV = 4; +export const STATION_DIV = 3; export const SELECTION_DIV = 5; +export const STATION_NAME_LIMIT = 2; export const SUB_WAY_INFO = "SUB_WAY_INFO"; +export const ERR_MESSAGE_STATION = + " 유효하지 않은 이름입니다. [2글자 이상 , 존재하지 않는 이름으로 입력하세요]"; diff --git a/src/utils/eventHandler.js b/src/utils/eventHandler.js index 1a4a68bf2..224677cf8 100644 --- a/src/utils/eventHandler.js +++ b/src/utils/eventHandler.js @@ -1,11 +1,14 @@ import { STATION_DIV, LINE_DIV, SELECTION_DIV } from "../constant.js"; import { controlDisplay, cleanPreView, cleanView } from "./controlView.js"; import { getDataFromLocalStorage } from "./getDataFromLocalStorage.js"; +import { ERR_MESSAGE_STATION } from "../constant.js"; export function stationEventHandler(e) { getDataFromLocalStorage(this); cleanPreView(STATION_DIV); controlDisplay(document.getElementById("app").children[STATION_DIV]); + const stationAddButton = document.getElementById("station-add-button"); + stationAddButton.addEventListener("click", stationAddHandler.bind(this)); } export function lineEventHandler(e) { getDataFromLocalStorage(this); @@ -21,3 +24,13 @@ export function mapPrintHandler() { getDataFromLocalStorage(this); cleanView(); } + +export function stationAddHandler() { + const stationNameInput = document.getElementById("station-name-input"); + if (this.isValidStation(stationNameInput.value)) { + this.station.push({ id: 1, name: stationNameInput.value }); + console.log(this.station); + } else { + alert(ERR_MESSAGE_STATION); + } +} From 64b9dc08c005c01d22c27357288fc4072feb630e Mon Sep 17 00:00:00 2001 From: song Date: Mon, 14 Dec 2020 20:13:25 +0900 Subject: [PATCH 12/28] feat: Add Functions about Add & Remove & Print Station --- src/style.css | 6 ++++++ src/utils/controlView.js | 36 +++++++++++++++++++++++++++++++++++- src/utils/eventHandler.js | 36 +++++++++++++++++++++++++++--------- 3 files changed, 68 insertions(+), 10 deletions(-) create mode 100644 src/style.css diff --git a/src/style.css b/src/style.css new file mode 100644 index 000000000..e1e060c9e --- /dev/null +++ b/src/style.css @@ -0,0 +1,6 @@ +table{ + border: 1px solid #444444; +} +th, td { + border: 1px solid #444444; + } \ No newline at end of file diff --git a/src/utils/controlView.js b/src/utils/controlView.js index cea46e979..be55687c8 100644 --- a/src/utils/controlView.js +++ b/src/utils/controlView.js @@ -1,4 +1,5 @@ import { STATION_DIV } from "../constant.js"; +import { removeStationHandler } from "./eventHandler.js"; export const cleanView = () => { const children = document.getElementById("app").children; for (let i = STATION_DIV; i < children.length; i += 1) { @@ -12,9 +13,42 @@ export const cleanPreView = (num) => { if (i !== num) children[i].style.display = "none"; } }; - export const controlDisplay = (child) => { child.style.display === "none" ? (child.style.display = "") : (child.style.display = "none"); }; + +export function tableButton(buttonNodes) { + Array.prototype.forEach.call( + buttonNodes, + function (button) { + button.addEventListener("click", removeStationHandler.bind(this)); + }.bind(this) + ); +} + +export function makeTableStation(table) { + table.innerHTML += ` + 역 이름 설정 + `; + this.station.map((v) => { + let row = ` + ${v.name} + + `; + table.innerHTML += row; + }); + tableButton.call(this, document.querySelectorAll(".station-delete-button")); +} + +export function printStation() { + let table; + if (!document.querySelector("table")) { + table = document.createElement("table"); + document.getElementById("app").children[STATION_DIV].append(table); + } + table = document.querySelector("table"); + table.innerHTML = ""; + makeTableStation.call(this, table); +} diff --git a/src/utils/eventHandler.js b/src/utils/eventHandler.js index 224677cf8..c640bb62d 100644 --- a/src/utils/eventHandler.js +++ b/src/utils/eventHandler.js @@ -1,8 +1,28 @@ import { STATION_DIV, LINE_DIV, SELECTION_DIV } from "../constant.js"; -import { controlDisplay, cleanPreView, cleanView } from "./controlView.js"; +import { + controlDisplay, + cleanPreView, + cleanView, + printStation, +} from "./controlView.js"; import { getDataFromLocalStorage } from "./getDataFromLocalStorage.js"; import { ERR_MESSAGE_STATION } from "../constant.js"; +export function stationAddHandler() { + const stationNameInput = document.getElementById("station-name-input"); + if (this.isValidStation(stationNameInput.value)) { + this.station.push({ + id: Math.random().toString(36).substr(2, 16), + name: stationNameInput.value, + }); + printStation.call(this); + stationNameInput.value = ""; + } else { + alert(ERR_MESSAGE_STATION); + stationNameInput.value = ""; + } +} + export function stationEventHandler(e) { getDataFromLocalStorage(this); cleanPreView(STATION_DIV); @@ -25,12 +45,10 @@ export function mapPrintHandler() { cleanView(); } -export function stationAddHandler() { - const stationNameInput = document.getElementById("station-name-input"); - if (this.isValidStation(stationNameInput.value)) { - this.station.push({ id: 1, name: stationNameInput.value }); - console.log(this.station); - } else { - alert(ERR_MESSAGE_STATION); - } +export function removeStationHandler(e) { + let tr = e.target.parentNode.parentNode; + const clearStation = this.station.filter((v) => v.id !== tr.dataset.id); + this.station = clearStation; + console.log(clearStation); + printStation.call(this); } From 09b33bd205c920f3a82617bde813892722f60fd8 Mon Sep 17 00:00:00 2001 From: song Date: Mon, 14 Dec 2020 20:53:23 +0900 Subject: [PATCH 13/28] fix: Apply style in index.html --- index.html | 1 + src/css/style.css | 6 ++++++ 2 files changed, 7 insertions(+) create mode 100644 src/css/style.css diff --git a/index.html b/index.html index 308c90cf3..28ac7ad70 100644 --- a/index.html +++ b/index.html @@ -51,5 +51,6 @@

구간 등록

+ \ No newline at end of file diff --git a/src/css/style.css b/src/css/style.css new file mode 100644 index 000000000..e1e060c9e --- /dev/null +++ b/src/css/style.css @@ -0,0 +1,6 @@ +table{ + border: 1px solid #444444; +} +th, td { + border: 1px solid #444444; + } \ No newline at end of file From fd3c4ac88f66601cf086b1e2706ea916c02cc377 Mon Sep 17 00:00:00 2001 From: song Date: Mon, 14 Dec 2020 20:54:37 +0900 Subject: [PATCH 14/28] chore: Update .eslintr --- .eslintrc.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.eslintrc.json b/.eslintrc.json index 7e8044666..955f8a746 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -18,7 +18,8 @@ "prettier/prettier": "error", "no-var": "error", "no-self-assign": "error", - "object-shorthand": "error" + "object-shorthand": "error", + "no-console":"off", } } From 15633f4202bfa09d448b18d831cdebe7b8a92f60 Mon Sep 17 00:00:00 2001 From: song Date: Mon, 14 Dec 2020 21:00:05 +0900 Subject: [PATCH 15/28] feat: Add Function about getNewId & Confirm about Delete --- src/constant.js | 1 + src/index.js | 3 +-- src/style.css | 6 ------ src/utils/controlView.js | 6 +++--- src/utils/eventHandler.js | 24 ++++++++++++++++-------- src/utils/getNewId.js | 3 +++ 6 files changed, 24 insertions(+), 19 deletions(-) delete mode 100644 src/style.css create mode 100644 src/utils/getNewId.js diff --git a/src/constant.js b/src/constant.js index 09a01d1f8..f1a7cb199 100644 --- a/src/constant.js +++ b/src/constant.js @@ -3,5 +3,6 @@ export const STATION_DIV = 3; export const SELECTION_DIV = 5; export const STATION_NAME_LIMIT = 2; export const SUB_WAY_INFO = "SUB_WAY_INFO"; +export const DELETE_MESSAGE_STATION = " 정말로 삭제하시겠습니까 ? "; export const ERR_MESSAGE_STATION = " 유효하지 않은 이름입니다. [2글자 이상 , 존재하지 않는 이름으로 입력하세요]"; diff --git a/src/index.js b/src/index.js index 0fd3de259..839a77ed4 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,5 @@ import Subway from "./Subway.js"; -import { cleanView } from "./utils/cleanView.js"; +import { cleanView } from "./utils/controlView.js"; import { getDataFromLocalStorage } from "./utils/getDataFromLocalStorage.js"; import { stationEventHandler, @@ -16,7 +16,6 @@ const mapPrintManageButton = document.getElementById("map-print-manage-button"); const init = () => { cleanView(); let subway = new Subway(); - getDataFromLocalStorage(subway); stationManagerButton.addEventListener( "click", stationEventHandler.bind(subway) diff --git a/src/style.css b/src/style.css deleted file mode 100644 index e1e060c9e..000000000 --- a/src/style.css +++ /dev/null @@ -1,6 +0,0 @@ -table{ - border: 1px solid #444444; -} -th, td { - border: 1px solid #444444; - } \ No newline at end of file diff --git a/src/utils/controlView.js b/src/utils/controlView.js index be55687c8..465ce398a 100644 --- a/src/utils/controlView.js +++ b/src/utils/controlView.js @@ -1,14 +1,14 @@ import { STATION_DIV } from "../constant.js"; import { removeStationHandler } from "./eventHandler.js"; export const cleanView = () => { - const children = document.getElementById("app").children; + const { children } = document.getElementById("app"); for (let i = STATION_DIV; i < children.length; i += 1) { children[i].style.display = "none"; } }; export const cleanPreView = (num) => { - const children = document.getElementById("app").children; + const { children } = document.getElementById("app"); for (let i = STATION_DIV; i < children.length; i += 1) { if (i !== num) children[i].style.display = "none"; } @@ -33,7 +33,7 @@ export function makeTableStation(table) { 역 이름 설정 `; this.station.map((v) => { - let row = ` + const row = ` ${v.name} `; diff --git a/src/utils/eventHandler.js b/src/utils/eventHandler.js index c640bb62d..66d366008 100644 --- a/src/utils/eventHandler.js +++ b/src/utils/eventHandler.js @@ -1,4 +1,11 @@ -import { STATION_DIV, LINE_DIV, SELECTION_DIV } from "../constant.js"; +import { getNewId } from "./getNewId.js"; +import { + STATION_DIV, + LINE_DIV, + SELECTION_DIV, + ERR_MESSAGE_STATION, + DELETE_MESSAGE_STATION, +} from "../constant.js"; import { controlDisplay, cleanPreView, @@ -6,13 +13,12 @@ import { printStation, } from "./controlView.js"; import { getDataFromLocalStorage } from "./getDataFromLocalStorage.js"; -import { ERR_MESSAGE_STATION } from "../constant.js"; export function stationAddHandler() { const stationNameInput = document.getElementById("station-name-input"); if (this.isValidStation(stationNameInput.value)) { this.station.push({ - id: Math.random().toString(36).substr(2, 16), + id: getNewId(), name: stationNameInput.value, }); printStation.call(this); @@ -46,9 +52,11 @@ export function mapPrintHandler() { } export function removeStationHandler(e) { - let tr = e.target.parentNode.parentNode; - const clearStation = this.station.filter((v) => v.id !== tr.dataset.id); - this.station = clearStation; - console.log(clearStation); - printStation.call(this); + if (confirm(DELETE_MESSAGE_STATION)) { + const tr = e.target.parentNode.parentNode; + const clearStation = this.station.filter((v) => v.id !== tr.dataset.id); + this.station = clearStation; + console.log(clearStation); + printStation.call(this); + } } diff --git a/src/utils/getNewId.js b/src/utils/getNewId.js new file mode 100644 index 000000000..90f0cf2b0 --- /dev/null +++ b/src/utils/getNewId.js @@ -0,0 +1,3 @@ +export function getNewId() { + return Math.random().toString(36).substr(2, 16); +} From 7385a78354e758f065b004fe5d1cdc48a3373720 Mon Sep 17 00:00:00 2001 From: song Date: Tue, 15 Dec 2020 00:24:31 +0900 Subject: [PATCH 16/28] refactor: Fix stationAddEvent Error & Code Modularize --- src/index.js | 31 ++++--------- src/utils/controlView.js | 2 +- src/utils/line.js | 13 ++++++ src/utils/mapPrint.js | 13 ++++++ src/utils/section.js | 18 ++++++++ src/utils/{eventHandler.js => station.js} | 56 +++++++++-------------- 6 files changed, 75 insertions(+), 58 deletions(-) create mode 100644 src/utils/line.js create mode 100644 src/utils/mapPrint.js create mode 100644 src/utils/section.js rename src/utils/{eventHandler.js => station.js} (69%) diff --git a/src/index.js b/src/index.js index 839a77ed4..59526dc2c 100644 --- a/src/index.js +++ b/src/index.js @@ -1,31 +1,16 @@ import Subway from "./Subway.js"; import { cleanView } from "./utils/controlView.js"; -import { getDataFromLocalStorage } from "./utils/getDataFromLocalStorage.js"; -import { - stationEventHandler, - lineEventHandler, - sectionEventHandler, - mapPrintHandler, -} from "./utils/eventHandler.js"; - -const stationManagerButton = document.getElementById("station-manager-button"); -const lineManagerButton = document.getElementById("line-manager-button"); -const sectionManagerButton = document.getElementById("section-manager-button"); -const mapPrintManageButton = document.getElementById("map-print-manage-button"); - +import { stationInit } from "./utils/station.js"; +import { lineInit } from "./utils/line.js"; +import { sectionInit } from "./utils/section.js"; +import { printMapInit } from "./utils/mapPrint.js"; const init = () => { cleanView(); let subway = new Subway(); - stationManagerButton.addEventListener( - "click", - stationEventHandler.bind(subway) - ); - sectionManagerButton.addEventListener( - "click", - sectionEventHandler.bind(subway) - ); - lineManagerButton.addEventListener("click", lineEventHandler.bind(subway)); - mapPrintManageButton.addEventListener("click", mapPrintHandler.bind(subway)); + stationInit.call(subway); + lineInit.call(subway); + sectionInit.call(subway); + printMapInit.call(subway); }; init(); diff --git a/src/utils/controlView.js b/src/utils/controlView.js index 465ce398a..633480797 100644 --- a/src/utils/controlView.js +++ b/src/utils/controlView.js @@ -1,5 +1,5 @@ import { STATION_DIV } from "../constant.js"; -import { removeStationHandler } from "./eventHandler.js"; +import { removeStationHandler } from "./station.js"; export const cleanView = () => { const { children } = document.getElementById("app"); for (let i = STATION_DIV; i < children.length; i += 1) { diff --git a/src/utils/line.js b/src/utils/line.js new file mode 100644 index 000000000..e4fe97ec8 --- /dev/null +++ b/src/utils/line.js @@ -0,0 +1,13 @@ +import { getDataFromLocalStorage } from "./getDataFromLocalStorage.js"; +import { cleanPreView, controlDisplay } from "./controlView.js"; +import { LINE_DIV } from "../constant.js"; + +export function lineEventHandler(e) { + getDataFromLocalStorage(this); + cleanPreView(LINE_DIV); + controlDisplay(document.getElementById("app").children[LINE_DIV]); +} +export function lineInit() { + const lineManagerButton = document.getElementById("line-manager-button"); + lineManagerButton.addEventListener("click", lineEventHandler.bind(this)); +} diff --git a/src/utils/mapPrint.js b/src/utils/mapPrint.js new file mode 100644 index 000000000..99cda1a7a --- /dev/null +++ b/src/utils/mapPrint.js @@ -0,0 +1,13 @@ +import { getDataFromLocalStorage } from "./getDataFromLocalStorage.js"; +import { cleanPreView } from "./controlView.js"; +export function mapPrintHandler() { + getDataFromLocalStorage(this); + cleanView(); +} + +export function printMapInit() { + const mapPrintManageButton = document.getElementById( + "map-print-manage-button" + ); + mapPrintManageButton.addEventListener("click", mapPrintHandler.bind(this)); +} diff --git a/src/utils/section.js b/src/utils/section.js new file mode 100644 index 000000000..15cfccfac --- /dev/null +++ b/src/utils/section.js @@ -0,0 +1,18 @@ +import { getDataFromLocalStorage } from "./getDataFromLocalStorage.js"; +import { cleanPreView, controlDisplay } from "./controlView.js"; +import { SELECTION_DIV } from "../constant.js"; +export function sectionEventHandler(e) { + getDataFromLocalStorage(this); + cleanPreView(SELECTION_DIV); + controlDisplay(document.getElementById("app").children[SELECTION_DIV]); +} + +export function sectionInit() { + const sectionManagerButton = document.getElementById( + "section-manager-button" + ); + sectionManagerButton.addEventListener( + "click", + sectionEventHandler.bind(this) + ); +} diff --git a/src/utils/eventHandler.js b/src/utils/station.js similarity index 69% rename from src/utils/eventHandler.js rename to src/utils/station.js index 66d366008..8ea80407e 100644 --- a/src/utils/eventHandler.js +++ b/src/utils/station.js @@ -1,19 +1,21 @@ -import { getNewId } from "./getNewId.js"; import { STATION_DIV, - LINE_DIV, - SELECTION_DIV, - ERR_MESSAGE_STATION, DELETE_MESSAGE_STATION, + ERR_MESSAGE_STATION, } from "../constant.js"; -import { - controlDisplay, - cleanPreView, - cleanView, - printStation, -} from "./controlView.js"; +import { getNewId } from "./getNewId.js"; import { getDataFromLocalStorage } from "./getDataFromLocalStorage.js"; +import { printStation, cleanPreView, controlDisplay } from "./controlView.js"; +export function removeStationHandler(e) { + if (confirm(DELETE_MESSAGE_STATION)) { + const tr = e.target.parentNode.parentNode; + const clearStation = this.station.filter((v) => v.id !== tr.dataset.id); + this.station = clearStation; + console.log(clearStation); + printStation.call(this); + } +} export function stationAddHandler() { const stationNameInput = document.getElementById("station-name-input"); if (this.isValidStation(stationNameInput.value)) { @@ -33,30 +35,16 @@ export function stationEventHandler(e) { getDataFromLocalStorage(this); cleanPreView(STATION_DIV); controlDisplay(document.getElementById("app").children[STATION_DIV]); - const stationAddButton = document.getElementById("station-add-button"); - stationAddButton.addEventListener("click", stationAddHandler.bind(this)); -} -export function lineEventHandler(e) { - getDataFromLocalStorage(this); - cleanPreView(LINE_DIV); - controlDisplay(document.getElementById("app").children[LINE_DIV]); -} -export function sectionEventHandler(e) { - getDataFromLocalStorage(this); - cleanPreView(SELECTION_DIV); - controlDisplay(document.getElementById("app").children[SELECTION_DIV]); -} -export function mapPrintHandler() { - getDataFromLocalStorage(this); - cleanView(); } -export function removeStationHandler(e) { - if (confirm(DELETE_MESSAGE_STATION)) { - const tr = e.target.parentNode.parentNode; - const clearStation = this.station.filter((v) => v.id !== tr.dataset.id); - this.station = clearStation; - console.log(clearStation); - printStation.call(this); - } +export function stationInit() { + const stationManagerButton = document.getElementById( + "station-manager-button" + ); + const stationAddButton = document.getElementById("station-add-button"); + stationManagerButton.addEventListener( + "click", + stationEventHandler.bind(this) + ); + stationAddButton.addEventListener("click", stationAddHandler.bind(this)); } From 875a6bda5987c244c76837dbd482e67e56c3c892 Mon Sep 17 00:00:00 2001 From: song Date: Tue, 15 Dec 2020 01:53:02 +0900 Subject: [PATCH 17/28] docs: Update README.md --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 81d8781c1..a6c871b87 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ - 지하철 노선 등록 - 중복된 이름은 등록할 수 없다. - 상행 종점과 하행 종점 역 두개를 입력해야 한다. + - 상행 종점과 하행 종점은 달라야한다. - 지하철 노선 삭제 - 등록 된 노선을 삭제한다. - 지하철 노선 조회 @@ -43,7 +44,7 @@ #### 예외 상황에 대한 대응 - 지하철 역 등록 - - 지하철 역의 이름 길이가 1~2 글자 이외일 경우 + - 지하철 역의 이름 길이가 2 글자 미만 일 경우 - 중복된 이름을 시도할 경우 :loudspeaker: alert로 메세지 출력 및 재입력 유도 @@ -52,6 +53,8 @@ :loudspeaker: alert로 메세지 출력 - 지하철 노선 등록 + - 지하철 노선의 이름 길이가 1글자 미만 일 경우 + - 지하철 상행 종점과 하행 종점이 같을 경우 - 중복된 이름을 시도할 경우 :loudspeaker: alert로 메세지 출력 및 재입력 유도 From 8982c068d2e3c979b7a375c33167ad73ff59f2aa Mon Sep 17 00:00:00 2001 From: song Date: Tue, 15 Dec 2020 04:48:57 +0900 Subject: [PATCH 18/28] feat: Add Functions for create Line Fix isValidStation to isValidName and Add Functions about createLines & addLinetoStation & isValidSelect --- src/Subway.js | 7 +++--- src/constant.js | 5 ++++ src/utils/controlView.js | 17 +++++++++++++ src/utils/line.js | 53 ++++++++++++++++++++++++++++++++++++++-- src/utils/station.js | 3 ++- 5 files changed, 78 insertions(+), 7 deletions(-) diff --git a/src/Subway.js b/src/Subway.js index 2fec53f8d..2bf71c5f6 100644 --- a/src/Subway.js +++ b/src/Subway.js @@ -1,12 +1,11 @@ -import { STATION_NAME_LIMIT } from "./constant.js"; export default function Subway() { this.station = []; this.line = []; } -Subway.prototype.isValidStation = function (stationInput) { +Subway.prototype.isValidName = function (inputValue, name, LIMIT_VALUE) { return ( - stationInput.trim().length >= STATION_NAME_LIMIT && - this.station.every((v) => v.name !== stationInput) + inputValue.trim().length >= LIMIT_VALUE && + this[name].every((v) => v.name !== inputValue) ); }; diff --git a/src/constant.js b/src/constant.js index f1a7cb199..35c57066c 100644 --- a/src/constant.js +++ b/src/constant.js @@ -2,7 +2,12 @@ export const LINE_DIV = 4; export const STATION_DIV = 3; export const SELECTION_DIV = 5; export const STATION_NAME_LIMIT = 2; +export const LINE_NAME_LIMIT = 1; export const SUB_WAY_INFO = "SUB_WAY_INFO"; export const DELETE_MESSAGE_STATION = " 정말로 삭제하시겠습니까 ? "; export const ERR_MESSAGE_STATION = " 유효하지 않은 이름입니다. [2글자 이상 , 존재하지 않는 이름으로 입력하세요]"; +export const ERR_MESSAGE_LINE = `유효하지 않은 노선입니다. 노선 이름과 종점을 확인하세요. +※ 노선 이름 :1글자 이상, 이미 존재하지 않는 이름 +※ 종점 :상행 종점과 하행 종점은 달라야 합니다. + `; diff --git a/src/utils/controlView.js b/src/utils/controlView.js index 633480797..a7fc23fe4 100644 --- a/src/utils/controlView.js +++ b/src/utils/controlView.js @@ -1,5 +1,6 @@ import { STATION_DIV } from "../constant.js"; import { removeStationHandler } from "./station.js"; + export const cleanView = () => { const { children } = document.getElementById("app"); for (let i = STATION_DIV; i < children.length; i += 1) { @@ -52,3 +53,19 @@ export function printStation() { table.innerHTML = ""; makeTableStation.call(this, table); } + +export function clearSelect(lineSelect) { + while (lineSelect.hasChildNodes()) { + lineSelect.removeChild(lineSelect.firstChild); + } +} +export function setDataSelect(name) { + const lineSelect = document.getElementById(name); + clearSelect(lineSelect); + this.station.forEach((v) => { + let option = document.createElement("option"); + option.dataset.id = v.id; + option.innerText = v.name; + lineSelect.append(option); + }); +} diff --git a/src/utils/line.js b/src/utils/line.js index e4fe97ec8..5920a7b8d 100644 --- a/src/utils/line.js +++ b/src/utils/line.js @@ -1,13 +1,62 @@ +import { getNewId } from "./getNewId.js"; import { getDataFromLocalStorage } from "./getDataFromLocalStorage.js"; -import { cleanPreView, controlDisplay } from "./controlView.js"; -import { LINE_DIV } from "../constant.js"; +import { cleanPreView, controlDisplay, setDataSelect } from "./controlView.js"; +import { LINE_DIV, ERR_MESSAGE_LINE, LINE_NAME_LIMIT } from "../constant.js"; +export function addLinetoStation(lineId, stationId) { + let stationIndex = this.station.findIndex((v) => v.id == stationId); + if (!this.station[stationIndex].hasOwnProperty("line")) { + this.station[stationIndex].line = []; + } + this.station[stationIndex].line.push({ id: lineId }); +} + +export function createLine(lineNameInput, destination) { + const lineId = getNewId(); + this.line.push({ + id: lineId, + name: lineNameInput, + stations: [{ id: destination[0] }, { id: destination[1] }], + }); + destination.map((v) => addLinetoStation.call(this, lineId, v)); +} + +export const isValidSelect = () => { + const selectStart = document.getElementById("line-start-station-selector"); + const selectEnd = document.getElementById("line-end-station-selector"); + let lineStartId = selectStart.options[selectStart.selectedIndex]?.dataset.id; + let lineEndId = selectEnd.options[selectEnd.selectedIndex]?.dataset.id; + if (lineStartId == null || lineEndId == null || lineStartId === lineEndId) { + return false; + } else { + return [lineStartId, lineEndId]; + } +}; + +export function lineAddHandler(e) { + const lineNameInput = document.getElementById("line-name-input"); + let destination = isValidSelect(); + if ( + this.isValidName(lineNameInput.value, "line", LINE_NAME_LIMIT) && + destination + ) { + createLine.call(this, lineNameInput.value, destination); + lineNameInput.value = ""; + } else { + alert(ERR_MESSAGE_LINE); + lineNameInput.value = ""; + } +} export function lineEventHandler(e) { getDataFromLocalStorage(this); cleanPreView(LINE_DIV); controlDisplay(document.getElementById("app").children[LINE_DIV]); + setDataSelect.call(this, "line-start-station-selector"); + setDataSelect.call(this, "line-end-station-selector"); } export function lineInit() { const lineManagerButton = document.getElementById("line-manager-button"); + const lineAddButton = document.getElementById("line-add-button"); lineManagerButton.addEventListener("click", lineEventHandler.bind(this)); + lineAddButton.addEventListener("click", lineAddHandler.bind(this)); } diff --git a/src/utils/station.js b/src/utils/station.js index 8ea80407e..7da7ff83d 100644 --- a/src/utils/station.js +++ b/src/utils/station.js @@ -1,4 +1,5 @@ import { + STATION_NAME_LIMIT, STATION_DIV, DELETE_MESSAGE_STATION, ERR_MESSAGE_STATION, @@ -18,7 +19,7 @@ export function removeStationHandler(e) { } export function stationAddHandler() { const stationNameInput = document.getElementById("station-name-input"); - if (this.isValidStation(stationNameInput.value)) { + if (this.isValidName(stationNameInput.value, "station", STATION_NAME_LIMIT)) { this.station.push({ id: getNewId(), name: stationNameInput.value, From ba721dd43ed06df32053a774d81bdd2c8dd67cec Mon Sep 17 00:00:00 2001 From: song Date: Tue, 15 Dec 2020 06:20:56 +0900 Subject: [PATCH 19/28] refactor: Fix Code Modularize & data struct --- src/utils/controlView.js | 11 ++++--- .../{getDataFromLocalStorage.js => data.js} | 9 ++++++ src/utils/getNewId.js | 3 -- src/utils/line.js | 30 ++++++++++++++----- src/utils/mapPrint.js | 2 +- src/utils/section.js | 2 +- src/utils/station.js | 9 +++--- 7 files changed, 44 insertions(+), 22 deletions(-) rename src/utils/{getDataFromLocalStorage.js => data.js} (55%) delete mode 100644 src/utils/getNewId.js diff --git a/src/utils/controlView.js b/src/utils/controlView.js index a7fc23fe4..4f39b9eaf 100644 --- a/src/utils/controlView.js +++ b/src/utils/controlView.js @@ -34,7 +34,7 @@ export function makeTableStation(table) { 역 이름 설정 `; this.station.map((v) => { - const row = ` + const row = ` ${v.name} `; @@ -43,15 +43,16 @@ export function makeTableStation(table) { tableButton.call(this, document.querySelectorAll(".station-delete-button")); } -export function printStation() { +export function printTable(NAME_DIV) { let table; if (!document.querySelector("table")) { table = document.createElement("table"); - document.getElementById("app").children[STATION_DIV].append(table); + document.getElementById("app").children[NAME_DIV].append(table); } table = document.querySelector("table"); table.innerHTML = ""; - makeTableStation.call(this, table); + if (NAME_DIV === STATION_DIV) makeTableStation.call(this, table); + else if (NAME_DIV === LINE_DIV) makeTableLine.call(this, table); } export function clearSelect(lineSelect) { @@ -59,12 +60,14 @@ export function clearSelect(lineSelect) { lineSelect.removeChild(lineSelect.firstChild); } } + export function setDataSelect(name) { const lineSelect = document.getElementById(name); clearSelect(lineSelect); this.station.forEach((v) => { let option = document.createElement("option"); option.dataset.id = v.id; + option.dataset.value = v.name; option.innerText = v.name; lineSelect.append(option); }); diff --git a/src/utils/getDataFromLocalStorage.js b/src/utils/data.js similarity index 55% rename from src/utils/getDataFromLocalStorage.js rename to src/utils/data.js index 83a3c9fe2..895d51b96 100644 --- a/src/utils/getDataFromLocalStorage.js +++ b/src/utils/data.js @@ -1,7 +1,16 @@ import { SUB_WAY_INFO } from "../constant.js"; + export const getDataFromLocalStorage = (subwayInfo) => { const dataFromStorage = localStorage.getItem(SUB_WAY_INFO); if (dataFromStorage !== null) { subwayInfo = JSON.parse(dataFromStorage); } }; + +export function getDataFromSelect(parent, dataName) { + return parent.options[parent.selectedIndex]?.dataset[dataName]; +} + +export function getNewId() { + return Math.random().toString(36).substr(2, 16); +} diff --git a/src/utils/getNewId.js b/src/utils/getNewId.js deleted file mode 100644 index 90f0cf2b0..000000000 --- a/src/utils/getNewId.js +++ /dev/null @@ -1,3 +0,0 @@ -export function getNewId() { - return Math.random().toString(36).substr(2, 16); -} diff --git a/src/utils/line.js b/src/utils/line.js index 5920a7b8d..b509a4d3f 100644 --- a/src/utils/line.js +++ b/src/utils/line.js @@ -1,6 +1,14 @@ -import { getNewId } from "./getNewId.js"; -import { getDataFromLocalStorage } from "./getDataFromLocalStorage.js"; -import { cleanPreView, controlDisplay, setDataSelect } from "./controlView.js"; +import { + getNewId, + getDataFromLocalStorage, + getDataFromSelect, +} from "./data.js"; +import { + cleanPreView, + controlDisplay, + setDataSelect, + printTable, +} from "./controlView.js"; import { LINE_DIV, ERR_MESSAGE_LINE, LINE_NAME_LIMIT } from "../constant.js"; export function addLinetoStation(lineId, stationId) { @@ -16,20 +24,23 @@ export function createLine(lineNameInput, destination) { this.line.push({ id: lineId, name: lineNameInput, - stations: [{ id: destination[0] }, { id: destination[1] }], + stations: destination, }); - destination.map((v) => addLinetoStation.call(this, lineId, v)); + destination.map((v) => addLinetoStation.call(this, lineId, v.id)); } export const isValidSelect = () => { const selectStart = document.getElementById("line-start-station-selector"); const selectEnd = document.getElementById("line-end-station-selector"); - let lineStartId = selectStart.options[selectStart.selectedIndex]?.dataset.id; - let lineEndId = selectEnd.options[selectEnd.selectedIndex]?.dataset.id; + const lineStartId = getDataFromSelect(selectStart, "id"); + const lineEndId = getDataFromSelect(selectEnd, "id"); if (lineStartId == null || lineEndId == null || lineStartId === lineEndId) { return false; } else { - return [lineStartId, lineEndId]; + return [ + { id: lineStartId, station: getDataFromSelect(selectStart, "value") }, + { id: lineEndId, station: getDataFromSelect(selectEnd, "value") }, + ]; } }; @@ -41,12 +52,14 @@ export function lineAddHandler(e) { destination ) { createLine.call(this, lineNameInput.value, destination); + // printTable.call(this, LINE_DIV); lineNameInput.value = ""; } else { alert(ERR_MESSAGE_LINE); lineNameInput.value = ""; } } + export function lineEventHandler(e) { getDataFromLocalStorage(this); cleanPreView(LINE_DIV); @@ -54,6 +67,7 @@ export function lineEventHandler(e) { setDataSelect.call(this, "line-start-station-selector"); setDataSelect.call(this, "line-end-station-selector"); } + export function lineInit() { const lineManagerButton = document.getElementById("line-manager-button"); const lineAddButton = document.getElementById("line-add-button"); diff --git a/src/utils/mapPrint.js b/src/utils/mapPrint.js index 99cda1a7a..a551e5cd9 100644 --- a/src/utils/mapPrint.js +++ b/src/utils/mapPrint.js @@ -1,4 +1,4 @@ -import { getDataFromLocalStorage } from "./getDataFromLocalStorage.js"; +import { getDataFromLocalStorage } from "./data.js"; import { cleanPreView } from "./controlView.js"; export function mapPrintHandler() { getDataFromLocalStorage(this); diff --git a/src/utils/section.js b/src/utils/section.js index 15cfccfac..5c27c4099 100644 --- a/src/utils/section.js +++ b/src/utils/section.js @@ -1,4 +1,4 @@ -import { getDataFromLocalStorage } from "./getDataFromLocalStorage.js"; +import { getDataFromLocalStorage } from "./data.js"; import { cleanPreView, controlDisplay } from "./controlView.js"; import { SELECTION_DIV } from "../constant.js"; export function sectionEventHandler(e) { diff --git a/src/utils/station.js b/src/utils/station.js index 7da7ff83d..f3d30af13 100644 --- a/src/utils/station.js +++ b/src/utils/station.js @@ -4,9 +4,8 @@ import { DELETE_MESSAGE_STATION, ERR_MESSAGE_STATION, } from "../constant.js"; -import { getNewId } from "./getNewId.js"; -import { getDataFromLocalStorage } from "./getDataFromLocalStorage.js"; -import { printStation, cleanPreView, controlDisplay } from "./controlView.js"; +import { getNewId, getDataFromLocalStorage } from "./data.js"; +import { printTable, cleanPreView, controlDisplay } from "./controlView.js"; export function removeStationHandler(e) { if (confirm(DELETE_MESSAGE_STATION)) { @@ -14,7 +13,7 @@ export function removeStationHandler(e) { const clearStation = this.station.filter((v) => v.id !== tr.dataset.id); this.station = clearStation; console.log(clearStation); - printStation.call(this); + printTable.call(this, STATION_DIV); } } export function stationAddHandler() { @@ -24,7 +23,7 @@ export function stationAddHandler() { id: getNewId(), name: stationNameInput.value, }); - printStation.call(this); + printTable.call(this, STATION_DIV); stationNameInput.value = ""; } else { alert(ERR_MESSAGE_STATION); From 3f703d06c007459487a9009292b2b85e0f8cc8be Mon Sep 17 00:00:00 2001 From: song Date: Tue, 15 Dec 2020 07:25:02 +0900 Subject: [PATCH 20/28] feat: Add makeTableLine & Fix printTable Error --- src/utils/controlView.js | 34 ++++++++++++++++++++++++++-------- src/utils/line.js | 3 ++- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/utils/controlView.js b/src/utils/controlView.js index 4f39b9eaf..897bb4ff8 100644 --- a/src/utils/controlView.js +++ b/src/utils/controlView.js @@ -1,4 +1,4 @@ -import { STATION_DIV } from "../constant.js"; +import { STATION_DIV, LINE_DIV } from "../constant.js"; import { removeStationHandler } from "./station.js"; export const cleanView = () => { @@ -35,8 +35,22 @@ export function makeTableStation(table) { `; this.station.map((v) => { const row = ` - ${v.name} - + ${v.name} + `; + table.innerHTML += row; + }); + tableButton.call(this, document.querySelectorAll(".station-delete-button")); +} + +export function makeTableLine(table) { + table.innerHTML += ` + 노선 이름 상행 종점역 하행 종점역 설정 + `; + this.line.map((v) => { + const row = ` + ${v.name} ${v.stations[0].station} + ${v.stations[v.stations.length - 1].station} + `; table.innerHTML += row; }); @@ -45,14 +59,18 @@ export function makeTableStation(table) { export function printTable(NAME_DIV) { let table; - if (!document.querySelector("table")) { + const parent = document.getElementById("app").children[NAME_DIV]; + if (!parent.getElementsByTagName("table").length) { table = document.createElement("table"); - document.getElementById("app").children[NAME_DIV].append(table); + parent.append(table); } - table = document.querySelector("table"); + table = parent.getElementsByTagName("table")[0]; table.innerHTML = ""; - if (NAME_DIV === STATION_DIV) makeTableStation.call(this, table); - else if (NAME_DIV === LINE_DIV) makeTableLine.call(this, table); + if (NAME_DIV === STATION_DIV) { + makeTableStation.call(this, table); + } else if (NAME_DIV === LINE_DIV) { + makeTableLine.call(this, table); + } } export function clearSelect(lineSelect) { diff --git a/src/utils/line.js b/src/utils/line.js index b509a4d3f..37dd8467f 100644 --- a/src/utils/line.js +++ b/src/utils/line.js @@ -52,7 +52,8 @@ export function lineAddHandler(e) { destination ) { createLine.call(this, lineNameInput.value, destination); - // printTable.call(this, LINE_DIV); + console.log(this.line); + printTable.call(this, LINE_DIV); lineNameInput.value = ""; } else { alert(ERR_MESSAGE_LINE); From d3856e0807a7c90375084fb2d218ab2bcb74e2ac Mon Sep 17 00:00:00 2001 From: song Date: Tue, 15 Dec 2020 08:38:21 +0900 Subject: [PATCH 21/28] feat: Add removeLineHandler and Functions for integration Add Function getButtonFunction and getDivName for distinguishing Menu --- src/constant.js | 2 +- src/utils/controlView.js | 15 ++++++--------- src/utils/data.js | 23 ++++++++++++++++++++++- src/utils/line.js | 17 +++++++++++++++-- src/utils/section.js | 2 +- src/utils/station.js | 5 ++--- 6 files changed, 47 insertions(+), 17 deletions(-) diff --git a/src/constant.js b/src/constant.js index 35c57066c..0545791de 100644 --- a/src/constant.js +++ b/src/constant.js @@ -4,7 +4,7 @@ export const SELECTION_DIV = 5; export const STATION_NAME_LIMIT = 2; export const LINE_NAME_LIMIT = 1; export const SUB_WAY_INFO = "SUB_WAY_INFO"; -export const DELETE_MESSAGE_STATION = " 정말로 삭제하시겠습니까 ? "; +export const DELETE_MESSAGE = " 정말로 삭제하시겠습니까 ? "; export const ERR_MESSAGE_STATION = " 유효하지 않은 이름입니다. [2글자 이상 , 존재하지 않는 이름으로 입력하세요]"; export const ERR_MESSAGE_LINE = `유효하지 않은 노선입니다. 노선 이름과 종점을 확인하세요. diff --git a/src/utils/controlView.js b/src/utils/controlView.js index 897bb4ff8..8d12e18c5 100644 --- a/src/utils/controlView.js +++ b/src/utils/controlView.js @@ -1,6 +1,5 @@ import { STATION_DIV, LINE_DIV } from "../constant.js"; -import { removeStationHandler } from "./station.js"; - +import { getButtonFunction, getDivName } from "./data.js"; export const cleanView = () => { const { children } = document.getElementById("app"); for (let i = STATION_DIV; i < children.length; i += 1) { @@ -14,6 +13,7 @@ export const cleanPreView = (num) => { if (i !== num) children[i].style.display = "none"; } }; + export const controlDisplay = (child) => { child.style.display === "none" ? (child.style.display = "") @@ -21,10 +21,11 @@ export const controlDisplay = (child) => { }; export function tableButton(buttonNodes) { + let buttonFunction = getButtonFunction(buttonNodes); Array.prototype.forEach.call( buttonNodes, function (button) { - button.addEventListener("click", removeStationHandler.bind(this)); + button.addEventListener("click", buttonFunction.bind(this)); }.bind(this) ); } @@ -54,7 +55,7 @@ export function makeTableLine(table) { `; table.innerHTML += row; }); - tableButton.call(this, document.querySelectorAll(".station-delete-button")); + tableButton.call(this, document.querySelectorAll(".line-delete-button")); } export function printTable(NAME_DIV) { @@ -66,11 +67,7 @@ export function printTable(NAME_DIV) { } table = parent.getElementsByTagName("table")[0]; table.innerHTML = ""; - if (NAME_DIV === STATION_DIV) { - makeTableStation.call(this, table); - } else if (NAME_DIV === LINE_DIV) { - makeTableLine.call(this, table); - } + getDivName.call(this, NAME_DIV, table); } export function clearSelect(lineSelect) { diff --git a/src/utils/data.js b/src/utils/data.js index 895d51b96..b7e5880e5 100644 --- a/src/utils/data.js +++ b/src/utils/data.js @@ -1,4 +1,7 @@ -import { SUB_WAY_INFO } from "../constant.js"; +import { STATION_DIV, LINE_DIV, SUB_WAY_INFO } from "../constant.js"; +import { makeTableStation, makeTableLine } from "./controlView.js"; +import { removeLineHandler } from "./line.js"; +import { removeStationHandler } from "./station.js"; export const getDataFromLocalStorage = (subwayInfo) => { const dataFromStorage = localStorage.getItem(SUB_WAY_INFO); @@ -14,3 +17,21 @@ export function getDataFromSelect(parent, dataName) { export function getNewId() { return Math.random().toString(36).substr(2, 16); } + +export function getButtonFunction(buttonNodes) { + let buttonFunction; + if (buttonNodes[0]?.getAttribute("class") === "station-delete-button") { + buttonFunction = removeStationHandler; + } else if (buttonNodes[0]?.getAttribute("class") === "line-delete-button") { + buttonFunction = removeLineHandler; + } + return buttonFunction; +} + +export function getDivName(NAME_DIV, table) { + if (NAME_DIV === STATION_DIV) { + makeTableStation.call(this, table); + } else if (NAME_DIV === LINE_DIV) { + makeTableLine.call(this, table); + } +} diff --git a/src/utils/line.js b/src/utils/line.js index 37dd8467f..c66e322f7 100644 --- a/src/utils/line.js +++ b/src/utils/line.js @@ -9,7 +9,21 @@ import { setDataSelect, printTable, } from "./controlView.js"; -import { LINE_DIV, ERR_MESSAGE_LINE, LINE_NAME_LIMIT } from "../constant.js"; +import { + LINE_DIV, + ERR_MESSAGE_LINE, + LINE_NAME_LIMIT, + DELETE_MESSAGE, +} from "../constant.js"; + +export function removeLineHandler(e) { + if (confirm(DELETE_MESSAGE)) { + const tr = e.target.parentNode.parentNode; + const clearLine = this.line.filter((v) => v.id !== tr.dataset.id); + this.line = clearLine; + printTable.call(this, LINE_DIV); + } +} export function addLinetoStation(lineId, stationId) { let stationIndex = this.station.findIndex((v) => v.id == stationId); @@ -52,7 +66,6 @@ export function lineAddHandler(e) { destination ) { createLine.call(this, lineNameInput.value, destination); - console.log(this.line); printTable.call(this, LINE_DIV); lineNameInput.value = ""; } else { diff --git a/src/utils/section.js b/src/utils/section.js index 5c27c4099..15cfccfac 100644 --- a/src/utils/section.js +++ b/src/utils/section.js @@ -1,4 +1,4 @@ -import { getDataFromLocalStorage } from "./data.js"; +import { getDataFromLocalStorage } from "./getDataFromLocalStorage.js"; import { cleanPreView, controlDisplay } from "./controlView.js"; import { SELECTION_DIV } from "../constant.js"; export function sectionEventHandler(e) { diff --git a/src/utils/station.js b/src/utils/station.js index f3d30af13..51bcd1bb7 100644 --- a/src/utils/station.js +++ b/src/utils/station.js @@ -1,18 +1,17 @@ import { STATION_NAME_LIMIT, STATION_DIV, - DELETE_MESSAGE_STATION, + DELETE_MESSAGE, ERR_MESSAGE_STATION, } from "../constant.js"; import { getNewId, getDataFromLocalStorage } from "./data.js"; import { printTable, cleanPreView, controlDisplay } from "./controlView.js"; export function removeStationHandler(e) { - if (confirm(DELETE_MESSAGE_STATION)) { + if (confirm(DELETE_MESSAGE)) { const tr = e.target.parentNode.parentNode; const clearStation = this.station.filter((v) => v.id !== tr.dataset.id); this.station = clearStation; - console.log(clearStation); printTable.call(this, STATION_DIV); } } From 0c5dc2c22291f42361803b8463eccac0de0422d3 Mon Sep 17 00:00:00 2001 From: song Date: Tue, 15 Dec 2020 13:16:09 +0900 Subject: [PATCH 22/28] refactor: Delete SectionAddDivTag in html.index --- index.html | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/index.html b/index.html index 28ac7ad70..76dce0bb1 100644 --- a/index.html +++ b/index.html @@ -42,13 +42,7 @@

🚉지하철 노선 목록

구간을 수정할 노선을 선택해주세요

-
-

구간 등록

- - - -
- + From 70e9ab07fec69ed0b8f79cd6d61aedbae94d77df Mon Sep 17 00:00:00 2001 From: song Date: Tue, 15 Dec 2020 13:32:43 +0900 Subject: [PATCH 23/28] feat: Add Functions about PrintSectionTags & SectionMenu Add Function to print SectionLineButton and Functions to print SectionAddTags --- src/constant.js | 2 ++ src/utils/controlView.js | 54 +++++++++++++++++++++++++++++++++++----- src/utils/section.js | 33 +++++++++++++++++++++--- 3 files changed, 80 insertions(+), 9 deletions(-) diff --git a/src/constant.js b/src/constant.js index 0545791de..98d80d3f8 100644 --- a/src/constant.js +++ b/src/constant.js @@ -3,6 +3,8 @@ export const STATION_DIV = 3; export const SELECTION_DIV = 5; export const STATION_NAME_LIMIT = 2; export const LINE_NAME_LIMIT = 1; +export const SELECTION_ADD_DIV_CHILD_COUNT = 2; +export const STATION_DELETE_BUTTON = ""; export const SUB_WAY_INFO = "SUB_WAY_INFO"; export const DELETE_MESSAGE = " 정말로 삭제하시겠습니까 ? "; export const ERR_MESSAGE_STATION = diff --git a/src/utils/controlView.js b/src/utils/controlView.js index 8d12e18c5..66271924b 100644 --- a/src/utils/controlView.js +++ b/src/utils/controlView.js @@ -1,5 +1,6 @@ -import { STATION_DIV, LINE_DIV } from "../constant.js"; +import { STATION_DIV, SELECTION_ADD_DIV_CHILD_COUNT } from "../constant.js"; import { getButtonFunction, getDivName } from "./data.js"; +import { lineControlEventHandler, sectionAddButton } from "./section.js"; export const cleanView = () => { const { children } = document.getElementById("app"); for (let i = STATION_DIV; i < children.length; i += 1) { @@ -30,13 +31,22 @@ export function tableButton(buttonNodes) { ); } +export function sectionLineButton(buttonNodes) { + Array.prototype.forEach.call( + buttonNodes, + function (button) { + button.addEventListener("click", lineControlEventHandler.bind(this)); + }.bind(this) + ); +} + export function makeTableStation(table) { table.innerHTML += ` - 역 이름 설정 + 역 이름 설정 `; this.station.map((v) => { const row = ` - ${v.name} + ${v.name} `; table.innerHTML += row; }); @@ -45,13 +55,13 @@ export function makeTableStation(table) { export function makeTableLine(table) { table.innerHTML += ` - 노선 이름 상행 종점역 하행 종점역 설정 + 노선 이름 상행 종점역 하행 종점역 설정 `; this.line.map((v) => { const row = ` ${v.name} ${v.stations[0].station} ${v.stations[v.stations.length - 1].station} - + `; table.innerHTML += row; }); @@ -67,7 +77,39 @@ export function printTable(NAME_DIV) { } table = parent.getElementsByTagName("table")[0]; table.innerHTML = ""; - getDivName.call(this, NAME_DIV, table); + getDivName.call(this, NAME_DIV, table); //NAME_DIV에 따라 함수 호출 구분 +} + +export function printSectionLineButton(parent) { + let div; + if (!parent.getElementsByTagName("div").length) { + div = document.createElement("div"); + parent.append(div); + } + div = parent.getElementsByTagName("div")[0]; + div.innerHTML = ""; + this.line.map((v) => { + div.innerHTML += ``; + }); + sectionLineButton.call( + this, + document.querySelectorAll(".section-line-menu-button") + ); +} + +export function printSectionAddDiv(parent, buttonName) { + let div; + if (parent.children.length !== SELECTION_ADD_DIV_CHILD_COUNT) { + div = document.createElement("div"); + parent.append(div); + } + div = parent.children[1]; + div.innerHTML = `

${buttonName} 관리

구간 등록

+ + + `; + setDataSelect.call(this, "section-station-selector"); + sectionAddButton.call(this); //이벤트 등록 함수 } export function clearSelect(lineSelect) { diff --git a/src/utils/section.js b/src/utils/section.js index 15cfccfac..adae57b2e 100644 --- a/src/utils/section.js +++ b/src/utils/section.js @@ -1,10 +1,37 @@ -import { getDataFromLocalStorage } from "./getDataFromLocalStorage.js"; -import { cleanPreView, controlDisplay } from "./controlView.js"; +import { getDataFromLocalStorage } from "./data.js"; +import { + cleanPreView, + controlDisplay, + printSectionLineButton, + printSectionAddDiv, +} from "./controlView.js"; import { SELECTION_DIV } from "../constant.js"; + +export function sectionAddButtonEventHandler(e) { + console.log(this); +} + +export function sectionAddButton(e) { + const sectionAddButton = document.getElementById("section-add-button"); + sectionAddButton.addEventListener( + "click", + sectionAddButtonEventHandler.bind(this) + ); +} + +export function lineControlEventHandler(e) { + printSectionAddDiv.call( + this, + document.getElementById("app").children[SELECTION_DIV], + e.target.dataset.value + ); //구간 등록 div 출력 +} export function sectionEventHandler(e) { + const parentMenu = document.getElementById("app").children[SELECTION_DIV]; getDataFromLocalStorage(this); + controlDisplay(parentMenu); cleanPreView(SELECTION_DIV); - controlDisplay(document.getElementById("app").children[SELECTION_DIV]); + printSectionLineButton.call(this, parentMenu.children[0]); } export function sectionInit() { From f5e3442f32ab85dabe27bcb7c9d2da7871867ba2 Mon Sep 17 00:00:00 2001 From: song Date: Tue, 15 Dec 2020 19:54:25 +0900 Subject: [PATCH 24/28] feat: Add Functions for adding Station to Line & Add setDataToStorage --- src/constant.js | 7 +++++- src/utils/controlView.js | 36 +++++++++++++++++++++++++---- src/utils/data.js | 42 ++++++++++++++++++++++++++------- src/utils/line.js | 7 ++++-- src/utils/section.js | 50 +++++++++++++++++++++++++++++++++++----- src/utils/station.js | 6 ++++- 6 files changed, 125 insertions(+), 23 deletions(-) diff --git a/src/constant.js b/src/constant.js index 98d80d3f8..c70408b61 100644 --- a/src/constant.js +++ b/src/constant.js @@ -5,11 +5,16 @@ export const STATION_NAME_LIMIT = 2; export const LINE_NAME_LIMIT = 1; export const SELECTION_ADD_DIV_CHILD_COUNT = 2; export const STATION_DELETE_BUTTON = ""; -export const SUB_WAY_INFO = "SUB_WAY_INFO"; +export const SUB_WAY_LINE_INFO = "SUB_WAY_LINE_INFO"; +export const SUB_WAY_STATION_INFO = "SUB_WAY_STATION_INFO"; export const DELETE_MESSAGE = " 정말로 삭제하시겠습니까 ? "; export const ERR_MESSAGE_STATION = " 유효하지 않은 이름입니다. [2글자 이상 , 존재하지 않는 이름으로 입력하세요]"; export const ERR_MESSAGE_LINE = `유효하지 않은 노선입니다. 노선 이름과 종점을 확인하세요. ※ 노선 이름 :1글자 이상, 이미 존재하지 않는 이름 +※ 종점 :상행 종점과 하행 종점은 달라야 합니다.`; + +export const ERR_MESSAGE_SECTION = ` 구간을 등록할 수 없습니다. +※ 순서 번호 : ※ 종점 :상행 종점과 하행 종점은 달라야 합니다. `; diff --git a/src/utils/controlView.js b/src/utils/controlView.js index 66271924b..a903dfa83 100644 --- a/src/utils/controlView.js +++ b/src/utils/controlView.js @@ -1,6 +1,13 @@ -import { STATION_DIV, SELECTION_ADD_DIV_CHILD_COUNT } from "../constant.js"; +import { + STATION_DIV, + SELECTION_ADD_DIV_CHILD_COUNT, + SELECTION_DIV, +} from "../constant.js"; + import { getButtonFunction, getDivName } from "./data.js"; + import { lineControlEventHandler, sectionAddButton } from "./section.js"; + export const cleanView = () => { const { children } = document.getElementById("app"); for (let i = STATION_DIV; i < children.length; i += 1) { @@ -41,6 +48,7 @@ export function sectionLineButton(buttonNodes) { } export function makeTableStation(table) { + console.log(this); table.innerHTML += ` 역 이름 설정 `; @@ -68,7 +76,23 @@ export function makeTableLine(table) { tableButton.call(this, document.querySelectorAll(".line-delete-button")); } -export function printTable(NAME_DIV) { +export function makeTableSection(table, buttonName) { + table.innerHTML += ` + 순서 이름 설정 + `; + let lineIndex = this.line.findIndex((v) => v.name === buttonName); + + this.line[lineIndex].stations.map((v, index) => { + const row = ` + ${index} ${v.station} + + `; + table.innerHTML += row; + }); + // tableButton.call(this, document.querySelectorAll(".section-delete-button")); +} + +export function printTable(NAME_DIV, buttonName) { let table; const parent = document.getElementById("app").children[NAME_DIV]; if (!parent.getElementsByTagName("table").length) { @@ -77,7 +101,7 @@ export function printTable(NAME_DIV) { } table = parent.getElementsByTagName("table")[0]; table.innerHTML = ""; - getDivName.call(this, NAME_DIV, table); //NAME_DIV에 따라 함수 호출 구분 + getDivName.call(this, NAME_DIV, table, buttonName); //NAME_DIV에 따라 함수 호출 구분 } export function printSectionLineButton(parent) { @@ -105,11 +129,13 @@ export function printSectionAddDiv(parent, buttonName) { } div = parent.children[1]; div.innerHTML = `

${buttonName} 관리

구간 등록

- + `; setDataSelect.call(this, "section-station-selector"); - sectionAddButton.call(this); //이벤트 등록 함수 + sectionAddButton.call(this, buttonName); //이벤트 등록 함수 + console.log(buttonName); + printTable.call(this, SELECTION_DIV, buttonName); } export function clearSelect(lineSelect) { diff --git a/src/utils/data.js b/src/utils/data.js index b7e5880e5..829f7e04b 100644 --- a/src/utils/data.js +++ b/src/utils/data.js @@ -1,14 +1,38 @@ -import { STATION_DIV, LINE_DIV, SUB_WAY_INFO } from "../constant.js"; -import { makeTableStation, makeTableLine } from "./controlView.js"; +import { + STATION_DIV, + LINE_DIV, + SUB_WAY_LINE_INFO, + SUB_WAY_STATION_INFO, +} from "../constant.js"; + +import { + makeTableStation, + makeTableLine, + makeTableSection, +} from "./controlView.js"; + import { removeLineHandler } from "./line.js"; + import { removeStationHandler } from "./station.js"; -export const getDataFromLocalStorage = (subwayInfo) => { - const dataFromStorage = localStorage.getItem(SUB_WAY_INFO); - if (dataFromStorage !== null) { - subwayInfo = JSON.parse(dataFromStorage); +export function getDataFromLocalStorage(subwayInfo) { + const lineFromStorage = localStorage.getItem(SUB_WAY_LINE_INFO); + const stationFromStorage = localStorage.getItem(SUB_WAY_STATION_INFO); + if (lineFromStorage !== null) { + subwayInfo.line = JSON.parse(lineFromStorage); + } + if (stationFromStorage !== null) { + subwayInfo.station = JSON.parse(stationFromStorage); } -}; +} + +export function setDataToStorage(subwayInfo) { + localStorage.setItem(SUB_WAY_LINE_INFO, JSON.stringify(subwayInfo.line)); + localStorage.setItem( + SUB_WAY_STATION_INFO, + JSON.stringify(subwayInfo.station) + ); +} export function getDataFromSelect(parent, dataName) { return parent.options[parent.selectedIndex]?.dataset[dataName]; @@ -28,10 +52,12 @@ export function getButtonFunction(buttonNodes) { return buttonFunction; } -export function getDivName(NAME_DIV, table) { +export function getDivName(NAME_DIV, table, buttonName) { if (NAME_DIV === STATION_DIV) { makeTableStation.call(this, table); } else if (NAME_DIV === LINE_DIV) { makeTableLine.call(this, table); + } else { + makeTableSection.call(this, table, buttonName); } } diff --git a/src/utils/line.js b/src/utils/line.js index c66e322f7..587dd1661 100644 --- a/src/utils/line.js +++ b/src/utils/line.js @@ -2,6 +2,7 @@ import { getNewId, getDataFromLocalStorage, getDataFromSelect, + setDataToStorage, } from "./data.js"; import { cleanPreView, @@ -21,6 +22,7 @@ export function removeLineHandler(e) { const tr = e.target.parentNode.parentNode; const clearLine = this.line.filter((v) => v.id !== tr.dataset.id); this.line = clearLine; + setDataToStorage(this); printTable.call(this, LINE_DIV); } } @@ -60,13 +62,13 @@ export const isValidSelect = () => { export function lineAddHandler(e) { const lineNameInput = document.getElementById("line-name-input"); - let destination = isValidSelect(); if ( this.isValidName(lineNameInput.value, "line", LINE_NAME_LIMIT) && - destination + isValidSelect() ) { createLine.call(this, lineNameInput.value, destination); printTable.call(this, LINE_DIV); + setDataToStorage(this); lineNameInput.value = ""; } else { alert(ERR_MESSAGE_LINE); @@ -80,6 +82,7 @@ export function lineEventHandler(e) { controlDisplay(document.getElementById("app").children[LINE_DIV]); setDataSelect.call(this, "line-start-station-selector"); setDataSelect.call(this, "line-end-station-selector"); + printTable.call(this, LINE_DIV); } export function lineInit() { diff --git a/src/utils/section.js b/src/utils/section.js index adae57b2e..61be99d3f 100644 --- a/src/utils/section.js +++ b/src/utils/section.js @@ -1,21 +1,59 @@ -import { getDataFromLocalStorage } from "./data.js"; +import { getDataFromLocalStorage, getDataFromSelect } from "./data.js"; import { cleanPreView, controlDisplay, printSectionLineButton, printSectionAddDiv, + printTable, } from "./controlView.js"; -import { SELECTION_DIV } from "../constant.js"; +import { ERR_MESSAGE_SECTION, SELECTION_DIV } from "../constant.js"; -export function sectionAddButtonEventHandler(e) { - console.log(this); +export function isValidSelectName(parent, lineIndex) { + let selectedId = getDataFromSelect(parent, "id"); + const result = this.line[lineIndex].stations.filter( + (v) => v.id === selectedId + ); + return result.length === 0; +} + +export function isValidOrder(lineIndex, sectionOrderInput) { + if ( + sectionOrderInput > 0 && + sectionOrderInput < this.line[lineIndex].stations.length //순서번호가 인덱스 0~인덱스 길이 사이 + ) { + return true; + } +} + +export function addStationtoLine(lineIndex, sectionOrderInput) { + this.line[lineIndex].stations.splice(parseInt(sectionOrderInput), 0, { + id: getDataFromSelect(sectionSelector, "id"), + station: getDataFromSelect(sectionSelector, "value"), + }); +} + +export function sectionAddButtonEventHandler(buttonName) { + const sectionOrderInput = document.getElementById("section-order-input"); + const sectionSelector = document.getElementById("section-station-selector"); + let lineIndex = this.line.findIndex((v) => v.name === buttonName); + if ( + isValidSelectName.call(this, sectionSelector, lineIndex) && + isValidOrder.call(this, lineIndex, sectionOrderInput.value) + ) { + addStationtoLine.call(this, lineIndex, sectionOrderInput.value); + printTable.call(this, SELECTION_DIV, buttonName); + sectionOrderInput.value = ""; + } else { + alert(ERR_MESSAGE_SECTION); + sectionOrderInput.value = ""; + } } -export function sectionAddButton(e) { +export function sectionAddButton(buttonName) { const sectionAddButton = document.getElementById("section-add-button"); sectionAddButton.addEventListener( "click", - sectionAddButtonEventHandler.bind(this) + sectionAddButtonEventHandler.bind(this, buttonName) ); } diff --git a/src/utils/station.js b/src/utils/station.js index 51bcd1bb7..05f9c94ef 100644 --- a/src/utils/station.js +++ b/src/utils/station.js @@ -4,7 +4,7 @@ import { DELETE_MESSAGE, ERR_MESSAGE_STATION, } from "../constant.js"; -import { getNewId, getDataFromLocalStorage } from "./data.js"; +import { getNewId, getDataFromLocalStorage, setDataToStorage } from "./data.js"; import { printTable, cleanPreView, controlDisplay } from "./controlView.js"; export function removeStationHandler(e) { @@ -12,9 +12,11 @@ export function removeStationHandler(e) { const tr = e.target.parentNode.parentNode; const clearStation = this.station.filter((v) => v.id !== tr.dataset.id); this.station = clearStation; + setDataToStorage(this); printTable.call(this, STATION_DIV); } } + export function stationAddHandler() { const stationNameInput = document.getElementById("station-name-input"); if (this.isValidName(stationNameInput.value, "station", STATION_NAME_LIMIT)) { @@ -23,6 +25,7 @@ export function stationAddHandler() { name: stationNameInput.value, }); printTable.call(this, STATION_DIV); + setDataToStorage(this); stationNameInput.value = ""; } else { alert(ERR_MESSAGE_STATION); @@ -32,6 +35,7 @@ export function stationAddHandler() { export function stationEventHandler(e) { getDataFromLocalStorage(this); + printTable.call(this, STATION_DIV); cleanPreView(STATION_DIV); controlDisplay(document.getElementById("app").children[STATION_DIV]); } From 1636834d0a0a41591fd22b700dfe481240eac9ef Mon Sep 17 00:00:00 2001 From: song Date: Tue, 15 Dec 2020 21:48:59 +0900 Subject: [PATCH 25/28] feat: Add Functions for Delete Section --- src/constant.js | 1 + src/utils/controlView.js | 6 +++--- src/utils/data.js | 3 +++ src/utils/line.js | 2 +- src/utils/section.js | 38 ++++++++++++++++++++++++++++++++------ 5 files changed, 40 insertions(+), 10 deletions(-) diff --git a/src/constant.js b/src/constant.js index c70408b61..9972948ff 100644 --- a/src/constant.js +++ b/src/constant.js @@ -18,3 +18,4 @@ export const ERR_MESSAGE_SECTION = ` 구간을 등록할 수 없습니다. ※ 순서 번호 : ※ 종점 :상행 종점과 하행 종점은 달라야 합니다. `; +export const ERR__DELETE = ` 삭제가 불가능합니다. `; diff --git a/src/utils/controlView.js b/src/utils/controlView.js index a903dfa83..90656b905 100644 --- a/src/utils/controlView.js +++ b/src/utils/controlView.js @@ -81,15 +81,15 @@ export function makeTableSection(table, buttonName) { 순서 이름 설정 `; let lineIndex = this.line.findIndex((v) => v.name === buttonName); - + console.log(this.line[lineIndex]); this.line[lineIndex].stations.map((v, index) => { - const row = ` + const row = ` ${index} ${v.station} `; table.innerHTML += row; }); - // tableButton.call(this, document.querySelectorAll(".section-delete-button")); + tableButton.call(this, document.querySelectorAll(".section-delete-button")); } export function printTable(NAME_DIV, buttonName) { diff --git a/src/utils/data.js b/src/utils/data.js index 829f7e04b..ff00f1a91 100644 --- a/src/utils/data.js +++ b/src/utils/data.js @@ -14,6 +14,7 @@ import { import { removeLineHandler } from "./line.js"; import { removeStationHandler } from "./station.js"; +import { removeSectionHandler } from "./section.js"; export function getDataFromLocalStorage(subwayInfo) { const lineFromStorage = localStorage.getItem(SUB_WAY_LINE_INFO); @@ -48,6 +49,8 @@ export function getButtonFunction(buttonNodes) { buttonFunction = removeStationHandler; } else if (buttonNodes[0]?.getAttribute("class") === "line-delete-button") { buttonFunction = removeLineHandler; + } else { + buttonFunction = removeSectionHandler; } return buttonFunction; } diff --git a/src/utils/line.js b/src/utils/line.js index 587dd1661..9ab66abc7 100644 --- a/src/utils/line.js +++ b/src/utils/line.js @@ -66,7 +66,7 @@ export function lineAddHandler(e) { this.isValidName(lineNameInput.value, "line", LINE_NAME_LIMIT) && isValidSelect() ) { - createLine.call(this, lineNameInput.value, destination); + createLine.call(this, lineNameInput.value, isValidSelect()); printTable.call(this, LINE_DIV); setDataToStorage(this); lineNameInput.value = ""; diff --git a/src/utils/section.js b/src/utils/section.js index 61be99d3f..d26b7a3e5 100644 --- a/src/utils/section.js +++ b/src/utils/section.js @@ -1,4 +1,8 @@ -import { getDataFromLocalStorage, getDataFromSelect } from "./data.js"; +import { + getDataFromLocalStorage, + getDataFromSelect, + setDataToStorage, +} from "./data.js"; import { cleanPreView, controlDisplay, @@ -6,10 +10,32 @@ import { printSectionAddDiv, printTable, } from "./controlView.js"; -import { ERR_MESSAGE_SECTION, SELECTION_DIV } from "../constant.js"; +import { + ERR_MESSAGE_SECTION, + SELECTION_DIV, + DELETE_MESSAGE, + ERR__DELETE, +} from "../constant.js"; + +export function removeSectionHandler(e) { + if (confirm(DELETE_MESSAGE)) { + const tr = e.target.parentNode.parentNode; + const sectionId = tr.dataset.sectionid; + let index = this.line.findIndex((v) => v.id === sectionId); + if (this.line[index].stations.length >= 3) { + const clearSection = this.line[index].stations.filter( + (v) => v.id !== tr.dataset.id + ); + this.line[index].stations = clearSection; + setDataToStorage(this); + printTable.call(this, SELECTION_DIV, this.line[index].name); + } + } +} -export function isValidSelectName(parent, lineIndex) { - let selectedId = getDataFromSelect(parent, "id"); +export function isValidSelectName(lineIndex) { + const sectionSelector = document.getElementById("section-station-selector"); + let selectedId = getDataFromSelect(sectionSelector, "id"); const result = this.line[lineIndex].stations.filter( (v) => v.id === selectedId ); @@ -26,6 +52,7 @@ export function isValidOrder(lineIndex, sectionOrderInput) { } export function addStationtoLine(lineIndex, sectionOrderInput) { + const sectionSelector = document.getElementById("section-station-selector"); this.line[lineIndex].stations.splice(parseInt(sectionOrderInput), 0, { id: getDataFromSelect(sectionSelector, "id"), station: getDataFromSelect(sectionSelector, "value"), @@ -34,10 +61,9 @@ export function addStationtoLine(lineIndex, sectionOrderInput) { export function sectionAddButtonEventHandler(buttonName) { const sectionOrderInput = document.getElementById("section-order-input"); - const sectionSelector = document.getElementById("section-station-selector"); let lineIndex = this.line.findIndex((v) => v.name === buttonName); if ( - isValidSelectName.call(this, sectionSelector, lineIndex) && + isValidSelectName.call(this, lineIndex) && isValidOrder.call(this, lineIndex, sectionOrderInput.value) ) { addStationtoLine.call(this, lineIndex, sectionOrderInput.value); From 7a25ed83757d2babf3c14b74cb7d64d83c8e25dd Mon Sep 17 00:00:00 2001 From: song Date: Tue, 15 Dec 2020 21:58:38 +0900 Subject: [PATCH 26/28] feat: Add Functions for printMap ans Add tag in index.html --- index.html | 4 ++-- src/constant.js | 1 + src/utils/controlView.js | 22 ++++++++++++++++++++++ src/utils/mapPrint.js | 7 +++++-- src/utils/section.js | 1 + 5 files changed, 31 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index 76dce0bb1..5206016c8 100644 --- a/index.html +++ b/index.html @@ -41,9 +41,9 @@

🚉지하철 노선 목록

구간을 수정할 노선을 선택해주세요

-
- +
+
diff --git a/src/constant.js b/src/constant.js index 9972948ff..7dbdae9f2 100644 --- a/src/constant.js +++ b/src/constant.js @@ -1,4 +1,5 @@ export const LINE_DIV = 4; +export const MAP_DIV = 6; export const STATION_DIV = 3; export const SELECTION_DIV = 5; export const STATION_NAME_LIMIT = 2; diff --git a/src/utils/controlView.js b/src/utils/controlView.js index 90656b905..21c2c6069 100644 --- a/src/utils/controlView.js +++ b/src/utils/controlView.js @@ -1,4 +1,5 @@ import { + MAP_DIV, STATION_DIV, SELECTION_ADD_DIV_CHILD_COUNT, SELECTION_DIV, @@ -138,6 +139,27 @@ export function printSectionAddDiv(parent, buttonName) { printTable.call(this, SELECTION_DIV, buttonName); } +export function printLineList() { + const mapNodes = document.querySelectorAll(".map"); + console.log(mapNodes); + for (let i = 0; i < mapNodes.length; i++) { + console.log(mapNodes[i]); + this.line[i].stations.forEach((v) => { + mapNodes[i].innerHTML += `
  • ${v.station}
  • `; + }); + } +} +export function printMapList() { + const mapDiv = document.getElementById("app").children[MAP_DIV]; + mapDiv.innerHTML = ""; + this.line.forEach((v) => { + mapDiv.innerHTML += `
    +

    ${v.name}

    +
    `; + }); + printLineList.call(this); +} + export function clearSelect(lineSelect) { while (lineSelect.hasChildNodes()) { lineSelect.removeChild(lineSelect.firstChild); diff --git a/src/utils/mapPrint.js b/src/utils/mapPrint.js index a551e5cd9..d217c9440 100644 --- a/src/utils/mapPrint.js +++ b/src/utils/mapPrint.js @@ -1,8 +1,11 @@ import { getDataFromLocalStorage } from "./data.js"; -import { cleanPreView } from "./controlView.js"; +import { cleanPreView, controlDisplay, printMapList } from "./controlView.js"; +import { MAP_DIV } from "../constant.js"; export function mapPrintHandler() { getDataFromLocalStorage(this); - cleanView(); + cleanPreView(MAP_DIV); + controlDisplay(document.getElementById("app").children[MAP_DIV]); + printMapList.call(this); } export function printMapInit() { diff --git a/src/utils/section.js b/src/utils/section.js index d26b7a3e5..9832985c5 100644 --- a/src/utils/section.js +++ b/src/utils/section.js @@ -67,6 +67,7 @@ export function sectionAddButtonEventHandler(buttonName) { isValidOrder.call(this, lineIndex, sectionOrderInput.value) ) { addStationtoLine.call(this, lineIndex, sectionOrderInput.value); + setDataToStorage(this); printTable.call(this, SELECTION_DIV, buttonName); sectionOrderInput.value = ""; } else { From ffcfcf73b99ea93bccf6ff115afae29db6a59b19 Mon Sep 17 00:00:00 2001 From: song Date: Tue, 15 Dec 2020 23:23:17 +0900 Subject: [PATCH 27/28] refactor: Add Alert & Update Code --- README.md | 9 +++++- src/Subway.js | 7 +++++ src/constant.js | 3 +- src/css/style.css | 7 ++++- src/utils/controlView.js | 64 +++++++++++++++++++++------------------- src/utils/data.js | 1 - src/utils/line.js | 2 ++ src/utils/mapPrint.js | 1 + src/utils/section.js | 12 ++++++-- src/utils/station.js | 13 +++++--- 10 files changed, 78 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index a6c871b87..2adbfd908 100644 --- a/README.md +++ b/README.md @@ -31,8 +31,10 @@ - 지하철 구간 조회 - 노선 이름 버튼을 클릭 하면, 관련 구간 정보를 수정 할 수 있다. - 지하철 구간 추가 - - 어떠한 위치든 추가할 수 있다. + - 역과 역 사이에만 추가 할 수 있다. - 길래 길은 생길 수 없다.(구간은 일직선이다.) + - 구간의 역은 유일하다. + - 순서번호는 숫자 이어야 한다. - 지하철 구간 삭제 - 종점을 제거하면, 상행 의 경우 다음 역이, 하행의 경우 그 전 역이 종점이 된다. - 노선에 포함된 역이 두개 이하일 경우에는 제거할 수 없다. @@ -58,6 +60,11 @@ - 중복된 이름을 시도할 경우 :loudspeaker: alert로 메세지 출력 및 재입력 유도 +- 지하철 구간 추가 + - 순서 번호 가 0 ~ 라인 갯수 사이 값이 아닐 경우, + - 이미 존재하는 역을 추가하려고 시도할 경우, + :loudspeaker: alert로 메세지 출력 및 재입력 유도 + - 지하철 구간 삭제 - 2개 이하가 남았을 시에, 구간 삭제를 시도할 경우 :loudspeaker: alert로 메세지 출력 diff --git a/src/Subway.js b/src/Subway.js index 2bf71c5f6..57644d69c 100644 --- a/src/Subway.js +++ b/src/Subway.js @@ -9,3 +9,10 @@ Subway.prototype.isValidName = function (inputValue, name, LIMIT_VALUE) { this[name].every((v) => v.name !== inputValue) ); }; + +Subway.prototype.isValidDeleteStation = function (id) { + const stationIndex = this.station.findIndex((v) => v.id === id); + if (!this.station[stationIndex].hasOwnProperty("line")) { + return true; + } +}; diff --git a/src/constant.js b/src/constant.js index 7dbdae9f2..8310492af 100644 --- a/src/constant.js +++ b/src/constant.js @@ -5,6 +5,7 @@ export const SELECTION_DIV = 5; export const STATION_NAME_LIMIT = 2; export const LINE_NAME_LIMIT = 1; export const SELECTION_ADD_DIV_CHILD_COUNT = 2; +export const SELECTION_DELETE_COUNT_LIMIT = 3; export const STATION_DELETE_BUTTON = ""; export const SUB_WAY_LINE_INFO = "SUB_WAY_LINE_INFO"; export const SUB_WAY_STATION_INFO = "SUB_WAY_STATION_INFO"; @@ -16,7 +17,7 @@ export const ERR_MESSAGE_LINE = `유효하지 않은 노선입니다. 노선 이 ※ 종점 :상행 종점과 하행 종점은 달라야 합니다.`; export const ERR_MESSAGE_SECTION = ` 구간을 등록할 수 없습니다. -※ 순서 번호 : +※ 순서 번호 : 종점 번호 제외 ※ 종점 :상행 종점과 하행 종점은 달라야 합니다. `; export const ERR__DELETE = ` 삭제가 불가능합니다. `; diff --git a/src/css/style.css b/src/css/style.css index e1e060c9e..527638c55 100644 --- a/src/css/style.css +++ b/src/css/style.css @@ -1,6 +1,11 @@ table{ border: 1px solid #444444; + margin-left: 10px; + margin-top: 10px; } th, td { border: 1px solid #444444; - } \ No newline at end of file + } +button{ + margin-right: 5px; +} \ No newline at end of file diff --git a/src/utils/controlView.js b/src/utils/controlView.js index 21c2c6069..4cb62e72d 100644 --- a/src/utils/controlView.js +++ b/src/utils/controlView.js @@ -6,10 +6,10 @@ import { } from "../constant.js"; import { getButtonFunction, getDivName } from "./data.js"; - import { lineControlEventHandler, sectionAddButton } from "./section.js"; export const cleanView = () => { + //초기 전체 화면 지우기 const { children } = document.getElementById("app"); for (let i = STATION_DIV; i < children.length; i += 1) { children[i].style.display = "none"; @@ -17,6 +17,7 @@ export const cleanView = () => { }; export const cleanPreView = (num) => { + //메뉴 이동시 화면 지우기 const { children } = document.getElementById("app"); for (let i = STATION_DIV; i < children.length; i += 1) { if (i !== num) children[i].style.display = "none"; @@ -29,16 +30,6 @@ export const controlDisplay = (child) => { : (child.style.display = "none"); }; -export function tableButton(buttonNodes) { - let buttonFunction = getButtonFunction(buttonNodes); - Array.prototype.forEach.call( - buttonNodes, - function (button) { - button.addEventListener("click", buttonFunction.bind(this)); - }.bind(this) - ); -} - export function sectionLineButton(buttonNodes) { Array.prototype.forEach.call( buttonNodes, @@ -49,32 +40,35 @@ export function sectionLineButton(buttonNodes) { } export function makeTableStation(table) { - console.log(this); - table.innerHTML += ` + if (this.station.length) { + table.innerHTML += ` 역 이름 설정 - `; - this.station.map((v) => { - const row = ` + `; + this.station.map((v) => { + const row = ` ${v.name} `; - table.innerHTML += row; - }); - tableButton.call(this, document.querySelectorAll(".station-delete-button")); + table.innerHTML += row; + }); + tableButton.call(this, document.querySelectorAll(".station-delete-button")); + } } export function makeTableLine(table) { - table.innerHTML += ` + if (this.line.length) { + table.innerHTML += ` 노선 이름 상행 종점역 하행 종점역 설정 - `; - this.line.map((v) => { - const row = ` + `; + this.line.map((v) => { + const row = ` ${v.name} ${v.stations[0].station} ${v.stations[v.stations.length - 1].station} - `; - table.innerHTML += row; - }); - tableButton.call(this, document.querySelectorAll(".line-delete-button")); + `; + table.innerHTML += row; + }); + tableButton.call(this, document.querySelectorAll(".line-delete-button")); + } } export function makeTableSection(table, buttonName) { @@ -93,6 +87,16 @@ export function makeTableSection(table, buttonName) { tableButton.call(this, document.querySelectorAll(".section-delete-button")); } +export function tableButton(buttonNodes) { + let buttonFunction = getButtonFunction(buttonNodes); + Array.prototype.forEach.call( + buttonNodes, + function (button) { + button.addEventListener("click", buttonFunction.bind(this)); + }.bind(this) + ); +} + export function printTable(NAME_DIV, buttonName) { let table; const parent = document.getElementById("app").children[NAME_DIV]; @@ -131,8 +135,7 @@ export function printSectionAddDiv(parent, buttonName) { div = parent.children[1]; div.innerHTML = `

    ${buttonName} 관리

    구간 등록

    - - `; + `; setDataSelect.call(this, "section-station-selector"); sectionAddButton.call(this, buttonName); //이벤트 등록 함수 console.log(buttonName); @@ -141,14 +144,13 @@ export function printSectionAddDiv(parent, buttonName) { export function printLineList() { const mapNodes = document.querySelectorAll(".map"); - console.log(mapNodes); for (let i = 0; i < mapNodes.length; i++) { - console.log(mapNodes[i]); this.line[i].stations.forEach((v) => { mapNodes[i].innerHTML += `
  • ${v.station}
  • `; }); } } + export function printMapList() { const mapDiv = document.getElementById("app").children[MAP_DIV]; mapDiv.innerHTML = ""; diff --git a/src/utils/data.js b/src/utils/data.js index ff00f1a91..34e3b89be 100644 --- a/src/utils/data.js +++ b/src/utils/data.js @@ -12,7 +12,6 @@ import { } from "./controlView.js"; import { removeLineHandler } from "./line.js"; - import { removeStationHandler } from "./station.js"; import { removeSectionHandler } from "./section.js"; diff --git a/src/utils/line.js b/src/utils/line.js index 9ab66abc7..bd31f639a 100644 --- a/src/utils/line.js +++ b/src/utils/line.js @@ -28,6 +28,7 @@ export function removeLineHandler(e) { } export function addLinetoStation(lineId, stationId) { + //노선에 포함 될때,line 프로퍼티 추가 let stationIndex = this.station.findIndex((v) => v.id == stationId); if (!this.station[stationIndex].hasOwnProperty("line")) { this.station[stationIndex].line = []; @@ -51,6 +52,7 @@ export const isValidSelect = () => { const lineStartId = getDataFromSelect(selectStart, "id"); const lineEndId = getDataFromSelect(selectEnd, "id"); if (lineStartId == null || lineEndId == null || lineStartId === lineEndId) { + // return false; } else { return [ diff --git a/src/utils/mapPrint.js b/src/utils/mapPrint.js index d217c9440..d7cdd8ea7 100644 --- a/src/utils/mapPrint.js +++ b/src/utils/mapPrint.js @@ -1,6 +1,7 @@ import { getDataFromLocalStorage } from "./data.js"; import { cleanPreView, controlDisplay, printMapList } from "./controlView.js"; import { MAP_DIV } from "../constant.js"; + export function mapPrintHandler() { getDataFromLocalStorage(this); cleanPreView(MAP_DIV); diff --git a/src/utils/section.js b/src/utils/section.js index 9832985c5..9ba85c23d 100644 --- a/src/utils/section.js +++ b/src/utils/section.js @@ -15,25 +15,30 @@ import { SELECTION_DIV, DELETE_MESSAGE, ERR__DELETE, + SELECTION_DELETE_COUNT_LIMIT, } from "../constant.js"; +import { addLinetoStation } from "./line.js"; export function removeSectionHandler(e) { if (confirm(DELETE_MESSAGE)) { const tr = e.target.parentNode.parentNode; const sectionId = tr.dataset.sectionid; let index = this.line.findIndex((v) => v.id === sectionId); - if (this.line[index].stations.length >= 3) { + if (this.line[index].stations.length >= SELECTION_DELETE_COUNT_LIMIT) { const clearSection = this.line[index].stations.filter( (v) => v.id !== tr.dataset.id ); this.line[index].stations = clearSection; setDataToStorage(this); printTable.call(this, SELECTION_DIV, this.line[index].name); + } else { + alert(ERR__DELETE); } } } export function isValidSelectName(lineIndex) { + //같은 역이 인지 확인 const sectionSelector = document.getElementById("section-station-selector"); let selectedId = getDataFromSelect(sectionSelector, "id"); const result = this.line[lineIndex].stations.filter( @@ -53,10 +58,12 @@ export function isValidOrder(lineIndex, sectionOrderInput) { export function addStationtoLine(lineIndex, sectionOrderInput) { const sectionSelector = document.getElementById("section-station-selector"); + const stationId = getDataFromSelect(sectionSelector, "id"); this.line[lineIndex].stations.splice(parseInt(sectionOrderInput), 0, { - id: getDataFromSelect(sectionSelector, "id"), + id: stationId, station: getDataFromSelect(sectionSelector, "value"), }); + addLinetoStation.call(this, this.line[lineIndex].id, stationId); //역에 노선 id 추가 } export function sectionAddButtonEventHandler(buttonName) { @@ -91,6 +98,7 @@ export function lineControlEventHandler(e) { e.target.dataset.value ); //구간 등록 div 출력 } + export function sectionEventHandler(e) { const parentMenu = document.getElementById("app").children[SELECTION_DIV]; getDataFromLocalStorage(this); diff --git a/src/utils/station.js b/src/utils/station.js index 05f9c94ef..cf0b4f46e 100644 --- a/src/utils/station.js +++ b/src/utils/station.js @@ -3,6 +3,7 @@ import { STATION_DIV, DELETE_MESSAGE, ERR_MESSAGE_STATION, + ERR__DELETE, } from "../constant.js"; import { getNewId, getDataFromLocalStorage, setDataToStorage } from "./data.js"; import { printTable, cleanPreView, controlDisplay } from "./controlView.js"; @@ -10,10 +11,14 @@ import { printTable, cleanPreView, controlDisplay } from "./controlView.js"; export function removeStationHandler(e) { if (confirm(DELETE_MESSAGE)) { const tr = e.target.parentNode.parentNode; - const clearStation = this.station.filter((v) => v.id !== tr.dataset.id); - this.station = clearStation; - setDataToStorage(this); - printTable.call(this, STATION_DIV); + if (this.isValidDeleteStation(tr.dataset.id)) { + const clearStation = this.station.filter((v) => v.id !== tr.dataset.id); + this.station = clearStation; + setDataToStorage(this); + printTable.call(this, STATION_DIV); + } else { + alert(ERR__DELETE); + } } } From 2f1a93b946ba75c854dfed1d3e62c5e4a958011b Mon Sep 17 00:00:00 2001 From: song Date: Tue, 15 Dec 2020 23:43:00 +0900 Subject: [PATCH 28/28] refactor: Update Code --- src/utils/line.js | 34 +++++++++++++++++++++++++--------- src/utils/section.js | 3 +-- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/utils/line.js b/src/utils/line.js index bd31f639a..78afac1a5 100644 --- a/src/utils/line.js +++ b/src/utils/line.js @@ -17,25 +17,41 @@ import { DELETE_MESSAGE, } from "../constant.js"; +export function addLinetoStation(lineId, stationId) { + //노선에 포함 될때,line 프로퍼티 추가 + let stationIndex = this.station.findIndex((v) => v.id == stationId); + if (!this.station[stationIndex].hasOwnProperty("line")) { + this.station[stationIndex].line = []; + } + this.station[stationIndex].line.push({ id: lineId }); +} + +export function deleteLine(index, lineId) { + this.station[index].line = this.station[index].line.filter( + (v) => v.id !== lineId + ); +} + +export function deleteLinetoStation(lineId) { + //노선에 포함 될때,line 프로퍼티 추가 + this.station.map((v, index) => { + if (v?.line) { + deleteLine.call(this, index, lineId); + } + }); +} + export function removeLineHandler(e) { if (confirm(DELETE_MESSAGE)) { const tr = e.target.parentNode.parentNode; const clearLine = this.line.filter((v) => v.id !== tr.dataset.id); this.line = clearLine; + deleteLinetoStation.call(this, tr.dataset.id); setDataToStorage(this); printTable.call(this, LINE_DIV); } } -export function addLinetoStation(lineId, stationId) { - //노선에 포함 될때,line 프로퍼티 추가 - let stationIndex = this.station.findIndex((v) => v.id == stationId); - if (!this.station[stationIndex].hasOwnProperty("line")) { - this.station[stationIndex].line = []; - } - this.station[stationIndex].line.push({ id: lineId }); -} - export function createLine(lineNameInput, destination) { const lineId = getNewId(); this.line.push({ diff --git a/src/utils/section.js b/src/utils/section.js index 9ba85c23d..976c377a9 100644 --- a/src/utils/section.js +++ b/src/utils/section.js @@ -22,8 +22,7 @@ import { addLinetoStation } from "./line.js"; export function removeSectionHandler(e) { if (confirm(DELETE_MESSAGE)) { const tr = e.target.parentNode.parentNode; - const sectionId = tr.dataset.sectionid; - let index = this.line.findIndex((v) => v.id === sectionId); + let index = this.line.findIndex((v) => v.id === tr.dataset.sectionid); if (this.line[index].stations.length >= SELECTION_DELETE_COUNT_LIMIT) { const clearSection = this.line[index].stations.filter( (v) => v.id !== tr.dataset.id