diff --git a/package.json b/package.json index 6d3d2668e..dd8069490 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "highcharts": "^11.3.0", "highcharts-react-official": "^3.2.1", "html-to-image": "^1.11.11", + "husky": "^9.0.11", "react": "^18.2.0", "react-devtools-core": "^5.0.0", "react-dom": "^18.2.0", @@ -96,7 +97,6 @@ "eslint-plugin-restrict-import-depth": "file:custom-eslint-rules", "eslint-plugin-simple-import-sort": "^12.0.0", "eslint-plugin-storybook": "^0.6.15", - "husky": "^9.0.11", "path": "^0.12.7", "postcss": "^8.4.35", "prettier": "^3.2.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a3dc12d16..40dd6d65f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,5 +1,9 @@ lockfileVersion: '6.0' +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + overrides: es-module-lexer: ^1.4.1 @@ -14,7 +18,7 @@ dependencies: version: 1.7.18(react-dom@18.2.0)(react@18.2.0) '@headlessui/tailwindcss': specifier: ^0.2.0 - version: 0.2.0 + version: 0.2.0(tailwindcss@3.4.1) '@hello-pangea/dnd': specifier: ^16.5.0 version: 16.5.0(@types/react-dom@18.2.19)(@types/react@18.2.57)(react-dom@18.2.0)(react@18.2.0) @@ -42,6 +46,9 @@ dependencies: html-to-image: specifier: ^1.11.11 version: 1.11.11 + husky: + specifier: ^9.0.11 + version: 9.0.11 react: specifier: ^18.2.0 version: 18.2.0 @@ -76,7 +83,7 @@ devDependencies: version: 1.1.73 '@storybook/addon-designs': specifier: ^7.0.9 - version: 7.0.9(react-dom@18.2.0)(react@18.2.0) + version: 7.0.9(@storybook/addon-docs@7.6.17)(@storybook/addons@7.6.17)(@storybook/components@7.6.17)(@storybook/manager-api@7.6.17)(@storybook/preview-api@7.6.17)(@storybook/theming@7.6.17)(react-dom@18.2.0)(react@18.2.0) '@storybook/addon-essentials': specifier: ^7.6.17 version: 7.6.17(@types/react-dom@18.2.19)(@types/react@18.2.57)(react-dom@18.2.0)(react@18.2.0) @@ -178,7 +185,7 @@ devDependencies: version: 8.56.0 eslint-config-airbnb: specifier: ^19.0.4 - version: 19.0.4(eslint-plugin-import@2.29.1)(eslint-plugin-react-hooks@4.6.0)(eslint-plugin-react@7.33.2)(eslint@8.56.0) + version: 19.0.4(eslint-plugin-import@2.29.1)(eslint-plugin-jsx-a11y@6.8.0)(eslint-plugin-react-hooks@4.6.0)(eslint-plugin-react@7.33.2)(eslint@8.56.0) eslint-config-airbnb-base: specifier: ^15.0.0 version: 15.0.0(eslint-plugin-import@2.29.1)(eslint@8.56.0) @@ -221,9 +228,6 @@ devDependencies: eslint-plugin-storybook: specifier: ^0.6.15 version: 0.6.15(eslint@8.56.0)(typescript@5.3.3) - husky: - specifier: ^9.0.11 - version: 9.0.11 path: specifier: ^0.12.7 version: 0.12.7 @@ -235,7 +239,7 @@ devDependencies: version: 3.2.5 react-dev-utils: specifier: ^12.0.1 - version: 12.0.1(eslint@8.56.0)(typescript@5.3.3) + version: 12.0.1(eslint@8.56.0)(typescript@5.3.3)(webpack@5.90.3) react-devtools: specifier: ^5.0.0 version: 5.0.0 @@ -272,6 +276,11 @@ packages: resolution: {integrity: sha512-rE0Pygv0sEZ4vBWHlAgJLGDU7Pm8xoO6p3wsEceb7GYAjScrOHpEo8KK/eVkAcnSM+slAEtXjA2JpdjLp4fJQQ==} dev: true + /@alloc/quick-lru@5.2.0: + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} + dev: false + /@ampproject/remapping@2.2.1: resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} engines: {node: '>=6.0.0'} @@ -2294,11 +2303,13 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false - /@headlessui/tailwindcss@0.2.0: + /@headlessui/tailwindcss@0.2.0(tailwindcss@3.4.1): resolution: {integrity: sha512-fpL830Fln1SykOCboExsWr3JIVeQKieLJ3XytLe/tt1A0XzqUthOftDmjcCYLW62w7mQI7wXcoPXr3tZ9QfGxw==} engines: {node: '>=10'} peerDependencies: tailwindcss: ^3.0 + dependencies: + tailwindcss: 3.4.1 dev: false /@hello-pangea/dnd@16.5.0(@types/react-dom@18.2.19)(@types/react@18.2.57)(react-dom@18.2.0)(react@18.2.0): @@ -2376,7 +2387,6 @@ packages: strip-ansi-cjs: /strip-ansi@6.0.1 wrap-ansi: 8.1.0 wrap-ansi-cjs: /wrap-ansi@7.0.0 - dev: true /@istanbuljs/load-nyc-config@1.1.0: resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} @@ -2470,6 +2480,13 @@ packages: engines: {node: '>=6.0.0'} requiresBuild: true + /@jridgewell/source-map@0.3.5: + resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==} + dependencies: + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.22 + dev: true + /@jridgewell/sourcemap-codec@1.4.15: resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} requiresBuild: true @@ -2522,12 +2539,10 @@ packages: dependencies: '@nodelib/fs.stat': 2.0.5 run-parallel: 1.2.0 - dev: true /@nodelib/fs.stat@2.0.5: resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} engines: {node: '>= 8'} - dev: true /@nodelib/fs.walk@1.2.8: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} @@ -2535,13 +2550,11 @@ packages: dependencies: '@nodelib/fs.scandir': 2.1.5 fastq: 1.17.1 - dev: true /@pkgjs/parseargs@0.11.0: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} requiresBuild: true - dev: true optional: true /@pkgr/core@0.1.1: @@ -3269,7 +3282,7 @@ packages: - supports-color dev: true - /@storybook/addon-designs@7.0.9(react-dom@18.2.0)(react@18.2.0): + /@storybook/addon-designs@7.0.9(@storybook/addon-docs@7.6.17)(@storybook/addons@7.6.17)(@storybook/components@7.6.17)(@storybook/manager-api@7.6.17)(@storybook/preview-api@7.6.17)(@storybook/theming@7.6.17)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-xJdw1/FgkC8ovTdRIL5FyEJaXtF1XPxsb6rsl2jByG+8tXyM0PJ/yFEkBrqn35Dei2i4N7x8EHXFd8DnzriBRg==} peerDependencies: '@storybook/addon-docs': ^7.0.0 @@ -3287,6 +3300,12 @@ packages: optional: true dependencies: '@figspec/react': 1.0.3(react@18.2.0) + '@storybook/addon-docs': 7.6.17(@types/react-dom@18.2.19)(@types/react@18.2.57)(react-dom@18.2.0)(react@18.2.0) + '@storybook/addons': 7.6.17(react-dom@18.2.0)(react@18.2.0) + '@storybook/components': 7.6.17(@types/react-dom@18.2.19)(@types/react@18.2.57)(react-dom@18.2.0)(react@18.2.0) + '@storybook/manager-api': 7.6.17(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.6.17 + '@storybook/theming': 7.6.17(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: true @@ -3398,6 +3417,17 @@ packages: memoizerific: 1.11.3 dev: true + /@storybook/addons@7.6.17(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-Ok18Y698Ccyg++MoUNJNHY0cXUvo8ETFIRLJk1g9ElJ70j6kPgNnzW2pAtZkBNmswHtofZ7pT156cj96k/LgfA==} + dependencies: + '@storybook/manager-api': 7.6.17(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.6.17 + '@storybook/types': 7.6.17 + transitivePeerDependencies: + - react + - react-dom + dev: true + /@storybook/blocks@7.6.17(@types/react-dom@18.2.19)(@types/react@18.2.57)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-PsNVoe0bX1mMn4Kk3nbKZ0ItDZZ0YJnYAFJ6toAbsyBAbgzg1sce88sQinzvbn58/RT9MPKeWMPB45ZS7ggiNg==} peerDependencies: @@ -4407,6 +4437,20 @@ packages: resolution: {integrity: sha512-AjwI4MvWx3HAOaZqYsjKWyEObT9lcVV0Y0V8nXo6cXzN8ZiMxVhf6F3d/UNvXVGKrEzL/Dluc5p+y9GkzlTWig==} dev: true + /@types/eslint-scope@3.7.7: + resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} + dependencies: + '@types/eslint': 8.56.4 + '@types/estree': 1.0.5 + dev: true + + /@types/eslint@8.56.4: + resolution: {integrity: sha512-lG1GLUnL5vuRBGb3MgWUWLdGMH2Hps+pERuyQXCfWozuGKdnhf9Pbg4pkcrVUHjKrU7Rl+GCZ/299ObBXZFAxg==} + dependencies: + '@types/estree': 1.0.5 + '@types/json-schema': 7.0.15 + dev: true + /@types/estree@0.0.51: resolution: {integrity: sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==} dev: true @@ -5261,10 +5305,124 @@ packages: pretty-format: 29.7.0 dev: true + /@webassemblyjs/ast@1.11.6: + resolution: {integrity: sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==} + dependencies: + '@webassemblyjs/helper-numbers': 1.11.6 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + dev: true + + /@webassemblyjs/floating-point-hex-parser@1.11.6: + resolution: {integrity: sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==} + dev: true + + /@webassemblyjs/helper-api-error@1.11.6: + resolution: {integrity: sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==} + dev: true + + /@webassemblyjs/helper-buffer@1.11.6: + resolution: {integrity: sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==} + dev: true + + /@webassemblyjs/helper-numbers@1.11.6: + resolution: {integrity: sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==} + dependencies: + '@webassemblyjs/floating-point-hex-parser': 1.11.6 + '@webassemblyjs/helper-api-error': 1.11.6 + '@xtuc/long': 4.2.2 + dev: true + + /@webassemblyjs/helper-wasm-bytecode@1.11.6: + resolution: {integrity: sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==} + dev: true + + /@webassemblyjs/helper-wasm-section@1.11.6: + resolution: {integrity: sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==} + dependencies: + '@webassemblyjs/ast': 1.11.6 + '@webassemblyjs/helper-buffer': 1.11.6 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + '@webassemblyjs/wasm-gen': 1.11.6 + dev: true + + /@webassemblyjs/ieee754@1.11.6: + resolution: {integrity: sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==} + dependencies: + '@xtuc/ieee754': 1.2.0 + dev: true + + /@webassemblyjs/leb128@1.11.6: + resolution: {integrity: sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==} + dependencies: + '@xtuc/long': 4.2.2 + dev: true + + /@webassemblyjs/utf8@1.11.6: + resolution: {integrity: sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==} + dev: true + + /@webassemblyjs/wasm-edit@1.11.6: + resolution: {integrity: sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==} + dependencies: + '@webassemblyjs/ast': 1.11.6 + '@webassemblyjs/helper-buffer': 1.11.6 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + '@webassemblyjs/helper-wasm-section': 1.11.6 + '@webassemblyjs/wasm-gen': 1.11.6 + '@webassemblyjs/wasm-opt': 1.11.6 + '@webassemblyjs/wasm-parser': 1.11.6 + '@webassemblyjs/wast-printer': 1.11.6 + dev: true + + /@webassemblyjs/wasm-gen@1.11.6: + resolution: {integrity: sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==} + dependencies: + '@webassemblyjs/ast': 1.11.6 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + '@webassemblyjs/ieee754': 1.11.6 + '@webassemblyjs/leb128': 1.11.6 + '@webassemblyjs/utf8': 1.11.6 + dev: true + + /@webassemblyjs/wasm-opt@1.11.6: + resolution: {integrity: sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==} + dependencies: + '@webassemblyjs/ast': 1.11.6 + '@webassemblyjs/helper-buffer': 1.11.6 + '@webassemblyjs/wasm-gen': 1.11.6 + '@webassemblyjs/wasm-parser': 1.11.6 + dev: true + + /@webassemblyjs/wasm-parser@1.11.6: + resolution: {integrity: sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==} + dependencies: + '@webassemblyjs/ast': 1.11.6 + '@webassemblyjs/helper-api-error': 1.11.6 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + '@webassemblyjs/ieee754': 1.11.6 + '@webassemblyjs/leb128': 1.11.6 + '@webassemblyjs/utf8': 1.11.6 + dev: true + + /@webassemblyjs/wast-printer@1.11.6: + resolution: {integrity: sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==} + dependencies: + '@webassemblyjs/ast': 1.11.6 + '@xtuc/long': 4.2.2 + dev: true + /@webcomponents/custom-elements@1.6.0: resolution: {integrity: sha512-CqTpxOlUCPWRNUPZDxT5v2NnHXA4oox612iUGnmTUGQFhZ1Gkj8kirtl/2wcF6MqX7+PqqicZzOCBKKfIn0dww==} dev: true + /@xtuc/ieee754@1.2.0: + resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} + dev: true + + /@xtuc/long@4.2.2: + resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} + dev: true + /@yarnpkg/esbuild-plugin-pnp@3.0.0-rc.15(esbuild@0.18.20): resolution: {integrity: sha512-kYzDJO5CA9sy+on/s2aIW0411AklfCi8Ck/4QDivOqsMKpStZA2SsR+X27VTggGwpStWaLrjJcDcdDMowtG8MA==} engines: {node: '>=14.15.0'} @@ -5307,6 +5465,14 @@ packages: negotiator: 0.6.3 dev: true + /acorn-import-assertions@1.9.0(acorn@8.11.3): + resolution: {integrity: sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==} + peerDependencies: + acorn: ^8 + dependencies: + acorn: 8.11.3 + dev: true + /acorn-jsx@5.3.2(acorn@7.4.1): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -5403,12 +5569,10 @@ packages: /ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - dev: true /ansi-regex@6.0.1: resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} engines: {node: '>=12'} - dev: true /ansi-styles@3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} @@ -5421,7 +5585,6 @@ packages: engines: {node: '>=8'} dependencies: color-convert: 2.0.1 - dev: true /ansi-styles@5.2.0: resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} @@ -5431,7 +5594,10 @@ packages: /ansi-styles@6.2.1: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} - dev: true + + /any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + dev: false /anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} @@ -5449,6 +5615,10 @@ packages: engines: {node: '>=14'} dev: true + /arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + dev: false + /argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} dependencies: @@ -5595,6 +5765,10 @@ packages: resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} dev: true + /ast-types-flow@0.0.8: + resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} + dev: true + /ast-types@0.16.1: resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} engines: {node: '>=4'} @@ -5648,6 +5822,17 @@ packages: possible-typed-array-names: 1.0.0 dev: true + /axe-core@4.7.0: + resolution: {integrity: sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==} + engines: {node: '>=4'} + dev: true + + /axobject-query@3.2.1: + resolution: {integrity: sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==} + dependencies: + dequal: 2.0.3 + dev: true + /babel-core@7.0.0-bridge.0(@babel/core@7.23.9): resolution: {integrity: sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==} peerDependencies: @@ -5707,7 +5892,6 @@ packages: /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - dev: true /base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -5798,7 +5982,6 @@ packages: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} dependencies: balanced-match: 1.0.2 - dev: true /braces@3.0.2: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} @@ -5908,6 +6091,11 @@ packages: engines: {node: '>=6'} dev: true + /camelcase-css@2.0.1: + resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} + engines: {node: '>= 6'} + dev: false + /camelcase-keys@6.2.2: resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==} engines: {node: '>=8'} @@ -6063,6 +6251,11 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /chrome-trace-event@1.0.3: + resolution: {integrity: sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==} + engines: {node: '>=6.0'} + dev: true + /ci-info@1.6.0: resolution: {integrity: sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==} dev: true @@ -6157,14 +6350,12 @@ packages: engines: {node: '>=7.0.0'} dependencies: color-name: 1.1.4 - dev: true /color-name@1.1.3: resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} /color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - dev: true /colord@2.9.3: resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} @@ -6181,6 +6372,15 @@ packages: delayed-stream: 1.0.0 dev: true + /commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + dev: true + + /commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + dev: false + /commander@6.2.1: resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} engines: {node: '>= 6'} @@ -6402,7 +6602,6 @@ packages: path-key: 3.1.1 shebang-command: 2.0.0 which: 2.0.2 - dev: true /crypto-random-string@1.0.0: resolution: {integrity: sha512-GsVpkFPlycH7/fRR7Dhcmnoii54gV1nz7y4CWyeFS14N+JVBBhY+r8amRHE4BwSYal7BPTDp8isvAlCxyFt3Hg==} @@ -6481,7 +6680,6 @@ packages: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} hasBin: true - dev: true /cssnano-preset-advanced@6.0.4(postcss@8.4.35): resolution: {integrity: sha512-39k8L0dQDOI0+stDQc68UMg9tKKWJcnFSMhpnB7lvkg5X3ogvrjk4vU06RKvrUBR2XTPnYr2NaX4sc1LEvNyUA==} @@ -6570,6 +6768,10 @@ packages: /csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + /damerau-levenshtein@1.0.8: + resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} + dev: true + /dargs@7.0.0: resolution: {integrity: sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==} engines: {node: '>=8'} @@ -6818,6 +7020,10 @@ packages: - supports-color dev: true + /didyoumean@1.2.2: + resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + dev: false + /diff-sequences@29.6.3: resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -6830,6 +7036,10 @@ packages: path-type: 4.0.0 dev: true + /dlv@1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + dev: false + /doctrine@2.1.0: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} @@ -6929,7 +7139,6 @@ packages: /eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - dev: true /ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} @@ -6961,11 +7170,9 @@ packages: /emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - dev: true /emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - dev: true /encodeurl@1.0.2: resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} @@ -7278,7 +7485,7 @@ packages: eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) dev: true - /eslint-config-airbnb@19.0.4(eslint-plugin-import@2.29.1)(eslint-plugin-react-hooks@4.6.0)(eslint-plugin-react@7.33.2)(eslint@8.56.0): + /eslint-config-airbnb@19.0.4(eslint-plugin-import@2.29.1)(eslint-plugin-jsx-a11y@6.8.0)(eslint-plugin-react-hooks@4.6.0)(eslint-plugin-react@7.33.2)(eslint@8.56.0): resolution: {integrity: sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew==} engines: {node: ^10.12.0 || ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -7291,6 +7498,7 @@ packages: eslint: 8.56.0 eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.29.1)(eslint@8.56.0) eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) + eslint-plugin-jsx-a11y: 6.8.0(eslint@8.56.0) eslint-plugin-react: 7.33.2(eslint@8.56.0) eslint-plugin-react-hooks: 4.6.0(eslint@8.56.0) object.assign: 4.1.5 @@ -7326,7 +7534,7 @@ packages: debug: 4.3.4 enhanced-resolve: 5.15.0 eslint: 8.56.0 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) fast-glob: 3.3.2 get-tsconfig: 4.7.2 @@ -7369,35 +7577,6 @@ packages: - supports-color dev: true - /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0): - resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: '*' - eslint-import-resolver-node: '*' - eslint-import-resolver-typescript: '*' - eslint-import-resolver-webpack: '*' - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - eslint: - optional: true - eslint-import-resolver-node: - optional: true - eslint-import-resolver-typescript: - optional: true - eslint-import-resolver-webpack: - optional: true - dependencies: - '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.3.3) - debug: 3.2.7 - eslint: 8.56.0 - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0)(eslint-plugin-import@2.29.1)(eslint@8.56.0) - transitivePeerDependencies: - - supports-color - dev: true - /eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0): resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} engines: {node: '>=4'} @@ -7453,6 +7632,31 @@ packages: - supports-color dev: true + /eslint-plugin-jsx-a11y@6.8.0(eslint@8.56.0): + resolution: {integrity: sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==} + engines: {node: '>=4.0'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + dependencies: + '@babel/runtime': 7.23.9 + aria-query: 5.3.0 + array-includes: 3.1.7 + array.prototype.flatmap: 1.3.2 + ast-types-flow: 0.0.8 + axe-core: 4.7.0 + axobject-query: 3.2.1 + damerau-levenshtein: 1.0.8 + emoji-regex: 9.2.2 + es-iterator-helpers: 1.0.17 + eslint: 8.56.0 + hasown: 2.0.1 + jsx-ast-utils: 3.3.5 + language-tags: 1.0.9 + minimatch: 3.1.2 + object.entries: 1.1.7 + object.fromentries: 2.0.7 + dev: true + /eslint-plugin-prettier@5.1.3(eslint-config-prettier@9.1.0)(eslint@8.56.0)(prettier@3.2.5): resolution: {integrity: sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==} engines: {node: ^14.18.0 || >=16.0.0} @@ -7671,6 +7875,11 @@ packages: engines: {node: '>= 0.6'} dev: true + /events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + dev: true + /execa@0.7.0: resolution: {integrity: sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw==} engines: {node: '>=4'} @@ -7800,7 +8009,6 @@ packages: glob-parent: 5.1.2 merge2: 1.4.1 micromatch: 4.0.5 - dev: true /fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} @@ -7814,7 +8022,6 @@ packages: resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} dependencies: reusify: 1.0.4 - dev: true /fb-watchman@2.0.2: resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} @@ -7953,9 +8160,8 @@ packages: dependencies: cross-spawn: 7.0.3 signal-exit: 4.1.0 - dev: true - /fork-ts-checker-webpack-plugin@6.5.3(eslint@8.56.0)(typescript@5.3.3): + /fork-ts-checker-webpack-plugin@6.5.3(eslint@8.56.0)(typescript@5.3.3)(webpack@5.90.3): resolution: {integrity: sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==} engines: {node: '>=10', yarn: '>=1.0.0'} peerDependencies: @@ -7984,6 +8190,7 @@ packages: semver: 7.6.0 tapable: 1.1.3 typescript: 5.3.3 + webpack: 5.90.3(esbuild@0.18.20) dev: true /form-data@4.0.0: @@ -8083,7 +8290,6 @@ packages: /function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - dev: true /function.prototype.name@1.1.6: resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} @@ -8221,7 +8427,6 @@ packages: engines: {node: '>=10.13.0'} dependencies: is-glob: 4.0.3 - dev: true /glob-promise@4.2.2(glob@7.2.3): resolution: {integrity: sha512-xcUzJ8NWN5bktoTIX7eOclO1Npxd/dyVqUJxlLIDasT4C7KZyqlPIwkdJ0Ypiy3p2ZKahTjK4M9uC3sNSfNMzw==} @@ -8247,7 +8452,6 @@ packages: minimatch: 9.0.3 minipass: 7.0.4 path-scurry: 1.10.1 - dev: true /glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} @@ -8455,7 +8659,6 @@ packages: engines: {node: '>= 0.4'} dependencies: function-bind: 1.1.2 - dev: true /highcharts-react-official@3.2.1(highcharts@11.3.0)(react@18.2.0): resolution: {integrity: sha512-hyQTX7ezCxl7JqumaWiGsroGWalzh24GedQIgO3vJbkGOZ6ySRAltIYjfxhrq4HszJOySZegotEF7v+haQ75UA==} @@ -8557,7 +8760,7 @@ packages: resolution: {integrity: sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==} engines: {node: '>=18'} hasBin: true - dev: true + dev: false /iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} @@ -8727,7 +8930,6 @@ packages: resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} dependencies: hasown: 2.0.1 - dev: true /is-date-object@1.0.5: resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} @@ -8770,7 +8972,6 @@ packages: /is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} - dev: true /is-generator-function@1.0.10: resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} @@ -9011,7 +9212,6 @@ packages: /isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - dev: true /isobject@3.0.1: resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} @@ -9081,7 +9281,6 @@ packages: '@isaacs/cliui': 8.0.2 optionalDependencies: '@pkgjs/parseargs': 0.11.0 - dev: true /jake@10.8.7: resolution: {integrity: sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==} @@ -9130,6 +9329,15 @@ packages: picomatch: 2.3.1 dev: true + /jest-worker@27.5.1: + resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} + engines: {node: '>= 10.13.0'} + dependencies: + '@types/node': 20.11.20 + merge-stream: 2.0.0 + supports-color: 8.1.1 + dev: true + /jest-worker@29.7.0: resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -9143,7 +9351,6 @@ packages: /jiti@1.21.0: resolution: {integrity: sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==} hasBin: true - dev: true /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -9313,6 +9520,17 @@ packages: resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} dev: true + /language-subtag-registry@0.3.22: + resolution: {integrity: sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==} + dev: true + + /language-tags@1.0.9: + resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==} + engines: {node: '>=0.10'} + dependencies: + language-subtag-registry: 0.3.22 + dev: true + /latest-version@3.1.0: resolution: {integrity: sha512-Be1YRHWWlZaSsrz2U+VInk+tO0EwLIyV+23RhWLINJYwg/UIikxjlj3MhH37/6/EDCAusjajvMkMMUXRaMWl/w==} engines: {node: '>=4'} @@ -9342,14 +9560,17 @@ packages: type-check: 0.4.0 dev: true + /lilconfig@2.1.0: + resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} + engines: {node: '>=10'} + dev: false + /lilconfig@3.1.1: resolution: {integrity: sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==} engines: {node: '>=14'} - dev: true /lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - dev: true /lit-element@3.3.3: resolution: {integrity: sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==} @@ -9373,6 +9594,11 @@ packages: lit-html: 2.8.0 dev: true + /loader-runner@4.3.0: + resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} + engines: {node: '>=6.11.5'} + dev: true + /loader-utils@3.2.1: resolution: {integrity: sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==} engines: {node: '>= 12.13.0'} @@ -9499,7 +9725,6 @@ packages: /lru-cache@10.2.0: resolution: {integrity: sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==} engines: {node: 14 || >=16.14} - dev: true /lru-cache@4.1.5: resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} @@ -9694,7 +9919,6 @@ packages: /merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - dev: true /methods@1.1.2: resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} @@ -9707,7 +9931,6 @@ packages: dependencies: braces: 3.0.2 picomatch: 2.3.1 - dev: true /mime-db@1.52.0: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} @@ -9776,7 +9999,6 @@ packages: engines: {node: '>=16 || 14 >=14.17'} dependencies: brace-expansion: 2.0.1 - dev: true /minimist-options@4.1.0: resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} @@ -9806,7 +10028,6 @@ packages: /minipass@7.0.4: resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==} engines: {node: '>=16 || 14 >=14.17'} - dev: true /minizlib@2.1.2: resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} @@ -9858,6 +10079,14 @@ packages: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} dev: true + /mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + dev: false + /nanoid@3.3.7: resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -9987,7 +10216,11 @@ packages: /object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} - dev: true + + /object-hash@3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + dev: false /object-inspect@1.13.1: resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} @@ -10290,7 +10523,6 @@ packages: /path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} - dev: true /path-key@4.0.0: resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} @@ -10299,7 +10531,6 @@ packages: /path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - dev: true /path-scurry@1.10.1: resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==} @@ -10307,7 +10538,6 @@ packages: dependencies: lru-cache: 10.2.0 minipass: 7.0.4 - dev: true /path-to-regexp@0.1.7: resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} @@ -10356,6 +10586,11 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} + /pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + dev: false + /pify@3.0.0: resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} engines: {node: '>=4'} @@ -10369,7 +10604,6 @@ packages: /pirates@4.0.6: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} - dev: true /pkg-dir@3.0.0: resolution: {integrity: sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==} @@ -10500,6 +10734,45 @@ packages: postcss-selector-parser: 6.0.15 dev: true + /postcss-import@15.1.0(postcss@8.4.35): + resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} + engines: {node: '>=14.0.0'} + peerDependencies: + postcss: ^8.0.0 + dependencies: + postcss: 8.4.35 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.8 + dev: false + + /postcss-js@4.0.1(postcss@8.4.35): + resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} + engines: {node: ^12 || ^14 || >= 16} + peerDependencies: + postcss: ^8.4.21 + dependencies: + camelcase-css: 2.0.1 + postcss: 8.4.35 + dev: false + + /postcss-load-config@4.0.2(postcss@8.4.35): + resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} + engines: {node: '>= 14'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + dependencies: + lilconfig: 3.1.1 + postcss: 8.4.35 + yaml: 2.4.0 + dev: false + /postcss-merge-idents@6.0.2(postcss@8.4.35): resolution: {integrity: sha512-1fJqEzpgyjuec8UR9WdUDvCU0NhHVwKm4JK2Vk2Xv7RB+zpssSGFNE5Xwa0fmQYFxAwfb824monvKAyqLTGsSw==} engines: {node: ^14 || ^16 || >=18.0} @@ -10579,6 +10852,16 @@ packages: postcss-selector-parser: 6.0.15 dev: true + /postcss-nested@6.0.1(postcss@8.4.35): + resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + dependencies: + postcss: 8.4.35 + postcss-selector-parser: 6.0.15 + dev: false + /postcss-normalize-charset@6.0.1(postcss@8.4.35): resolution: {integrity: sha512-aW5LbMNRZ+oDV57PF9K+WI1Z8MPnF+A8qbajg/T8PP126YrGX1f9IQx21GI2OlGz7XFJi/fNi0GTbY948XJtXg==} engines: {node: ^14 || ^16 || >=18.0} @@ -10717,7 +11000,6 @@ packages: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 - dev: true /postcss-svgo@6.0.2(postcss@8.4.35): resolution: {integrity: sha512-IH5R9SjkTkh0kfFOQDImyy1+mTCb+E830+9SV1O+AaDcoHTvfsvt6WwJeo7KwcHbFnevZVCsXhDmjFiGVuwqFQ==} @@ -10935,7 +11217,6 @@ packages: /queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - dev: true /quick-lru@4.0.1: resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} @@ -10955,6 +11236,12 @@ packages: resolution: {integrity: sha512-BBea6L67bYLtdbOqfp8f58fPMqEwx0doL+pAi8TZyp2YWz8R9G8z9x75CZI8W+ftqhFHCpEX2cRnUUXK130iKA==} dev: true + /randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + dependencies: + safe-buffer: 5.2.1 + dev: true + /range-parser@1.2.1: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} @@ -10990,7 +11277,7 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: true - /react-dev-utils@12.0.1(eslint@8.56.0)(typescript@5.3.3): + /react-dev-utils@12.0.1(eslint@8.56.0)(typescript@5.3.3)(webpack@5.90.3): resolution: {integrity: sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==} engines: {node: '>=14'} peerDependencies: @@ -11009,7 +11296,7 @@ packages: escape-string-regexp: 4.0.0 filesize: 8.0.7 find-up: 5.0.0 - fork-ts-checker-webpack-plugin: 6.5.3(eslint@8.56.0)(typescript@5.3.3) + fork-ts-checker-webpack-plugin: 6.5.3(eslint@8.56.0)(typescript@5.3.3)(webpack@5.90.3) global-modules: 2.0.0 globby: 11.1.0 gzip-size: 6.0.0 @@ -11025,6 +11312,7 @@ packages: strip-ansi: 6.0.1 text-table: 0.2.0 typescript: 5.3.3 + webpack: 5.90.3(esbuild@0.18.20) transitivePeerDependencies: - eslint - supports-color @@ -11223,6 +11511,12 @@ packages: dependencies: loose-envify: 1.4.0 + /read-cache@1.0.0: + resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + dependencies: + pify: 2.3.0 + dev: false + /read-pkg-up@7.0.1: resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} engines: {node: '>=8'} @@ -11442,7 +11736,6 @@ packages: is-core-module: 2.13.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - dev: true /resolve@2.0.0-next.5: resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} @@ -11470,7 +11763,6 @@ packages: /reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - dev: true /rimraf@2.6.3: resolution: {integrity: sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==} @@ -11554,7 +11846,6 @@ packages: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} dependencies: queue-microtask: 1.2.3 - dev: true /rxjs@7.5.7: resolution: {integrity: sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==} @@ -11616,6 +11907,15 @@ packages: ajv-keywords: 3.5.2(ajv@6.12.6) dev: true + /schema-utils@3.3.0: + resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} + engines: {node: '>= 10.13.0'} + dependencies: + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + ajv-keywords: 3.5.2(ajv@6.12.6) + dev: true + /semver-compare@1.0.0: resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==} requiresBuild: true @@ -11676,6 +11976,12 @@ packages: dev: true optional: true + /serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + dependencies: + randombytes: 2.1.0 + dev: true + /serve-static@1.15.0: resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} engines: {node: '>= 0.8.0'} @@ -11737,7 +12043,6 @@ packages: engines: {node: '>=8'} dependencies: shebang-regex: 3.0.0 - dev: true /shebang-regex@1.0.0: resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} @@ -11747,7 +12052,6 @@ packages: /shebang-regex@3.0.0: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - dev: true /shell-quote@1.8.1: resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==} @@ -11773,7 +12077,6 @@ packages: /signal-exit@4.1.0: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} - dev: true /sirv@2.0.4: resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==} @@ -11939,7 +12242,6 @@ packages: emoji-regex: 8.0.0 is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 - dev: true /string-width@5.1.2: resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} @@ -11948,7 +12250,6 @@ packages: eastasianwidth: 0.2.0 emoji-regex: 9.2.2 strip-ansi: 7.1.0 - dev: true /string.prototype.matchall@4.0.10: resolution: {integrity: sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==} @@ -12013,14 +12314,12 @@ packages: engines: {node: '>=8'} dependencies: ansi-regex: 5.0.1 - dev: true /strip-ansi@7.1.0: resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} engines: {node: '>=12'} dependencies: ansi-regex: 6.0.1 - dev: true /strip-bom@3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} @@ -12107,6 +12406,20 @@ packages: resolution: {integrity: sha512-EQepAV+wMsIaGVGX1RECzgrcqRRU/0sYOHkeLsZ3fzHaHXZy4DaOOX0vOlGQdlsjkh3mFHAIlVimpwAs4dslyQ==} dev: false + /sucrase@3.35.0: + resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + dependencies: + '@jridgewell/gen-mapping': 0.3.3 + commander: 4.1.1 + glob: 10.3.10 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.6 + ts-interface-checker: 0.1.13 + dev: false + /sumchecker@3.0.1: resolution: {integrity: sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==} engines: {node: '>= 8.0'} @@ -12139,7 +12452,6 @@ packages: /supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - dev: true /svg-parser@2.0.4: resolution: {integrity: sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==} @@ -12179,6 +12491,37 @@ packages: tslib: 2.6.2 dev: true + /tailwindcss@3.4.1: + resolution: {integrity: sha512-qAYmXRfk3ENzuPBakNK0SRrUDipP8NQnEY6772uDhflcQz5EhRdD7JNZxyrFHVQNCwULPBn6FNPp9brpO7ctcA==} + engines: {node: '>=14.0.0'} + hasBin: true + dependencies: + '@alloc/quick-lru': 5.2.0 + arg: 5.0.2 + chokidar: 3.6.0 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.3.2 + glob-parent: 6.0.2 + is-glob: 4.0.3 + jiti: 1.21.0 + lilconfig: 2.1.0 + micromatch: 4.0.5 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.0.0 + postcss: 8.4.35 + postcss-import: 15.1.0(postcss@8.4.35) + postcss-js: 4.0.1(postcss@8.4.35) + postcss-load-config: 4.0.2(postcss@8.4.35) + postcss-nested: 6.0.1(postcss@8.4.35) + postcss-selector-parser: 6.0.15 + resolve: 1.22.8 + sucrase: 3.35.0 + transitivePeerDependencies: + - ts-node + dev: false + /tapable@1.1.3: resolution: {integrity: sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==} engines: {node: '>=6'} @@ -12257,6 +12600,42 @@ packages: execa: 0.7.0 dev: true + /terser-webpack-plugin@5.3.10(esbuild@0.18.20)(webpack@5.90.3): + resolution: {integrity: sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==} + engines: {node: '>= 10.13.0'} + peerDependencies: + '@swc/core': '*' + esbuild: '*' + uglify-js: '*' + webpack: ^5.1.0 + peerDependenciesMeta: + '@swc/core': + optional: true + esbuild: + optional: true + uglify-js: + optional: true + dependencies: + '@jridgewell/trace-mapping': 0.3.22 + esbuild: 0.18.20 + jest-worker: 27.5.1 + schema-utils: 3.3.0 + serialize-javascript: 6.0.2 + terser: 5.28.1 + webpack: 5.90.3(esbuild@0.18.20) + dev: true + + /terser@5.28.1: + resolution: {integrity: sha512-wM+bZp54v/E9eRRGXb5ZFDvinrJIOaTapx3WUokyVGZu5ucVCK55zEgGd5Dl2fSr3jUo5sDiERErUWLY6QPFyA==} + engines: {node: '>=10'} + hasBin: true + dependencies: + '@jridgewell/source-map': 0.3.5 + acorn: 8.11.3 + commander: 2.20.3 + source-map-support: 0.5.21 + dev: true + /test-exclude@6.0.0: resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} engines: {node: '>=8'} @@ -12275,6 +12654,19 @@ packages: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} dev: true + /thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + dependencies: + thenify: 3.3.1 + dev: false + + /thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + dependencies: + any-promise: 1.3.0 + dev: false + /through2@2.0.5: resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} dependencies: @@ -12365,6 +12757,10 @@ packages: engines: {node: '>=6.10'} dev: true + /ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + dev: false + /tsconfig-paths@3.15.0: resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} dependencies: @@ -12804,7 +13200,6 @@ packages: /util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - dev: true /util@0.10.4: resolution: {integrity: sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==} @@ -13025,6 +13420,46 @@ packages: resolution: {integrity: sha512-poXpCylU7ExuvZK8z+On3kX+S8o/2dQ/SVYueKA0D4WEMXROXgY8Ez50/bQEUmvoSMMrWcrJqCHuhAbsiwg7Dg==} dev: true + /webpack@5.90.3(esbuild@0.18.20): + resolution: {integrity: sha512-h6uDYlWCctQRuXBs1oYpVe6sFcWedl0dpcVaTf/YF67J9bKvwJajFulMVSYKHrksMB3I/pIagRzDxwxkebuzKA==} + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + dependencies: + '@types/eslint-scope': 3.7.7 + '@types/estree': 1.0.5 + '@webassemblyjs/ast': 1.11.6 + '@webassemblyjs/wasm-edit': 1.11.6 + '@webassemblyjs/wasm-parser': 1.11.6 + acorn: 8.11.3 + acorn-import-assertions: 1.9.0(acorn@8.11.3) + browserslist: 4.23.0 + chrome-trace-event: 1.0.3 + enhanced-resolve: 5.15.0 + es-module-lexer: 1.4.1 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + json-parse-even-better-errors: 2.3.1 + loader-runner: 4.3.0 + mime-types: 2.1.35 + neo-async: 2.6.2 + schema-utils: 3.3.0 + tapable: 2.2.1 + terser-webpack-plugin: 5.3.10(esbuild@0.18.20)(webpack@5.90.3) + watchpack: 2.4.0 + webpack-sources: 3.2.3 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + dev: true + /whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} dependencies: @@ -13093,7 +13528,6 @@ packages: hasBin: true dependencies: isexe: 2.0.0 - dev: true /why-is-node-running@2.2.2: resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} @@ -13122,7 +13556,6 @@ packages: ansi-styles: 4.3.0 string-width: 4.2.3 strip-ansi: 6.0.1 - dev: true /wrap-ansi@8.1.0: resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} @@ -13131,7 +13564,6 @@ packages: ansi-styles: 6.2.1 string-width: 5.1.2 strip-ansi: 7.1.0 - dev: true /wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -13223,6 +13655,12 @@ packages: engines: {node: '>= 6'} dev: true + /yaml@2.4.0: + resolution: {integrity: sha512-j9iR8g+/t0lArF4V6NE/QCfT+CO7iLqrXAHZbJdo+LfjqP1vR8Fg5bSiaq6Q2lOD1AUEVrEVIgABvBFYojJVYQ==} + engines: {node: '>= 14'} + hasBin: true + dev: false + /yargs-parser@20.2.9: resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} engines: {node: '>=10'} @@ -13266,9 +13704,4 @@ packages: file:custom-eslint-rules: resolution: {directory: custom-eslint-rules, type: directory} name: eslint-plugin-restrict-import-depth - version: 0.1.0 dev: true - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false diff --git a/src/shared/types/UserSchedule.ts b/src/shared/types/UserSchedule.ts index f6bd1e85d..fbfa8501e 100644 --- a/src/shared/types/UserSchedule.ts +++ b/src/shared/types/UserSchedule.ts @@ -10,12 +10,20 @@ export class UserSchedule { name: string; hours: number; - constructor(schedule: Serialized) { - this.courses = schedule.courses.map(c => new Course(c)); - this.name = schedule.name; - this.hours = 0; - for (const course of this.courses) { - this.hours += course.creditHours; + constructor(schedule: Serialized); + constructor(courses: Course[], name: string, hours: number); + constructor(coursesOrSchedule: Course[] | Serialized, name?: string, hours?: number) { + if (Array.isArray(coursesOrSchedule)) { + this.courses = coursesOrSchedule; + this.name = name || ''; + this.hours = hours || 0; + } else { + this.courses = coursesOrSchedule.courses.map(c => new Course(c)); + this.name = coursesOrSchedule.name; + this.hours = 0; + for (const course of this.courses) { + this.hours += course.creditHours; + } } } diff --git a/src/stories/components/calendar/CalendarGrid.stories.tsx b/src/stories/components/calendar/CalendarGrid.stories.tsx index 4c3d0d81a..39e79bff3 100644 --- a/src/stories/components/calendar/CalendarGrid.stories.tsx +++ b/src/stories/components/calendar/CalendarGrid.stories.tsx @@ -4,6 +4,8 @@ import type { Meta, StoryObj } from '@storybook/react'; import CalendarGrid from '@views/components/calendar/CalendarGrid/CalendarGrid'; import type { CalendarGridCourse } from '@views/hooks/useFlattenedCourseSchedule'; +import { ExampleCourse } from '../PopupCourseBlock.stories'; + const meta = { title: 'Components/Calendar/CalendarGrid', component: CalendarGrid, @@ -32,6 +34,7 @@ const testData: CalendarGridCourse[] = [ status: Status.OPEN, colors: getCourseColors('emerald', 500), }, + course: ExampleCourse, }, { calendarGridPoint: { @@ -45,6 +48,7 @@ const testData: CalendarGridCourse[] = [ status: Status.OPEN, colors: getCourseColors('emerald', 500), }, + course: ExampleCourse, }, { calendarGridPoint: { @@ -58,6 +62,7 @@ const testData: CalendarGridCourse[] = [ status: Status.CLOSED, colors: getCourseColors('emerald', 500), }, + course: ExampleCourse, }, { calendarGridPoint: { @@ -71,6 +76,7 @@ const testData: CalendarGridCourse[] = [ status: Status.OPEN, colors: getCourseColors('emerald', 500), }, + course: ExampleCourse, }, { calendarGridPoint: { @@ -84,6 +90,7 @@ const testData: CalendarGridCourse[] = [ status: Status.CLOSED, colors: getCourseColors('emerald', 500), }, + course: ExampleCourse, }, { calendarGridPoint: { @@ -97,6 +104,7 @@ const testData: CalendarGridCourse[] = [ status: Status.CLOSED, colors: getCourseColors('emerald', 500), }, + course: ExampleCourse, }, { calendarGridPoint: { @@ -110,6 +118,7 @@ const testData: CalendarGridCourse[] = [ status: Status.CLOSED, colors: getCourseColors('emerald', 500), }, + course: ExampleCourse, }, ]; diff --git a/src/views/components/PopupMain.tsx b/src/views/components/PopupMain.tsx index 4d5ca71ee..8b7421988 100644 --- a/src/views/components/PopupMain.tsx +++ b/src/views/components/PopupMain.tsx @@ -10,6 +10,7 @@ import { handleOpenCalendar } from '@views/components/injected/CourseCatalogInje import useSchedules from '@views/hooks/useSchedules'; import { openTabFromContentScript } from '@views/lib/openNewTabFromContentScript'; import React from 'react'; +import { act } from 'react-dom/test-utils'; import { tailwindColorways } from 'src/shared/util/storybook'; import CalendarIcon from '~icons/material-symbols/calendar-month'; @@ -21,14 +22,21 @@ import SettingsIcon from '~icons/material-symbols/settings'; * This component displays the main schedule, courses, and options buttons. */ export default function PopupMain() { - const [activeSchedule] = useSchedules(); - - const draggableElements = activeSchedule?.courses.map((course, i) => ( - + const [activeSchedule, schedules] = useSchedules(); + const coursesLength = activeSchedule ? activeSchedule.courses.length : 0; + if (!activeSchedule) { + return; + } + + const draggableElements = activeSchedule?.courses.map((course, i) => ( + )); const handleOpenOptions = async () => { - // Not sure if it's bad practice to export this const url = chrome.runtime.getURL('/src/pages/options/index.html'); await openTabFromContentScript(url); }; @@ -60,11 +68,11 @@ export default function PopupMain() {
- MAIN SCHEDULE: + {`${activeSchedule.name}`}:
- 22 HOURS - 8 Courses + {`${activeSchedule.hours} HOURS`} + {`${coursesLength} Courses`}
{/* Integrate the List component here */} diff --git a/src/views/components/calendar/Calendar/Calendar.tsx b/src/views/components/calendar/Calendar/Calendar.tsx index da21870bb..63162daef 100644 --- a/src/views/components/calendar/Calendar/Calendar.tsx +++ b/src/views/components/calendar/Calendar/Calendar.tsx @@ -1,9 +1,15 @@ +import type { Course } from '@shared/types/Course'; import { CalendarBottomBar } from '@views/components/calendar/CalendarBottomBar/CalendarBottomBar'; import CalendarGrid from '@views/components/calendar/CalendarGrid/CalendarGrid'; import CalendarHeader from '@views/components/calendar/CalendarHeader/CalenderHeader'; import { CalendarSchedules } from '@views/components/calendar/CalendarSchedules/CalendarSchedules'; import ImportantLinks from '@views/components/calendar/ImportantLinks'; +import CourseCatalogInjectedPopup from '@views/components/injected/CourseCatalogInjectedPopup/CourseCatalogInjectedPopup'; +import { useFlattenedCourseSchedule } from '@views/hooks/useFlattenedCourseSchedule'; import React from 'react'; +import { ExampleCourse } from 'src/stories/components/PopupCourseBlock.stories'; + + export const flags = ['WR', 'QR', 'GC', 'CD', 'E', 'II']; @@ -16,9 +22,12 @@ interface Props { * @returns */ export function Calendar(): JSX.Element { + const { courseCells, activeSchedule } = useFlattenedCourseSchedule(); + const [course, setCourse] = React.useState(null); + return ( - <> - +
+
@@ -26,15 +35,18 @@ export function Calendar(): JSX.Element {
-
+
- +
- + {/* TODO: Doesn't work when exampleCourse is replaced with an actual course through setCourse. + Check CalendarGrid.tsx and AccountForCourseConflicts for an example */} + {course ? setCourse(null)}/> : null} +
); } diff --git a/src/views/components/calendar/CalendarCourseCell/CalendarCourseCell.tsx b/src/views/components/calendar/CalendarCourseCell/CalendarCourseCell.tsx index 9542a8055..f7e5fa5cd 100644 --- a/src/views/components/calendar/CalendarCourseCell/CalendarCourseCell.tsx +++ b/src/views/components/calendar/CalendarCourseCell/CalendarCourseCell.tsx @@ -19,6 +19,7 @@ export interface CalendarCourseCellProps { status: StatusType; colors: CourseColors; className?: string; + onClick?: React.MouseEventHandler; } /** @@ -39,6 +40,7 @@ const CalendarCourseCell: React.FC = ({ status, colors, className, + onClick, }: CalendarCourseCellProps) => { let rightIcon: React.ReactNode | null = null; if (status === Status.WAITLISTED) { @@ -54,10 +56,11 @@ const CalendarCourseCell: React.FC = ({ return (
!['S', 'SU'].includes(key)); -const hoursOfDay = Array.from({ length: 14 }, (_, index) => index + 8); -const grid = []; -for (let i = 0; i < 13; i++) { - const row = []; - let hour = hoursOfDay[i]; - row.push( -
-
-

{(hour % 12 === 0 ? 12 : hour % 12) + (hour < 12 ? ' AM' : ' PM')}

-
-
- ); - row.push(Array.from({ length: 5 }, (_, j) => )); - grid.push(row); -} */ interface Props { courseCells?: CalendarGridCourse[]; saturdayClass?: boolean; + setCourse: React.Dispatch>; } /** * Grid of CalendarGridCell components forming the user's course schedule calendar view * @param props */ -function CalendarGrid({ courseCells, saturdayClass }: React.PropsWithChildren): JSX.Element { - const [grid, setGrid] = useState([]); +function CalendarGrid({ courseCells, saturdayClass, setCourse }: React.PropsWithChildren): JSX.Element { + // const [grid, setGrid] = useState([]); const calendarRef = useRef(null); // Create a ref for the calendar grid const daysOfWeek = Object.keys(DAY_MAP).filter(key => !['S', 'SU'].includes(key)); @@ -76,39 +63,32 @@ function CalendarGrid({ courseCells, saturdayClass }: React.PropsWithChildren { - const newGrid = []; - for (let i = 0; i < 13; i++) { - const row = []; - let hour = hoursOfDay[i]; - let styleProp = { - gridColumn: '1', - gridRow: `${2 * i + 2}`, - }; - row.push( -
-
-

{(hour % 12 === 0 ? 12 : hour % 12) + (hour < 12 ? ' AM' : ' PM')}

-
+ // TODO: Change to useMemo hook once we start calculating grid size based on if there's a Saturday class or not + const grid = []; + for (let i = 0; i < 13; i++) { + const row = []; + let hour = hoursOfDay[i]; + let styleProp = { + gridColumn: '1', + gridRow: `${2 * i + 2}`, + }; + row.push( +
+
+

{(hour % 12 === 0 ? 12 : hour % 12) + (hour < 12 ? ' AM' : ' PM')}

- ); - for (let k = 0; k < 5; k++) { - // let shouldRender = false; - styleProp = { - gridColumn: `${k + 2}`, - gridRow: `${2 * i + 2} / ${2 * i + 4}`, - }; - /* let shouldRenderChild = courseCells[iterator]?.calendarGridPoint && - k === courseCells[iterator].calendarGridPoint.dayIndex && i === courseCells[iterator].calendarGridPoint.startIndex; - let childElement =
; */ - /* let completeGridCell = shouldRenderChild ? - : ; */ - row.push(); - } - newGrid.push(row); +
+ ); + for (let k = 0; k < 5; k++) { + styleProp = { + gridColumn: `${k + 2}`, + gridRow: `${2 * i + 2} / ${2 * i + 4}`, + }; + row.push(); } - setGrid(newGrid); - }, [hoursOfDay]); + grid.push(row); + } + return (
@@ -120,23 +100,7 @@ function CalendarGrid({ courseCells, saturdayClass }: React.PropsWithChildren ))} {grid.map((row, rowIndex) => row)} - {courseCells ? : null} - {/* courseCells.map((block: CalendarGridCourse) => ( -
- -
- )) */} + {courseCells ? : null}
); } @@ -145,9 +109,10 @@ export default CalendarGrid; interface AccountForCourseConflictsProps { courseCells: CalendarGridCourse[]; + setCourse: React.Dispatch>; } -function AccountForCourseConflicts({ courseCells }: AccountForCourseConflictsProps): JSX.Element[] { +function AccountForCourseConflicts({ courseCells, setCourse }: AccountForCourseConflictsProps): JSX.Element[] { // Groups by dayIndex to identify overlaps const days = courseCells.reduce((acc, cell: CalendarGridCourse) => { const { dayIndex } = cell.calendarGridPoint; @@ -173,11 +138,9 @@ function AccountForCourseConflicts({ courseCells }: AccountForCourseConflictsPro otherCell.calendarGridPoint.startIndex < cell.calendarGridPoint.endIndex && otherCell.calendarGridPoint.endIndex > cell.calendarGridPoint.startIndex; if (isOverlapping) { - console.log('Found overlapping element'); // Adjust columnIndex to not overlap with the otherCell if (otherCell.gridColumnStart && otherCell.gridColumnStart >= columnIndex) { columnIndex = otherCell.gridColumnStart + 1; - console.log(columnIndex); } cell.totalColumns += 1; } @@ -188,12 +151,15 @@ function AccountForCourseConflicts({ courseCells }: AccountForCourseConflictsPro }); }); + // Part of TODO: block.course is definitely a course object + console.log(courseCells); + return courseCells.map(block => (
setCourse(block.course)} />
)); diff --git a/src/views/components/calendar/CalendarHeader/CalenderHeader.tsx b/src/views/components/calendar/CalendarHeader/CalenderHeader.tsx index ee13b99cd..235c13124 100644 --- a/src/views/components/calendar/CalendarHeader/CalenderHeader.tsx +++ b/src/views/components/calendar/CalendarHeader/CalenderHeader.tsx @@ -4,6 +4,7 @@ import CourseStatus from '@views/components/common/CourseStatus/CourseStatus'; import Divider from '@views/components/common/Divider/Divider'; import ScheduleTotalHoursAndCourses from '@views/components/common/ScheduleTotalHoursAndCourses/ScheduleTotalHoursAndCourses'; import Text from '@views/components/common/Text/Text'; +import { openTabFromContentScript } from '@views/lib/openNewTabFromContentScript'; import React from 'react'; import calIcon from 'src/assets/logo.png'; @@ -12,12 +13,13 @@ import RedoIcon from '~icons/material-symbols/redo'; import SettingsIcon from '~icons/material-symbols/settings'; import UndoIcon from '~icons/material-symbols/undo'; -/** - * Renders the header component for the calendar. - * @returns The CalendarHeader component. - */ -const CalendarHeader = () => ( -
+const handleOpenOptions = async () => { + const url = chrome.runtime.getURL('/src/pages/options/index.html'); + await openTabFromContentScript(url); +}; + +const CalendarHeader = ( { totalHours, totalCourses, scheduleName } ) => ( +
@@ -47,7 +49,7 @@ const CalendarHeader = () => (
diff --git a/src/views/components/calendar/CalendarSchedules/CalendarSchedules.tsx b/src/views/components/calendar/CalendarSchedules/CalendarSchedules.tsx index 0ab39600d..c99eea3dd 100644 --- a/src/views/components/calendar/CalendarSchedules/CalendarSchedules.tsx +++ b/src/views/components/calendar/CalendarSchedules/CalendarSchedules.tsx @@ -1,14 +1,15 @@ +import createSchedule from '@pages/background/lib/createSchedule'; +import switchSchedule from '@pages/background/lib/switchSchedule'; import type { UserSchedule } from '@shared/types/UserSchedule'; -import List from '@views/components/common/List/List'; -import ScheduleListItem from '@views/components/common/ScheduleListItem/ScheduleListItem'; -import Text from '@views/components/common/Text/Text'; -import React, { useState } from 'react'; +import useSchedules from '@views/hooks/useSchedules'; +import React, { useEffect,useState } from 'react'; import AddSchedule from '~icons/material-symbols/add'; -/** - * Props for the CalendarSchedules component. - */ +import List from '../../common/List/List'; +import ScheduleListItem from '../../common/ScheduleListItem/ScheduleListItem'; +import Text from '../../common/Text/Text'; + export type Props = { style?: React.CSSProperties; dummySchedules?: UserSchedule[]; @@ -22,11 +23,39 @@ export type Props = { * @returns The rendered component. */ export function CalendarSchedules(props: Props) { - const [activeScheduleIndex, setActiveScheduleIndex] = useState(props.dummyActiveIndex || 0); - const [schedules, setSchedules] = useState(props.dummySchedules || []); + const [activeScheduleIndex, setActiveScheduleIndex] = useState(0); + const [newSchedule, setNewSchedule] = useState(''); + const [activeSchedule, schedules] = useSchedules(); + + useEffect(() => { + const index = schedules.findIndex(schedule => schedule.name === activeSchedule.name); + if (index !== -1) { + setActiveScheduleIndex(index); + } + }, [activeSchedule, schedules]); + + const handleKeyDown = event => { + if (event.code === 'Enter') { + createSchedule(newSchedule); + setNewSchedule(''); + } + }; + + const handleScheduleInputChange = (e: React.ChangeEvent) => { + setNewSchedule(e.target.value); + }; + + const selectItem = (index: number) => { + setActiveScheduleIndex(index); + switchSchedule(schedules[index].name); + }; const scheduleComponents = schedules.map((schedule, index) => ( - + selectItem(index)} + /> )); return ( @@ -39,8 +68,16 @@ export function CalendarSchedules(props: Props) {
- - +
+ + +
); } diff --git a/src/views/components/common/List/List.tsx b/src/views/components/common/List/List.tsx index c6bce8101..2ae857965 100644 --- a/src/views/components/common/List/List.tsx +++ b/src/views/components/common/List/List.tsx @@ -1,6 +1,6 @@ import { DragDropContext, Draggable, Droppable } from '@hello-pangea/dnd'; import type { ReactElement } from 'react'; -import React, { useCallback, useState } from 'react'; +import React, { useCallback, useEffect,useState } from 'react'; /* * Ctrl + f dragHandleProps on PopupCourseBlock.tsx for example implementation of drag handle (two lines of code) @@ -19,9 +19,9 @@ export interface ListProps { gap: number; // Impacts the spacing between items in the list } -function initial(draggableElements: any[] = []) { +function initial(count: number, draggableElements: any[] = []) { return draggableElements.map((element, index) => ({ - id: `id:${index}`, + id: `id:${index + count}`, content: element as ReactElement, })); } @@ -83,8 +83,17 @@ const Row: React.FC = React.memo(({ data: { items, gap }, index, style * */ const List: React.FC = ({ draggableElements, itemHeight, listHeight, listWidth, gap = 12 }: ListProps) => { - const [items, setItems] = useState(() => initial(draggableElements)); - + const [items, setItems] = useState(() => initial(0, draggableElements)); + + useEffect(() => { + setItems((prevItems) => { + const prevItemIds = prevItems.map(item => item.id); + const newElements = draggableElements.filter((_, index) => !prevItemIds.includes(`id:${index}`)); + const newItems = initial(prevItems.length, newElements); + return [...prevItems, ...newItems]; + }); + }, [draggableElements]); + const onDragEnd = useCallback( result => { if (!result.destination) { @@ -113,8 +122,7 @@ const List: React.FC = ({ draggableElements, itemHeight, listHeight, const transform = style?.transform; if (snapshot.isDragging && transform) { - console.log(transform); - let [, _x, y] = transform.match(/translate\(([-\d]+)px, ([-\d]+)px\)/) || []; + let [, , y] = transform.match(/translate\(([-\d]+)px, ([-\d]+)px\)/) || []; style.transform = `translate3d(0px, ${y}px, 0px)`; // Apply constrained y value } diff --git a/src/views/components/common/ScheduleListItem/ScheduleListItem.tsx b/src/views/components/common/ScheduleListItem/ScheduleListItem.tsx index 270f357c3..4889578a6 100644 --- a/src/views/components/common/ScheduleListItem/ScheduleListItem.tsx +++ b/src/views/components/common/ScheduleListItem/ScheduleListItem.tsx @@ -12,14 +12,15 @@ export type Props = { active?: boolean; name: string; dragHandleProps?: any; + onClick?: (index) => void; }; /** * This is a reusable dropdown component that can be used to toggle the visiblity of information */ export default function ScheduleListItem(props: Props) { - const { dragHandleProps } = props; - console.log(props); + const { dragHandleProps, onClick } = props; + return (
  • @@ -31,7 +32,10 @@ export default function ScheduleListItem(props: Props) {
  • -
    +
    { */ const HeadingAndActions: React.FC = ({ course, onClose, activeSchedule }) => { const { courseName, department, number: courseNumber, uniqueId, instructors, flags, schedule } = course; - const [courseAdded, setCourseAdded] = useState( - activeSchedule.courses.some(course => course.uniqueId === uniqueId) - ); + const courseAdded = activeSchedule.courses.some(ourCourse => ourCourse.uniqueId === uniqueId); const instructorString = instructors .map(instructor => { @@ -82,7 +80,6 @@ const HeadingAndActions: React.FC = ({ course, onClose, a } else { await removeCourse(activeSchedule.name, course); } - setCourseAdded(!courseAdded); }; return (
    diff --git a/src/views/hooks/useFlattenedCourseSchedule.ts b/src/views/hooks/useFlattenedCourseSchedule.ts index 040f3167c..e7f784f8a 100644 --- a/src/views/hooks/useFlattenedCourseSchedule.ts +++ b/src/views/hooks/useFlattenedCourseSchedule.ts @@ -1,7 +1,12 @@ +import type { Course, StatusType } from '@shared/types/Course'; +import type { CourseMeeting } from '@shared/types/CourseMeeting'; +import { UserSchedule } from '@shared/types/UserSchedule'; import type { CalendarCourseCellProps } from '@views/components/calendar/CalendarCourseCell/CalendarCourseCell'; import useSchedules from './useSchedules'; + + const dayToNumber: { [day: string]: number } = { Monday: 0, Tuesday: 1, @@ -16,17 +21,27 @@ interface CalendarGridPoint { endIndex: number; } +interface componentProps { + calendarCourseCellProps: CalendarCourseCellProps; +} + /** * Return type of useFlattenedCourseSchedule */ export interface CalendarGridCourse { calendarGridPoint: CalendarGridPoint; componentProps: CalendarCourseCellProps; + course: Course; gridColumnStart?: number; gridColumnEnd?: number; totalColumns?: number; } +export interface FlattenedCourseSchedule { + courseCells: CalendarGridCourse[]; + activeSchedule?: UserSchedule; +} + /** * Converts minutes to an index value. * @param minutes The number of minutes. @@ -38,74 +53,168 @@ export const convertMinutesToIndex = (minutes: number): number => Math.floor((mi * Get the active schedule, and convert it to be render-able into a calendar. * @returns CalendarGridCourse */ -export function useFlattenedCourseSchedule(): CalendarGridCourse[] { +export function useFlattenedCourseSchedule(): FlattenedCourseSchedule { const [activeSchedule] = useSchedules(); - const { courses } = activeSchedule; - - return courses - .flatMap(course => { - const { - status, - department, - instructors, - schedule: { meetings }, - } = course; - const courseDeptAndInstr = `${department} ${instructors[0].lastName}`; - - if (meetings.length === 0) { - // asynch, online course - return [ - { - calendarGridPoint: { - dayIndex: 0, - startIndex: 0, - endIndex: 0, - }, - componentProps: { - courseDeptAndInstr, - status, - colors: { - // TODO: figure out colors - these are defaults - primaryColor: 'ut-gray', - secondaryColor: 'ut-gray', - }, - }, - }, - ]; - } - - // in-person - return meetings.flatMap(meeting => { - const { days, startTime, endTime, location } = meeting; - const time = meeting.getTimeString({ separator: '-', capitalize: true }); - const timeAndLocation = `${time} - ${location ? location.building : 'WB'}`; - - return days.map(d => ({ - calendarGridPoint: { - dayIndex: dayToNumber[d], - startIndex: convertMinutesToIndex(startTime), - endIndex: convertMinutesToIndex(endTime), - }, - componentProps: { - courseDeptAndInstr, - timeAndLocation, - status, - colors: { - // TODO: figure out colors - these are defaults - primaryColor: 'ut-orange', - secondaryColor: 'ut-orange', - }, - }, - })); - }); - }) - .sort((a: CalendarGridCourse, b: CalendarGridCourse) => { - if (a.calendarGridPoint.dayIndex !== b.calendarGridPoint.dayIndex) { - return a.calendarGridPoint.dayIndex - b.calendarGridPoint.dayIndex; - } - if (a.calendarGridPoint.startIndex !== b.calendarGridPoint.startIndex) { - return a.calendarGridPoint.startIndex - b.calendarGridPoint.startIndex; - } - return a.calendarGridPoint.endIndex - b.calendarGridPoint.endIndex; - }); + + if (!activeSchedule) { + return { + courseCells: [] as CalendarGridCourse[], + activeSchedule: new UserSchedule([], 'Something may have went wrong', 0), + } as FlattenedCourseSchedule; + } + + if (activeSchedule.courses.length === 0) { + return { + courseCells: [] as CalendarGridCourse[], + activeSchedule + } satisfies FlattenedCourseSchedule; + + } + + const { courses, name, hours } = activeSchedule; + + const processedCourses = courses.flatMap((course: Course) => { + const { status, courseDeptAndInstr, meetings } = extractCourseInfo(course); + + if (meetings.length === 0) { + return processAsyncCourses({ courseDeptAndInstr, status, course }); + } + + return meetings.flatMap((meeting: CourseMeeting) => + processInPersonMeetings(meeting, { courseDeptAndInstr, status, course }) + ); + }).sort(sortCourses); + + return { + courseCells: processedCourses as CalendarGridCourse[], + activeSchedule: { name, courses, hours } as UserSchedule, + } satisfies FlattenedCourseSchedule; +} + +// Helper function to extract and format basic course information +function extractCourseInfo(course: Course) { + const { + status, + department, + instructors, + schedule: { meetings }, + } = course; + const courseDeptAndInstr = `${department} ${instructors[0].lastName}`; + return { status, courseDeptAndInstr, meetings, course }; +} + +/** + * Function to process each in-person class into its distinct meeting objects for calendar grid + */ +function processAsyncCourses({ courseDeptAndInstr, status, course }: { courseDeptAndInstr: string, status: StatusType, course: Course }) { + return [{ + calendarGridPoint: { + dayIndex: 0, + startIndex: 0, + endIndex: 0, + }, + componentProps: { + courseDeptAndInstr, + status, + colors: { + primaryColor: 'ut-gray', + secondaryColor: 'ut-gray', + }, + }, + course, + }] satisfies CalendarGridCourse[]; +} + +/** + * Function to process each in-person class into its distinct meeting objects for calendar grid + */ +function processInPersonMeetings( { days, startTime, endTime, location }: CourseMeeting, { courseDeptAndInstr, status, course }) { + const time = getTimeString({ separator: '-', capitalize: true }, startTime, endTime); + const timeAndLocation = `${time} - ${location ? location.building : 'WB'}`; + return days.map(day => ({ + calendarGridPoint: { + dayIndex: dayToNumber[day], + startIndex: convertMinutesToIndex(startTime), + endIndex: convertMinutesToIndex(endTime), + }, + componentProps: { + courseDeptAndInstr, + timeAndLocation, + status, + colors: { + primaryColor: 'ut-orange', + secondaryColor: 'ut-orange', + }, + }, + course, + })) satisfies CalendarGridCourse[]; } + + +/** + * Utility function to sort courses for the calendar grid + */ +function sortCourses(a, b) { + const { dayIndex: dayIndexA, startIndex: startIndexA, endIndex: endIndexA } = a.calendarGridPoint; + const { dayIndex: dayIndexB, startIndex: startIndexB, endIndex: endIndexB } = b.calendarGridPoint; + + if (dayIndexA !== dayIndexB) { + return dayIndexA - dayIndexB; + } + if (startIndexA !== startIndexB) { + return startIndexA - startIndexB; + } + return endIndexA - endIndexB; +} + + +/** + * Utility function also present in CourseMeeting object. Wasn't being found at runtime, so I copied it over. + */ +function getTimeString(options: TimeStringOptions, startTime: number, endTime: number): string { + const startHour = Math.floor(startTime / 60); + const startMinute = startTime % 60; + const endHour = Math.floor(endTime / 60); + const endMinute = endTime % 60; + + let startTimeString = ''; + let endTimeString = ''; + + if (startHour === 0) { + startTimeString = '12'; + } else if (startHour > 12) { + startTimeString = `${startHour - 12}`; + } else { + startTimeString = `${startHour}`; + } + + startTimeString += startMinute === 0 ? ':00' : `:${startMinute}`; + startTimeString += startHour >= 12 ? 'pm' : 'am'; + + if (endHour === 0) { + endTimeString = '12'; + } else if (endHour > 12) { + endTimeString = `${endHour - 12}`; + } else { + endTimeString = `${endHour}`; + } + endTimeString += endMinute === 0 ? ':00' : `:${endMinute}`; + endTimeString += endHour >= 12 ? 'pm' : 'am'; + + if (options.capitalize) { + startTimeString = startTimeString.toUpperCase(); + endTimeString = endTimeString.toUpperCase(); + } + + return `${startTimeString} ${options.separator} ${endTimeString}`; +} + +/** + * Options to control the format of the time string + */ +type TimeStringOptions = { + /** the separator between the start and end times */ + separator: string; + /** capitalizes the AM/PM */ + capitalize?: boolean; +}; \ No newline at end of file diff --git a/src/views/lib/openNewTabFromContentScript.ts b/src/views/lib/openNewTabFromContentScript.ts index cde2b3d80..782d0ec77 100644 --- a/src/views/lib/openNewTabFromContentScript.ts +++ b/src/views/lib/openNewTabFromContentScript.ts @@ -15,7 +15,7 @@ const messenger = createMessenger('background'); */ export async function openTabFromContentScript(url: string) { messenger - .openNewTab({ url }) + .openNewTab({ url }) // Fix: Pass the url as a property of an object .then(() => { console.log('New tab opened with URL:', url); })