From 2d7db3b12075c59dea665340d829c62db7770d87 Mon Sep 17 00:00:00 2001 From: Paul Abumov Date: Mon, 24 Jun 2024 23:08:30 -0400 Subject: [PATCH 1/3] Added response histogram for choice-based FormComposer questions --- .../how_to_use/review_app/server_api.md | 2 +- .../dynamic_example_ec2_mturk_sandbox.yaml | 2 +- .../conf/dynamic_example_ec2_prolific.yaml | 2 +- .../conf/dynamic_example_local_mock.yaml | 2 +- ...c_presigned_urls_example_ec2_prolific.yaml | 2 +- .../conf/example_local_mock.yaml | 2 +- .../hydra_configs/conf/default.yaml | 2 +- mephisto/generators/form_composer/stats.py | 96 +++ mephisto/review_app/client/package-lock.json | 807 +++++++++++++++++- mephisto/review_app/client/package.json | 1 + mephisto/review_app/client/src/App/App.tsx | 5 + .../pages/TaskPage/ModalForm/ModalForm.tsx | 3 +- .../client/src/pages/TaskPage/TaskPage.tsx | 4 +- .../src/pages/TaskStatsPage/Histogram.tsx | 116 +++ .../src/pages/TaskStatsPage/TaskStatsPage.css | 64 ++ .../src/pages/TaskStatsPage/TaskStatsPage.tsx | 145 ++++ .../client/src/pages/TasksPage/TasksPage.css | 15 + .../client/src/pages/TasksPage/TasksPage.tsx | 9 + .../review_app/client/src/requests/tasks.ts | 21 + .../client/src/types/histogram.d.ts | 10 + .../review_app/client/src/types/tasks.d.ts | 7 + mephisto/review_app/client/src/urls.ts | 4 +- .../review_app/server/api/views/__init__.py | 3 +- .../{stats_view.py => review_stats_view.py} | 2 +- .../api/views/task_export_results_view.py | 4 +- .../api/views/task_stats_results_view.py | 43 + mephisto/review_app/server/urls.py | 8 +- .../mephisto-task-multipart/package-lock.json | 391 +++------ .../react-form-composer/package-lock.json | 1 + 29 files changed, 1441 insertions(+), 332 deletions(-) create mode 100644 mephisto/generators/form_composer/stats.py create mode 100644 mephisto/review_app/client/src/pages/TaskStatsPage/Histogram.tsx create mode 100644 mephisto/review_app/client/src/pages/TaskStatsPage/TaskStatsPage.css create mode 100644 mephisto/review_app/client/src/pages/TaskStatsPage/TaskStatsPage.tsx create mode 100644 mephisto/review_app/client/src/types/histogram.d.ts rename mephisto/review_app/server/api/views/{stats_view.py => review_stats_view.py} (99%) create mode 100644 mephisto/review_app/server/api/views/task_stats_results_view.py diff --git a/docs/web/docs/guides/how_to_use/review_app/server_api.md b/docs/web/docs/guides/how_to_use/review_app/server_api.md index 59b826082..98769f1c9 100644 --- a/docs/web/docs/guides/how_to_use/review_app/server_api.md +++ b/docs/web/docs/guides/how_to_use/review_app/server_api.md @@ -310,7 +310,7 @@ Get list of all granted qualifications for a worker --- -### `GET /api/stats?{task_id=}{worker_id=}{since=}{limit=}` +### `GET /api/review-stats?{task_id=}{worker_id=}{since=}{limit=}` Get stats of (recent) approvals. Either `task_id` or `worker_id` (or both) must be present. diff --git a/examples/form_composer_demo/hydra_configs/conf/dynamic_example_ec2_mturk_sandbox.yaml b/examples/form_composer_demo/hydra_configs/conf/dynamic_example_ec2_mturk_sandbox.yaml index 0ca13548b..a32edf2cc 100644 --- a/examples/form_composer_demo/hydra_configs/conf/dynamic_example_ec2_mturk_sandbox.yaml +++ b/examples/form_composer_demo/hydra_configs/conf/dynamic_example_ec2_mturk_sandbox.yaml @@ -28,7 +28,7 @@ mephisto: task_title: "Dynamic form-based Tasks for Mturk" task_description: "In this Task, we use dynamic FormComposer feature." task_reward: 0.05 - task_tags: "dynamic,form,testing" + task_tags: "dynamic,form,testing,form-composer" assignment_duration_in_seconds: 3600 force_rebuild: true max_num_concurrent_units: 1 diff --git a/examples/form_composer_demo/hydra_configs/conf/dynamic_example_ec2_prolific.yaml b/examples/form_composer_demo/hydra_configs/conf/dynamic_example_ec2_prolific.yaml index c47a3be28..776589de7 100644 --- a/examples/form_composer_demo/hydra_configs/conf/dynamic_example_ec2_prolific.yaml +++ b/examples/form_composer_demo/hydra_configs/conf/dynamic_example_ec2_prolific.yaml @@ -28,7 +28,7 @@ mephisto: task_title: "Dynamic form-based Tasks for Prolifik" task_description: "In this Task, we use dynamic FormComposer feature." task_reward: 70 - task_tags: "test,simple,form" + task_tags: "test,simple,form,form-composer" force_rebuild: true max_num_concurrent_units: 1 provider: diff --git a/examples/form_composer_demo/hydra_configs/conf/dynamic_example_local_mock.yaml b/examples/form_composer_demo/hydra_configs/conf/dynamic_example_local_mock.yaml index 3a3aeca3b..49d25bc78 100644 --- a/examples/form_composer_demo/hydra_configs/conf/dynamic_example_local_mock.yaml +++ b/examples/form_composer_demo/hydra_configs/conf/dynamic_example_local_mock.yaml @@ -22,5 +22,5 @@ mephisto: task_title: "Example how to easily create dynamic form-based Tasks" task_description: "In this Task, we use FormComposer feature." task_reward: 0 - task_tags: "test,dynamic,form" + task_tags: "test,dynamic,form,form-composer" force_rebuild: true diff --git a/examples/form_composer_demo/hydra_configs/conf/dynamic_presigned_urls_example_ec2_prolific.yaml b/examples/form_composer_demo/hydra_configs/conf/dynamic_presigned_urls_example_ec2_prolific.yaml index b98632152..df2cc2d01 100644 --- a/examples/form_composer_demo/hydra_configs/conf/dynamic_presigned_urls_example_ec2_prolific.yaml +++ b/examples/form_composer_demo/hydra_configs/conf/dynamic_presigned_urls_example_ec2_prolific.yaml @@ -27,7 +27,7 @@ mephisto: task_title: "Dynamic form-based Tasks with expiring URLs for Prolifik" task_description: "In this Task, we use dynamic FormComposer feature with presigned S3 URLs." task_reward: 70 - task_tags: "test,simple,form" + task_tags: "test,simple,form,form-composer" force_rebuild: true max_num_concurrent_units: 1 provider: diff --git a/examples/form_composer_demo/hydra_configs/conf/example_local_mock.yaml b/examples/form_composer_demo/hydra_configs/conf/example_local_mock.yaml index 2cb6b5f32..f4f45e10c 100644 --- a/examples/form_composer_demo/hydra_configs/conf/example_local_mock.yaml +++ b/examples/form_composer_demo/hydra_configs/conf/example_local_mock.yaml @@ -22,5 +22,5 @@ mephisto: task_title: "Example how to easily create simple form-based Tasks" task_description: "In this Task, we use FormComposer feature." task_reward: 0 - task_tags: "test,simple,form" + task_tags: "test,simple,form,form-composer" force_rebuild: true diff --git a/mephisto/generators/form_composer/hydra_configs/conf/default.yaml b/mephisto/generators/form_composer/hydra_configs/conf/default.yaml index 2eff8fb35..8efa48d4e 100644 --- a/mephisto/generators/form_composer/hydra_configs/conf/default.yaml +++ b/mephisto/generators/form_composer/hydra_configs/conf/default.yaml @@ -21,4 +21,4 @@ mephisto: task_title: "Form-task" task_description: "Auto-generated form" task_reward: 0 - task_tags: "simple,form,generated" + task_tags: "simple,form,generated,form-composer" diff --git a/mephisto/generators/form_composer/stats.py b/mephisto/generators/form_composer/stats.py new file mode 100644 index 000000000..dd22e7f3a --- /dev/null +++ b/mephisto/generators/form_composer/stats.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python3 + +# Copyright (c) Meta Platforms and its affiliates. +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +from typing import List + +from mephisto.data_model.task import Task +from mephisto.data_model.unit import Unit +from mephisto.tools.data_browser import DataBrowser + +FIELD_TYPES_FOR_HISTOGRAM = ["radio", "checkbox", "select"] + + +def _get_unit_data(data_browser: DataBrowser, unit: Unit) -> dict: + unit_data = data_browser.get_data_from_unit(unit) + + unit_inputs = unit_data.get("data", {}).get("inputs") or {} + unit_outputs = unit_data.get("data", {}).get("outputs") or {} + # In case if there is outdated code that returns `final_submission` + # under `inputs` and `outputs` keys, we should use the value in side `final_submission` + if "final_submission" in unit_inputs: + unit_inputs = unit_inputs["final_submission"] + if "final_submission" in unit_outputs: + unit_outputs = unit_outputs["final_submission"] + + return { + "unit_inputs": unit_inputs, + "unit_outputs": unit_outputs, + } + + +def _get_unit_fields_for_histogram(unit_inputs: dict) -> dict: + fields = {} + form_data = unit_inputs["form"] + for section in form_data["sections"]: + for fieldset in section["fieldsets"]: + for row in fieldset["rows"]: + for field in row["fields"]: + if field["type"] in FIELD_TYPES_FOR_HISTOGRAM: + fields[field["name"]] = field + return fields + + +def _update_data_for_histogram(data: dict, fields: dict, unit_outputs: dict) -> dict: + for field_name, field in fields.items(): + histogram_name = field["label"] + prev_histogram_value = data.get(histogram_name, {}) + + field_options_to_dict = {o["value"]: o["label"] for o in field["options"]} + + is_multiple = field.get("multiple") is True + + unit_field_result = unit_outputs.get(field_name) + + # Radio + if isinstance(unit_field_result, dict): + unit_field_result = [k for k, v in unit_field_result.items() if v is True] + is_multiple = True + + unit_field_result = unit_field_result if is_multiple else [unit_field_result] + for option_value, option_name in field_options_to_dict.items(): + prev_option_value = prev_histogram_value.get(option_name, 0) + + plus_worker = 1 if option_value in unit_field_result else 0 + prev_histogram_value[option_name] = prev_option_value + plus_worker + + data[histogram_name] = prev_histogram_value + + return data + + +def collect_task_stats(task: Task) -> dict: + data_for_histogram = {} + + data_browser = DataBrowser(db=task.db) + + units: List[Unit] = task.db.find_units(task_id=task.db_id) + for unit in units: + unit_data = _get_unit_data(data_browser, unit) + unit_inputs = unit_data["unit_inputs"] + unit_outputs = unit_data["unit_outputs"] + unit_fields_for_histogram = _get_unit_fields_for_histogram(unit_inputs) + data_for_histogram = _update_data_for_histogram( + data_for_histogram, + unit_fields_for_histogram, + unit_outputs, + ) + + return { + "stats": data_for_histogram, + "task_id": task.db_id, + "task_name": task.task_name, + "workers_count": len(set(([u.worker_id for u in units]))), + } diff --git a/mephisto/review_app/client/package-lock.json b/mephisto/review_app/client/package-lock.json index 81107ce16..9cf63450c 100644 --- a/mephisto/review_app/client/package-lock.json +++ b/mephisto/review_app/client/package-lock.json @@ -5,11 +5,13 @@ "requires": true, "packages": { "": { + "name": "client", "version": "0.1.0", "dependencies": { "@types/react": "^18.2.21", "@types/react-dom": "^18.2.7", "bootstrap": "^5.3.1", + "d3": "^7.9.0", "lodash": "^4.17.21", "mephisto-task": "^2.0.4", "moment": "^2.29.4", @@ -6147,6 +6149,384 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, + "node_modules/d3": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", + "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", + "dependencies": { + "d3-array": "3", + "d3-axis": "3", + "d3-brush": "3", + "d3-chord": "3", + "d3-color": "3", + "d3-contour": "4", + "d3-delaunay": "6", + "d3-dispatch": "3", + "d3-drag": "3", + "d3-dsv": "3", + "d3-ease": "3", + "d3-fetch": "3", + "d3-force": "3", + "d3-format": "3", + "d3-geo": "3", + "d3-hierarchy": "3", + "d3-interpolate": "3", + "d3-path": "3", + "d3-polygon": "3", + "d3-quadtree": "3", + "d3-random": "3", + "d3-scale": "4", + "d3-scale-chromatic": "3", + "d3-selection": "3", + "d3-shape": "3", + "d3-time": "3", + "d3-time-format": "4", + "d3-timer": "3", + "d3-transition": "3", + "d3-zoom": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-axis": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", + "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-brush": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", + "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "3", + "d3-transition": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-chord": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", + "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", + "dependencies": { + "d3-path": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-contour": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", + "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", + "dependencies": { + "d3-array": "^3.2.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "dependencies": { + "delaunator": "5" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "dependencies": { + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" + }, + "bin": { + "csv2json": "bin/dsv2json.js", + "csv2tsv": "bin/dsv2dsv.js", + "dsv2dsv": "bin/dsv2dsv.js", + "dsv2json": "bin/dsv2json.js", + "json2csv": "bin/json2dsv.js", + "json2dsv": "bin/json2dsv.js", + "json2tsv": "bin/json2dsv.js", + "tsv2csv": "bin/dsv2dsv.js", + "tsv2json": "bin/dsv2json.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-fetch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", + "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "dependencies": { + "d3-dsv": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-force": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", + "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-quadtree": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-geo": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", + "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", + "dependencies": { + "d3-array": "2.5.0 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-hierarchy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-polygon": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", + "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-quadtree": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", + "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-random": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", + "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", + "dependencies": { + "d3-color": "1 - 3", + "d3-interpolate": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "dependencies": { + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" + } + }, + "node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -6255,6 +6635,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delaunator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", + "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", + "dependencies": { + "robust-predicates": "^3.0.2" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -8814,6 +9202,14 @@ "node": ">= 0.4" } }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "engines": { + "node": ">=12" + } + }, "node_modules/invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", @@ -14755,6 +15151,11 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/robust-predicates": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", + "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==" + }, "node_modules/rollup": { "version": "2.79.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", @@ -14846,6 +15247,11 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" + }, "node_modules/safe-array-concat": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.0.tgz", @@ -18128,7 +18534,8 @@ "@babel/plugin-proposal-private-property-in-object": { "version": "7.21.0-placeholder-for-preset-env.2", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", - "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==" + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "requires": {} }, "@babel/plugin-syntax-async-generators": { "version": "7.8.4", @@ -19835,7 +20242,8 @@ "uncontrollable": { "version": "8.0.4", "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.4.tgz", - "integrity": "sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ==" + "integrity": "sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ==", + "requires": {} } } }, @@ -20701,12 +21109,14 @@ "acorn-import-assertions": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==" + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "requires": {} }, "acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==" + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "requires": {} }, "acorn-walk": { "version": "7.2.0", @@ -20749,7 +21159,8 @@ "ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "requires": {} }, "ansi-escapes": { "version": "4.3.2", @@ -21156,7 +21567,8 @@ "babel-plugin-named-asset-import": { "version": "0.3.8", "resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.8.tgz", - "integrity": "sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q==" + "integrity": "sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q==", + "requires": {} }, "babel-plugin-polyfill-corejs2": { "version": "0.4.8", @@ -21349,7 +21761,8 @@ "bootstrap": { "version": "5.3.3", "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.3.tgz", - "integrity": "sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg==" + "integrity": "sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg==", + "requires": {} }, "bowser": { "version": "2.11.0", @@ -21768,12 +22181,14 @@ "css-blank-pseudo": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-2.0.0.tgz", - "integrity": "sha512-n7fxEOyuvAVPLPb9kL4XTIK/gnp2fKQ7KFQ+9lj60W9pDn/jTr5LjS/kHHm+rES/YJ3m0S6+uJgYSuAJg9zOyA==" + "integrity": "sha512-n7fxEOyuvAVPLPb9kL4XTIK/gnp2fKQ7KFQ+9lj60W9pDn/jTr5LjS/kHHm+rES/YJ3m0S6+uJgYSuAJg9zOyA==", + "requires": {} }, "css-declaration-sorter": { "version": "6.4.1", "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz", - "integrity": "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==" + "integrity": "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==", + "requires": {} }, "css-has-pseudo": { "version": "2.0.0", @@ -21864,7 +22279,8 @@ "css-prefers-color-scheme": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-5.0.0.tgz", - "integrity": "sha512-XpzVrdwbppHm+Nnrzcb/hQb8eq1aKv4U8Oh59LsLfTsbIZZ6Fvn9razb66ihH2aTJ0VhO9n9sVm8piyKXJAZMA==" + "integrity": "sha512-XpzVrdwbppHm+Nnrzcb/hQb8eq1aKv4U8Oh59LsLfTsbIZZ6Fvn9razb66ihH2aTJ0VhO9n9sVm8piyKXJAZMA==", + "requires": {} }, "css-select": { "version": "4.3.0", @@ -21963,7 +22379,8 @@ "cssnano-utils": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", - "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==" + "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", + "requires": {} }, "csso": { "version": "4.2.0", @@ -22019,6 +22436,276 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, + "d3": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", + "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", + "requires": { + "d3-array": "3", + "d3-axis": "3", + "d3-brush": "3", + "d3-chord": "3", + "d3-color": "3", + "d3-contour": "4", + "d3-delaunay": "6", + "d3-dispatch": "3", + "d3-drag": "3", + "d3-dsv": "3", + "d3-ease": "3", + "d3-fetch": "3", + "d3-force": "3", + "d3-format": "3", + "d3-geo": "3", + "d3-hierarchy": "3", + "d3-interpolate": "3", + "d3-path": "3", + "d3-polygon": "3", + "d3-quadtree": "3", + "d3-random": "3", + "d3-scale": "4", + "d3-scale-chromatic": "3", + "d3-selection": "3", + "d3-shape": "3", + "d3-time": "3", + "d3-time-format": "4", + "d3-timer": "3", + "d3-transition": "3", + "d3-zoom": "3" + } + }, + "d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "requires": { + "internmap": "1 - 2" + } + }, + "d3-axis": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", + "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==" + }, + "d3-brush": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", + "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", + "requires": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "3", + "d3-transition": "3" + } + }, + "d3-chord": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", + "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", + "requires": { + "d3-path": "1 - 3" + } + }, + "d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==" + }, + "d3-contour": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", + "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", + "requires": { + "d3-array": "^3.2.0" + } + }, + "d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "requires": { + "delaunator": "5" + } + }, + "d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==" + }, + "d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "requires": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + } + }, + "d3-dsv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "requires": { + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" + }, + "dependencies": { + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" + } + } + }, + "d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==" + }, + "d3-fetch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", + "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "requires": { + "d3-dsv": "1 - 3" + } + }, + "d3-force": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", + "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", + "requires": { + "d3-dispatch": "1 - 3", + "d3-quadtree": "1 - 3", + "d3-timer": "1 - 3" + } + }, + "d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==" + }, + "d3-geo": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", + "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", + "requires": { + "d3-array": "2.5.0 - 3" + } + }, + "d3-hierarchy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==" + }, + "d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "requires": { + "d3-color": "1 - 3" + } + }, + "d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==" + }, + "d3-polygon": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", + "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==" + }, + "d3-quadtree": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", + "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==" + }, + "d3-random": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", + "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==" + }, + "d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "requires": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + } + }, + "d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", + "requires": { + "d3-color": "1 - 3", + "d3-interpolate": "1 - 3" + } + }, + "d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==" + }, + "d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "requires": { + "d3-path": "^3.1.0" + } + }, + "d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "requires": { + "d3-array": "2 - 3" + } + }, + "d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "requires": { + "d3-time": "1 - 3" + } + }, + "d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==" + }, + "d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "requires": { + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" + } + }, + "d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "requires": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + } + }, "damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -22095,6 +22782,14 @@ "object-keys": "^1.1.1" } }, + "delaunator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", + "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", + "requires": { + "robust-predicates": "^3.0.2" + } + }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -22817,7 +23512,8 @@ "eslint-plugin-react-hooks": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", - "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==" + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "requires": {} }, "eslint-plugin-testing-library": { "version": "5.11.1", @@ -23854,7 +24550,8 @@ "icss-utils": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==" + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "requires": {} }, "idb": { "version": "7.1.1", @@ -23931,6 +24628,11 @@ "side-channel": "^1.0.4" } }, + "internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==" + }, "invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", @@ -24986,7 +25688,8 @@ "jest-pnp-resolver": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", - "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==" + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "requires": {} }, "jest-regex-util": { "version": "27.5.1", @@ -26758,7 +27461,8 @@ "postcss-browser-comments": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/postcss-browser-comments/-/postcss-browser-comments-4.0.0.tgz", - "integrity": "sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg==" + "integrity": "sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg==", + "requires": {} }, "postcss-calc": { "version": "8.2.4", @@ -26816,7 +27520,8 @@ "postcss-custom-media": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-8.0.0.tgz", - "integrity": "sha512-FvO2GzMUaTN0t1fBULDeIvxr5IvbDXcIatt6pnJghc736nqNgsGao5NT+5+WVLAQiTt6Cb3YUms0jiPaXhL//g==" + "integrity": "sha512-FvO2GzMUaTN0t1fBULDeIvxr5IvbDXcIatt6pnJghc736nqNgsGao5NT+5+WVLAQiTt6Cb3YUms0jiPaXhL//g==", + "requires": {} }, "postcss-custom-properties": { "version": "12.0.0", @@ -26856,22 +27561,26 @@ "postcss-discard-comments": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", - "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==" + "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", + "requires": {} }, "postcss-discard-duplicates": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", - "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==" + "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", + "requires": {} }, "postcss-discard-empty": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", - "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==" + "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", + "requires": {} }, "postcss-discard-overridden": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", - "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==" + "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", + "requires": {} }, "postcss-double-position-gradients": { "version": "3.0.1", @@ -26892,27 +27601,32 @@ "postcss-flexbugs-fixes": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz", - "integrity": "sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==" + "integrity": "sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==", + "requires": {} }, "postcss-focus-visible": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-6.0.1.tgz", - "integrity": "sha512-UddLlBmJ78Nu7OrKME70EKxCPBdxTx7pKIyD3GDNRM8Tnq19zmscT9QzsvR8gygz0i0nNUjMtSz4N3AEWZ5R/Q==" + "integrity": "sha512-UddLlBmJ78Nu7OrKME70EKxCPBdxTx7pKIyD3GDNRM8Tnq19zmscT9QzsvR8gygz0i0nNUjMtSz4N3AEWZ5R/Q==", + "requires": {} }, "postcss-focus-within": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-5.0.1.tgz", - "integrity": "sha512-50v1AZVlFSVzLTNdBQG521Aa54VABf/X1RkhR8Fm/9dDQby0W0XdwOnuo8Juvf0ZZXbKkxyTkyyQD0QaNVZVGg==" + "integrity": "sha512-50v1AZVlFSVzLTNdBQG521Aa54VABf/X1RkhR8Fm/9dDQby0W0XdwOnuo8Juvf0ZZXbKkxyTkyyQD0QaNVZVGg==", + "requires": {} }, "postcss-font-variant": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz", - "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==" + "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==", + "requires": {} }, "postcss-gap-properties": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.0.tgz", - "integrity": "sha512-QJOkz1epC/iCuOdhQPm3n9T+F25+P+MYJEEcs5xz/Q+020mc9c6ZRGJkzPJd8FS9hFmT9eEKFEx9PEDl+lH5og==" + "integrity": "sha512-QJOkz1epC/iCuOdhQPm3n9T+F25+P+MYJEEcs5xz/Q+020mc9c6ZRGJkzPJd8FS9hFmT9eEKFEx9PEDl+lH5og==", + "requires": {} }, "postcss-image-set-function": { "version": "4.0.2", @@ -26935,7 +27649,8 @@ "postcss-initial": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-4.0.1.tgz", - "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==" + "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==", + "requires": {} }, "postcss-js": { "version": "4.0.1", @@ -26988,12 +27703,14 @@ "postcss-logical": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.0.tgz", - "integrity": "sha512-fWEWMn/xf6F9SMzAD7OS0GTm8Qh1BlBmEbVT/YZGYhwipQEwOpO7YOOu+qnzLksDg9JjLRj5tLmeN8OW8+ogIA==" + "integrity": "sha512-fWEWMn/xf6F9SMzAD7OS0GTm8Qh1BlBmEbVT/YZGYhwipQEwOpO7YOOu+qnzLksDg9JjLRj5tLmeN8OW8+ogIA==", + "requires": {} }, "postcss-media-minmax": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz", - "integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==" + "integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==", + "requires": {} }, "postcss-merge-longhand": { "version": "5.1.7", @@ -27054,7 +27771,8 @@ "postcss-modules-extract-imports": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", - "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==" + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "requires": {} }, "postcss-modules-local-by-default": { "version": "4.0.4", @@ -27122,7 +27840,8 @@ "postcss-normalize-charset": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", - "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==" + "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", + "requires": {} }, "postcss-normalize-display-values": { "version": "5.1.0", @@ -27202,12 +27921,14 @@ "postcss-overflow-shorthand": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.0.tgz", - "integrity": "sha512-4fTapLT68wUoIr4m3Z0sKn1NbXX0lJYvj4aDA2++KpNx8wMSVf55UuLPz0nSjXa7dV1p0xQHlJ0iFJRNrSY2mw==" + "integrity": "sha512-4fTapLT68wUoIr4m3Z0sKn1NbXX0lJYvj4aDA2++KpNx8wMSVf55UuLPz0nSjXa7dV1p0xQHlJ0iFJRNrSY2mw==", + "requires": {} }, "postcss-page-break": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz", - "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==" + "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==", + "requires": {} }, "postcss-place": { "version": "7.0.1", @@ -27286,7 +28007,8 @@ "postcss-replace-overflow-wrap": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz", - "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==" + "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==", + "requires": {} }, "postcss-selector-not": { "version": "5.0.0", @@ -28066,6 +28788,11 @@ "glob": "^7.1.3" } }, + "robust-predicates": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", + "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==" + }, "rollup": { "version": "2.79.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", @@ -28126,6 +28853,11 @@ "queue-microtask": "^1.2.2" } }, + "rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" + }, "safe-array-concat": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.0.tgz", @@ -28768,7 +29500,8 @@ "style-loader": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.4.tgz", - "integrity": "sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==" + "integrity": "sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==", + "requires": {} }, "stylehacks": { "version": "5.1.1", @@ -29702,7 +30435,8 @@ "ws": { "version": "8.16.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", - "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==" + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "requires": {} } } }, @@ -30211,7 +30945,8 @@ "ws": { "version": "7.5.9", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==" + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "requires": {} }, "xml-name-validator": { "version": "3.0.0", diff --git a/mephisto/review_app/client/package.json b/mephisto/review_app/client/package.json index 2aa82a67a..cf0c54d7d 100644 --- a/mephisto/review_app/client/package.json +++ b/mephisto/review_app/client/package.json @@ -6,6 +6,7 @@ "@types/react": "^18.2.21", "@types/react-dom": "^18.2.7", "bootstrap": "^5.3.1", + "d3": "^7.9.0", "lodash": "^4.17.21", "mephisto-task": "^2.0.4", "moment": "^2.29.4", diff --git a/mephisto/review_app/client/src/App/App.tsx b/mephisto/review_app/client/src/App/App.tsx index 0cbe77ad3..b59635e3d 100644 --- a/mephisto/review_app/client/src/App/App.tsx +++ b/mephisto/review_app/client/src/App/App.tsx @@ -10,6 +10,7 @@ import Errors from "components/Errors/Errors"; import HomePage from "pages/HomePage/HomePage"; import TaskPage from "pages/TaskPage/TaskPage"; import TasksPage from "pages/TasksPage/TasksPage"; +import TaskStatsPage from "pages/TaskStatsPage/TaskStatsPage"; import * as React from "react"; import { Route, Routes } from "react-router-dom"; import urls from "urls"; @@ -29,6 +30,10 @@ function App() { path={urls.client.task(":id")} element={} /> + } + /> } diff --git a/mephisto/review_app/client/src/pages/TaskPage/ModalForm/ModalForm.tsx b/mephisto/review_app/client/src/pages/TaskPage/ModalForm/ModalForm.tsx index 65f2c433f..649bbb9ae 100644 --- a/mephisto/review_app/client/src/pages/TaskPage/ModalForm/ModalForm.tsx +++ b/mephisto/review_app/client/src/pages/TaskPage/ModalForm/ModalForm.tsx @@ -58,8 +58,7 @@ function ModalForm(props: ModalFormProps) { } else { prevFormData.qualification = value; - const prevGrantedQualification = - workerGrantedQualifications[value]; + const prevGrantedQualification = workerGrantedQualifications[value]; const prevGrantedQualificationValue = prevGrantedQualification?.value; if (prevGrantedQualificationValue !== undefined) { // Set to previous granted value for selected qualification diff --git a/mephisto/review_app/client/src/pages/TaskPage/TaskPage.tsx b/mephisto/review_app/client/src/pages/TaskPage/TaskPage.tsx index 9188f8624..0d633cf6a 100644 --- a/mephisto/review_app/client/src/pages/TaskPage/TaskPage.tsx +++ b/mephisto/review_app/client/src/pages/TaskPage/TaskPage.tsx @@ -347,9 +347,7 @@ function TaskPage(props: PropsType) { setLoading, onError, { - bonus: modalData.form.checkboxGiveBonus - ? modalData.form.bonus - : null, + bonus: modalData.form.checkboxGiveBonus ? modalData.form.bonus : null, review_note: modalData.form.checkboxReviewNote ? modalData.form.reviewNote : null, diff --git a/mephisto/review_app/client/src/pages/TaskStatsPage/Histogram.tsx b/mephisto/review_app/client/src/pages/TaskStatsPage/Histogram.tsx new file mode 100644 index 000000000..775042c0d --- /dev/null +++ b/mephisto/review_app/client/src/pages/TaskStatsPage/Histogram.tsx @@ -0,0 +1,116 @@ +import { useEffect, useRef } from "react"; +import * as React from "react"; +import { + ScaleBand, + ScaleLinear, + axisBottom, + axisLeft, + format, + scaleBand, + scaleLinear, + select, +} from "d3"; + +interface HistogramPropsType { + data: HistogramData[]; + height: number; + width: number; +} + +interface AxisBottomPropsType { + scale: ScaleBand; + transform: string; +} + +interface AxisLeftPropsType { + maxValue: number; + scale: ScaleLinear; +} + +interface BarsPropsType { + data: HistogramPropsType["data"]; + height: number; + scaleX: AxisBottomPropsType["scale"]; + scaleY: AxisLeftPropsType["scale"]; +} + +function truncateLabel(str, n) { + return str.length > n ? str.slice(0, n - 1) + "..." : str; +} + +function AxisBottom(props: AxisBottomPropsType) { + const { scale, transform } = props; + const ref = useRef(null); + + useEffect(() => { + if (ref.current) { + select(ref.current).call(axisBottom(scale)); + } + }, [scale]); + + return ; +} + +function AxisLeft(props: AxisLeftPropsType) { + const { maxValue, scale } = props; + const ref = useRef(null); + + const tickValues = Array.from({ length: maxValue + 1 }, (v, i) => i); + + useEffect(() => { + if (ref.current) { + select(ref.current).call( + axisLeft(scale).tickValues(tickValues).tickFormat(format("d")) + ); + } + }, [scale]); + + return ; +} + +function Bars(props: BarsPropsType) { + const { data, height, scaleX, scaleY } = props; + + return ( + <> + {data.map(({ value, label }) => ( + + ))} + + ); +} + +export function Histogram(props: HistogramPropsType) { + const { data, height, width } = props; + const margin = { top: 20, right: 0, bottom: 20, left: 40 }; + const _width = width - margin.left - margin.right; + const _height = height - margin.top - margin.bottom; + + const scaleX = scaleBand() + .domain(data.map(({ label }) => truncateLabel(label, 25))) + .range([0, _width]) + .padding(0.5); + + const maxScaleYValue = Math.max(...data.map(({ value }) => value)); + const scaleY = scaleLinear().domain([0, maxScaleYValue]).range([_height, 0]); + + return ( + + + + + + + + ); +} diff --git a/mephisto/review_app/client/src/pages/TaskStatsPage/TaskStatsPage.css b/mephisto/review_app/client/src/pages/TaskStatsPage/TaskStatsPage.css new file mode 100644 index 000000000..08390bf57 --- /dev/null +++ b/mephisto/review_app/client/src/pages/TaskStatsPage/TaskStatsPage.css @@ -0,0 +1,64 @@ +/* + * Copyright (c) Meta Platforms and its affiliates. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.task-stats { + box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + display: flex; + flex-direction: column; +} + +.task-stats .header { + padding: 10px 20px; + background-color: #ecdadf; +} + +.task-stats .header .task-name { + font-size: 25px; +} + +.task-stats .header .task-info { + display: flex; + flex-direction: row; + gap: 25px; +} + +.task-stats .header .task-info span { + font-size: 15px; + color: grey; +} + +.task-stats .content { + padding: 10px 20px; +} + +.task-stats .content .explanation { + font-size: 19px; + color: #888888; + font-style: italic; + margin-bottom: 20px; + padding-left: 20px; + line-height: 1.2; +} + +.task-stats .content .stats .field-stats { + padding-bottom: 40px; +} + +.task-stats .content .stats .field-stats .histogram-name { + font-size: 32px; + padding-left: 20px; + padding-bottom: 20px; +} + +.task-stats .loading { + width: 100%; + height: 100px; + display: flex; + align-items: center; + justify-content: center; +} diff --git a/mephisto/review_app/client/src/pages/TaskStatsPage/TaskStatsPage.tsx b/mephisto/review_app/client/src/pages/TaskStatsPage/TaskStatsPage.tsx new file mode 100644 index 000000000..c138ed20a --- /dev/null +++ b/mephisto/review_app/client/src/pages/TaskStatsPage/TaskStatsPage.tsx @@ -0,0 +1,145 @@ +/* + * Copyright (c) Meta Platforms and its affiliates. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { setPageTitle } from "pages/TaskPage/helpers"; +import * as React from "react"; +import { useEffect } from "react"; +import { Spinner } from "react-bootstrap"; +import { useParams } from "react-router-dom"; +import { getTaskStats } from "requests/tasks"; +import TasksHeader from "../TasksPage/TasksHeader/TasksHeader"; +import { Histogram } from "./Histogram"; +import "./TaskStatsPage.css"; + +type ParamsType = { + id: string; +}; + +interface PropsType { + setErrors: Function; +} + +function TaskStatsPage(props: PropsType) { + const params = useParams(); + + const [taskStats, setTaskStats] = React.useState(null); + const [loading, setLoading] = React.useState(false); + + const hasStats = taskStats && Object.keys(taskStats.stats).length != 0; + + function onError(errorResponse: ErrorResponseType | null) { + if (errorResponse) { + props.setErrors((oldErrors) => [...oldErrors, ...[errorResponse.error]]); + } + } + + // Effects + useEffect(() => { + // Set default title + setPageTitle("Mephisto - Task Stats"); + + if (taskStats === null) { + getTaskStats(params.id, setTaskStats, setLoading, onError, null); + } + }, []); + + useEffect(() => { + if (taskStats) { + // Update title with current task name + setPageTitle(`Mephisto - Task Stats - ${taskStats.task_name}`); + } + }, [taskStats]); + + if (taskStats === null) { + return null; + } + + return ( +
+ {/* Header */} + + + {!loading && ( + // Task name +
+
Task: {taskStats.task_name}
+ +
+ Task ID: {taskStats.task_id} + + + Workers count: {taskStats.workers_count} + +
+
+ )} + +
+ {/* Preloader when we request task stats */} + {loading ? ( +
+ + Loading... + +
+ ) : ( + <> +
+ This is response statistics to multi-choice questions. +
+ It is presented in form of histograms counting amount of responses + to each available option. +
+ + {/* Histograms */} + {hasStats ? ( +
+ {Object.entries(taskStats.stats).map( + ([histogramName, data]) => { + if (!Object.values(data).filter(Boolean).length) { + return; + } + + const width = Object.values(data).length > 10 ? 1400 : 700; + const height = 300; + + const histogramData: HistogramData[] = Object.entries( + data + ).map(([key, value]) => { + return { + label: key, + value: value, + }; + }); + + return ( +
+
{histogramName}
+ + +
+ ); + } + )} +
+ ) : ( +
This task has no statistics yet.
+ )} + + )} +
+
+ ); +} + +export default TaskStatsPage; diff --git a/mephisto/review_app/client/src/pages/TasksPage/TasksPage.css b/mephisto/review_app/client/src/pages/TasksPage/TasksPage.css index 882c511a8..2695a91b1 100644 --- a/mephisto/review_app/client/src/pages/TasksPage/TasksPage.css +++ b/mephisto/review_app/client/src/pages/TasksPage/TasksPage.css @@ -32,6 +32,11 @@ text-align: center; } +.tasks .tasks-table .titles-row .stats { + width: 80px; + text-align: center; +} + .tasks .tasks-table .task-row:not(.no-hover) { cursor: pointer; } @@ -67,8 +72,18 @@ text-decoration: underline; } +.tasks .tasks-table .task-row .stats a { + cursor: pointer; + text-decoration: unset; +} + +.tasks .tasks-table .task-row .stats a:hover { + text-decoration: underline; +} + .tasks .tasks-table .task-row .reviewed, .tasks .tasks-table .task-row .units, +.tasks .tasks-table .task-row .stats, .tasks .tasks-table .task-row .date { text-align: center; } diff --git a/mephisto/review_app/client/src/pages/TasksPage/TasksPage.tsx b/mephisto/review_app/client/src/pages/TasksPage/TasksPage.tsx index 448e3c2b0..c6c6c02e1 100644 --- a/mephisto/review_app/client/src/pages/TasksPage/TasksPage.tsx +++ b/mephisto/review_app/client/src/pages/TasksPage/TasksPage.tsx @@ -8,6 +8,7 @@ import * as moment from "moment/moment"; import * as React from "react"; import { useEffect } from "react"; import { Spinner, Table } from "react-bootstrap"; +import { Link } from "react-router-dom"; import { exportTaskResults, getTasks } from "requests/tasks"; import urls from "urls"; import TasksHeader from "./TasksHeader/TasksHeader"; @@ -99,6 +100,9 @@ function TasksPage(props: PropsType) { Date + + Stats + Export results @@ -129,6 +133,11 @@ function TasksPage(props: PropsType) { {task.unit_count} {date} + + + Show + + {task.is_reviewed && !( diff --git a/mephisto/review_app/client/src/requests/tasks.ts b/mephisto/review_app/client/src/requests/tasks.ts index 705a51e1f..e0c9c8e0d 100644 --- a/mephisto/review_app/client/src/requests/tasks.ts +++ b/mephisto/review_app/client/src/requests/tasks.ts @@ -92,3 +92,24 @@ export function exportTaskResults( abortController ); } + +export function getTaskStats( + id: string, + setDataAction: SetRequestDataActionType, + setLoadingAction: SetRequestLoadingActionType, + setErrorsAction: SetRequestErrorsActionType, + abortController?: AbortController +) { + const url = generateURL(urls.server.taskStatsResults, [id], null); + + makeRequest( + "GET", + url, + null, + (data) => setDataAction(data), + setLoadingAction, + setErrorsAction, + "getTaskStats error:", + abortController + ); +} diff --git a/mephisto/review_app/client/src/types/histogram.d.ts b/mephisto/review_app/client/src/types/histogram.d.ts new file mode 100644 index 000000000..ed367fea2 --- /dev/null +++ b/mephisto/review_app/client/src/types/histogram.d.ts @@ -0,0 +1,10 @@ +/* + * Copyright (c) Meta Platforms and its affiliates. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +declare interface HistogramData { + label: string; + value: number; +} diff --git a/mephisto/review_app/client/src/types/tasks.d.ts b/mephisto/review_app/client/src/types/tasks.d.ts index 3c3033d0b..8ff99dabb 100644 --- a/mephisto/review_app/client/src/types/tasks.d.ts +++ b/mephisto/review_app/client/src/types/tasks.d.ts @@ -19,3 +19,10 @@ declare type TaskStatsType = { rejected_count: number; soft_rejected_count: number; }; + +declare type TaskRusultStatsType = { + stats: { [key: string]: { [key: string]: number } }; + task_id: string; + task_name: string; + workers_count: number; +}; diff --git a/mephisto/review_app/client/src/urls.ts b/mephisto/review_app/client/src/urls.ts index 2e1e2d384..f841f907d 100644 --- a/mephisto/review_app/client/src/urls.ts +++ b/mephisto/review_app/client/src/urls.ts @@ -10,6 +10,7 @@ const urls = { client: { home: "/", task: (id) => `/tasks/${id}`, + taskStats: (id) => `/tasks/${id}/stats`, tasks: "/tasks", }, server: { @@ -19,11 +20,12 @@ const urls = { API_URL + `/api/qualifications/${id}/workers/${workerId}/grant`, qualificationRevokeWorker: (id, workerId) => API_URL + `/api/qualifications/${id}/workers/${workerId}/revoke`, - stats: API_URL + "/api/stats", + stats: API_URL + "/api/review-stats", task: (id) => API_URL + `/api/tasks/${id}`, taskExportResults: (id) => API_URL + `/api/tasks/${id}/export-results`, taskExportResultsJson: (id, nUnits) => API_URL + `/api/tasks/${id}/${nUnits}/export-results.json`, + taskStatsResults: (id) => API_URL + `/api/tasks/${id}/stats-results`, tasks: API_URL + "/api/tasks", tasksWorkerUnitsIds: (id) => API_URL + `/api/tasks/${id}/worker-units-ids`, unitReviewHtml: (id) => API_URL + `/api/units/${id}/review.html`, diff --git a/mephisto/review_app/server/api/views/__init__.py b/mephisto/review_app/server/api/views/__init__.py index 6e90ade3c..52d18554a 100644 --- a/mephisto/review_app/server/api/views/__init__.py +++ b/mephisto/review_app/server/api/views/__init__.py @@ -8,9 +8,10 @@ from .qualification_workers_view import QualificationWorkersView from .qualifications_view import QualificationsView from .qualify_worker_view import QualifyWorkerView -from .stats_view import StatsView +from .review_stats_view import ReviewStatsView from .task_export_results_json_view import TaskExportResultsJsonView from .task_export_results_view import TaskExportResultsView +from .task_stats_results_view import TaskStatsResultsView from .task_view import TaskView from .tasks_view import TasksView from .tasks_worker_units_view import TaskUnitIdsView diff --git a/mephisto/review_app/server/api/views/stats_view.py b/mephisto/review_app/server/api/views/review_stats_view.py similarity index 99% rename from mephisto/review_app/server/api/views/stats_view.py rename to mephisto/review_app/server/api/views/review_stats_view.py index 1629c6701..9914c8177 100644 --- a/mephisto/review_app/server/api/views/stats_view.py +++ b/mephisto/review_app/server/api/views/review_stats_view.py @@ -143,7 +143,7 @@ def _find_units_for_worker( return results -class StatsView(MethodView): +class ReviewStatsView(MethodView): def get(self) -> dict: """Get stats of recent approvals for the worker or task""" diff --git a/mephisto/review_app/server/api/views/task_export_results_view.py b/mephisto/review_app/server/api/views/task_export_results_view.py index 51bb0fd2e..36b75d1e3 100644 --- a/mephisto/review_app/server/api/views/task_export_results_view.py +++ b/mephisto/review_app/server/api/views/task_export_results_view.py @@ -68,4 +68,6 @@ def get(self, task_id: str = None) -> dict: with open(results_file_path, "w") as f: f.write(json.dumps(task_units_data, indent=4)) - return {"file_created": True} + return { + "file_created": True, + } diff --git a/mephisto/review_app/server/api/views/task_stats_results_view.py b/mephisto/review_app/server/api/views/task_stats_results_view.py new file mode 100644 index 000000000..c4e07faa8 --- /dev/null +++ b/mephisto/review_app/server/api/views/task_stats_results_view.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 + +# Copyright (c) Meta Platforms and its affiliates. +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +from typing import List + +from flask import current_app as app +from flask.views import MethodView +from omegaconf import DictConfig +from werkzeug.exceptions import BadRequest + +from mephisto.data_model.task import Task +from mephisto.data_model.task_run import TaskRun + + +class TaskStatsResultsView(MethodView): + def get(self, task_id: str = None) -> dict: + """Assemble stats with results for Task""" + + task: Task = Task.get(db=app.db, db_id=task_id) + app.logger.debug(f"Found Task in DB: {task}") + + task_runs: List[TaskRun] = task.get_runs() + + if not task_runs: + raise BadRequest("This task has never been launched before.") + + last_task_run: TaskRun = task_runs[-1] + last_task_run_config: DictConfig = last_task_run.get_task_args() + + collect_task_stats_func = None + if "form-composer" in last_task_run_config.task_tags: + from mephisto.generators.form_composer.stats import collect_task_stats + + collect_task_stats_func = collect_task_stats + else: + raise BadRequest("Statistics for tasks of this type are not yet supported.") + + stats = collect_task_stats_func(task) + + return stats diff --git a/mephisto/review_app/server/urls.py b/mephisto/review_app/server/urls.py index 1658f3d53..9e79ebd11 100644 --- a/mephisto/review_app/server/urls.py +++ b/mephisto/review_app/server/urls.py @@ -54,6 +54,10 @@ def init_urls(app: Flask): "/api/tasks///export-results.json", view_func=api_views.TaskExportResultsJsonView.as_view("task_export_results_json"), ) + app.add_url_rule( + "/api/tasks//stats-results", + view_func=api_views.TaskStatsResultsView.as_view("task_stats_results"), + ) app.add_url_rule( "/api/units", view_func=api_views.UnitsView.as_view("units"), @@ -93,8 +97,8 @@ def init_urls(app: Flask): ), ) app.add_url_rule( - "/api/stats", - view_func=api_views.StatsView.as_view("stats"), + "/api/review-stats", + view_func=api_views.ReviewStatsView.as_view("review-stats"), ) app.add_url_rule( "/", diff --git a/packages/mephisto-task-multipart/package-lock.json b/packages/mephisto-task-multipart/package-lock.json index f4037165c..5b549fefe 100644 --- a/packages/mephisto-task-multipart/package-lock.json +++ b/packages/mephisto-task-multipart/package-lock.json @@ -47,7 +47,6 @@ "version": "1.2.6", "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -2096,7 +2095,6 @@ "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, "dependencies": { "eslint-visitor-keys": "^3.3.0" }, @@ -2111,7 +2109,6 @@ "version": "4.10.0", "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", - "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } @@ -2120,7 +2117,6 @@ "version": "2.1.4", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -2143,7 +2139,6 @@ "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, "dependencies": { "type-fest": "^0.20.2" }, @@ -2158,7 +2153,6 @@ "version": "8.57.0", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } @@ -2167,7 +2161,6 @@ "version": "0.11.14", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^2.0.2", "debug": "^4.3.1", @@ -2181,7 +2174,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, "engines": { "node": ">=12.22" }, @@ -2193,8 +2185,7 @@ "node_modules/@humanwhocodes/object-schema": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", - "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", - "dev": true + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==" }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", @@ -2269,7 +2260,6 @@ "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -2282,7 +2272,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, "engines": { "node": ">= 8" } @@ -2291,7 +2280,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -2715,8 +2703,7 @@ "node_modules/@ungap/structured-clone": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" }, "node_modules/@webassemblyjs/ast": { "version": "1.11.6", @@ -2916,7 +2903,6 @@ "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "dev": true, "bin": { "acorn": "bin/acorn" }, @@ -2937,7 +2923,6 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -2946,7 +2931,6 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -2971,7 +2955,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "engines": { "node": ">=8" } @@ -3004,8 +2987,7 @@ "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "node_modules/aria-query": { "version": "5.3.0", @@ -3428,8 +3410,7 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/big.js": { "version": "5.2.2", @@ -3459,7 +3440,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3538,7 +3518,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, "engines": { "node": ">=6" } @@ -3672,8 +3651,7 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "node_modules/confusing-browser-globals": { "version": "1.0.11", @@ -3720,7 +3698,6 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -3835,8 +3812,7 @@ "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" }, "node_modules/define-data-property": { "version": "1.1.4", @@ -3905,7 +3881,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, "dependencies": { "esutils": "^2.0.2" }, @@ -4143,7 +4118,6 @@ "version": "8.57.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", - "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -4507,7 +4481,6 @@ "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -4519,7 +4492,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -4534,7 +4506,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -4550,7 +4521,6 @@ "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, "dependencies": { "color-name": "~1.1.4" }, @@ -4561,14 +4531,12 @@ "node_modules/eslint/node_modules/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 + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/eslint/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, "engines": { "node": ">=10" }, @@ -4580,7 +4548,6 @@ "version": "7.2.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -4596,7 +4563,6 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, "dependencies": { "is-glob": "^4.0.3" }, @@ -4608,7 +4574,6 @@ "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, "dependencies": { "type-fest": "^0.20.2" }, @@ -4623,7 +4588,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, "engines": { "node": ">=8" } @@ -4632,7 +4596,6 @@ "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, "dependencies": { "has-flag": "^4.0.0" }, @@ -4644,7 +4607,6 @@ "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", @@ -4661,7 +4623,6 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, "dependencies": { "estraverse": "^5.1.0" }, @@ -4673,7 +4634,6 @@ "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, "dependencies": { "estraverse": "^5.2.0" }, @@ -4685,7 +4645,6 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, "engines": { "node": ">=4.0" } @@ -4694,7 +4653,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -4711,8 +4669,7 @@ "node_modules/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 + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-glob": { "version": "3.3.2", @@ -4733,14 +4690,12 @@ "node_modules/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 + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" }, "node_modules/fastest-levenshtein": { "version": "1.0.16", @@ -4755,7 +4710,6 @@ "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, "dependencies": { "reusify": "^1.0.4" } @@ -4764,7 +4718,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, "dependencies": { "flat-cache": "^3.0.4" }, @@ -4820,7 +4773,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -4845,7 +4797,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.3", @@ -4858,8 +4809,7 @@ "node_modules/flatted": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==" }, "node_modules/follow-redirects": { "version": "1.15.6", @@ -4911,8 +4861,7 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "node_modules/fsevents": { "version": "2.3.3", @@ -5012,7 +4961,6 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -5119,8 +5067,7 @@ "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" }, "node_modules/has-bigints": { "version": "1.0.2", @@ -5217,7 +5164,6 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "dev": true, "engines": { "node": ">= 4" } @@ -5226,7 +5172,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -5261,7 +5206,6 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, "engines": { "node": ">=0.8.19" } @@ -5270,7 +5214,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -5279,8 +5222,7 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/internal-slot": { "version": "1.0.7", @@ -5425,7 +5367,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -5461,7 +5402,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -5518,7 +5458,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, "engines": { "node": ">=8" } @@ -5663,8 +5602,7 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/isobject": { "version": "3.0.1", @@ -5735,7 +5673,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, "dependencies": { "argparse": "^2.0.1" }, @@ -5757,8 +5694,7 @@ "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", @@ -5769,14 +5705,12 @@ "node_modules/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 + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, "node_modules/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": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" }, "node_modules/json5": { "version": "2.2.3", @@ -5809,7 +5743,6 @@ "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, "dependencies": { "json-buffer": "3.0.1" } @@ -5845,7 +5778,6 @@ "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, "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -5887,7 +5819,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, "dependencies": { "p-locate": "^5.0.0" }, @@ -5913,8 +5844,7 @@ "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" }, "node_modules/loose-envify": { "version": "1.4.0", @@ -6010,7 +5940,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -6053,8 +5982,7 @@ "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" }, "node_modules/natural-compare-lite": { "version": "1.4.0", @@ -6207,7 +6135,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, "dependencies": { "wrappy": "1" } @@ -6216,7 +6143,6 @@ "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", - "dev": true, "dependencies": { "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", @@ -6233,7 +6159,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, "dependencies": { "yocto-queue": "^0.1.0" }, @@ -6248,7 +6173,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, "dependencies": { "p-limit": "^3.0.2" }, @@ -6272,7 +6196,6 @@ "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, "dependencies": { "callsites": "^3.0.0" }, @@ -6302,7 +6225,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, "engines": { "node": ">=8" } @@ -6311,7 +6233,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -6320,7 +6241,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "engines": { "node": ">=8" } @@ -6549,7 +6469,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, "engines": { "node": ">= 0.8.0" } @@ -6574,7 +6493,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, "engines": { "node": ">=6" } @@ -6583,7 +6501,6 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, "funding": [ { "type": "github", @@ -6824,7 +6741,6 @@ "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, "engines": { "node": ">=4" } @@ -6833,7 +6749,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -6843,7 +6758,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, "dependencies": { "glob": "^7.1.3" }, @@ -6858,7 +6772,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, "funding": [ { "type": "github", @@ -7025,7 +6938,6 @@ "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, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -7037,7 +6949,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, "engines": { "node": ">=8" } @@ -7172,7 +7083,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -7193,7 +7103,6 @@ "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, "engines": { "node": ">=8" }, @@ -7327,8 +7236,7 @@ "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" }, "node_modules/to-fast-properties": { "version": "2.0.0", @@ -7399,7 +7307,6 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, "dependencies": { "prelude-ls": "^1.2.1" }, @@ -7411,7 +7318,6 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, "engines": { "node": ">=10" }, @@ -7492,6 +7398,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/typescript": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", + "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", + "dev": true, + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -7587,7 +7507,6 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, "dependencies": { "punycode": "^2.1.0" } @@ -7804,7 +7723,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -7900,8 +7818,7 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/yallist": { "version": "3.1.1", @@ -7922,7 +7839,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, "engines": { "node": ">=10" }, @@ -7935,8 +7851,7 @@ "@aashutoshrathi/word-wrap": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==" }, "@ampproject/remapping": { "version": "2.3.0", @@ -8370,7 +8285,8 @@ "version": "7.21.0-placeholder-for-preset-env.2", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", - "dev": true + "dev": true, + "requires": {} }, "@babel/plugin-syntax-async-generators": { "version": "7.8.4", @@ -9320,7 +9236,6 @@ "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, "requires": { "eslint-visitor-keys": "^3.3.0" } @@ -9328,14 +9243,12 @@ "@eslint-community/regexpp": { "version": "4.10.0", "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", - "dev": true + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==" }, "@eslint/eslintrc": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -9352,7 +9265,6 @@ "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, "requires": { "type-fest": "^0.20.2" } @@ -9362,14 +9274,12 @@ "@eslint/js": { "version": "8.57.0", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "dev": true + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==" }, "@humanwhocodes/config-array": { "version": "0.11.14", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "dev": true, "requires": { "@humanwhocodes/object-schema": "^2.0.2", "debug": "^4.3.1", @@ -9379,14 +9289,12 @@ "@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==" }, "@humanwhocodes/object-schema": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", - "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", - "dev": true + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==" }, "@jridgewell/gen-mapping": { "version": "0.3.5", @@ -9452,7 +9360,6 @@ "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, "requires": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -9461,14 +9368,12 @@ "@nodelib/fs.stat": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" }, "@nodelib/fs.walk": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, "requires": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -9769,8 +9674,7 @@ "@ungap/structured-clone": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" }, "@webassemblyjs/ast": { "version": "1.11.6", @@ -9922,7 +9826,8 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz", "integrity": "sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==", - "dev": true + "dev": true, + "requires": {} }, "@webpack-cli/info": { "version": "1.5.0", @@ -9937,7 +9842,8 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz", "integrity": "sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==", - "dev": true + "dev": true, + "requires": {} }, "@xtuc/ieee754": { "version": "1.2.0", @@ -9954,26 +9860,25 @@ "acorn": { "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "dev": true + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==" }, "acorn-import-assertions": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", - "dev": true + "dev": true, + "requires": {} }, "acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true + "requires": {} }, "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", @@ -9985,13 +9890,13 @@ "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true + "dev": true, + "requires": {} }, "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" }, "ansi-styles": { "version": "3.2.1", @@ -10015,8 +9920,7 @@ "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "aria-query": { "version": "5.3.0", @@ -10343,8 +10247,7 @@ "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "big.js": { "version": "5.2.2", @@ -10368,7 +10271,6 @@ "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" @@ -10417,8 +10319,7 @@ "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" }, "caniuse-lite": { "version": "1.0.30001596", @@ -10512,8 +10413,7 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "confusing-browser-globals": { "version": "1.0.11", @@ -10553,7 +10453,6 @@ "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", @@ -10625,8 +10524,7 @@ "deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" }, "define-data-property": { "version": "1.1.4", @@ -10674,7 +10572,6 @@ "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" } @@ -10867,7 +10764,6 @@ "version": "8.57.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", - "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -10913,7 +10809,6 @@ "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" } @@ -10922,7 +10817,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -10932,7 +10826,6 @@ "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" } @@ -10940,20 +10833,17 @@ "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 + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" }, "eslint-scope": { "version": "7.2.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, "requires": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -10963,7 +10853,6 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, "requires": { "is-glob": "^4.0.3" } @@ -10972,7 +10861,6 @@ "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, "requires": { "type-fest": "^0.20.2" } @@ -10980,14 +10868,12 @@ "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 + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "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" } @@ -11198,7 +11084,8 @@ "version": "4.6.0", "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", - "dev": true + "dev": true, + "requires": {} }, "eslint-plugin-testing-library": { "version": "5.11.1", @@ -11230,14 +11117,12 @@ "eslint-visitor-keys": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==" }, "espree": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, "requires": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", @@ -11248,7 +11133,6 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, "requires": { "estraverse": "^5.1.0" } @@ -11257,7 +11141,6 @@ "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" } @@ -11265,14 +11148,12 @@ "estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==" }, "esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" }, "events": { "version": "3.3.0", @@ -11283,8 +11164,7 @@ "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 + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "fast-glob": { "version": "3.3.2", @@ -11302,14 +11182,12 @@ "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 + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" }, "fastest-levenshtein": { "version": "1.0.16", @@ -11321,7 +11199,6 @@ "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, "requires": { "reusify": "^1.0.4" } @@ -11330,7 +11207,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, "requires": { "flat-cache": "^3.0.4" } @@ -11370,7 +11246,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, "requires": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -11386,7 +11261,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, "requires": { "flatted": "^3.2.9", "keyv": "^4.5.3", @@ -11396,8 +11270,7 @@ "flatted": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==" }, "follow-redirects": { "version": "1.15.6", @@ -11432,8 +11305,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "fsevents": { "version": "2.3.3", @@ -11499,7 +11371,6 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -11578,8 +11449,7 @@ "graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" }, "has-bigints": { "version": "1.0.2", @@ -11634,19 +11504,18 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "dev": true + "dev": true, + "requires": {} }, "ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "dev": true + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==" }, "import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, "requires": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -11665,14 +11534,12 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==" }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -11681,8 +11548,7 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "internal-slot": { "version": "1.0.7", @@ -11781,8 +11647,7 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" }, "is-finalizationregistry": { "version": "1.0.2", @@ -11806,7 +11671,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, "requires": { "is-extglob": "^2.1.1" } @@ -11841,8 +11705,7 @@ "is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==" }, "is-plain-object": { "version": "2.0.4", @@ -11939,8 +11802,7 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "isobject": { "version": "3.0.1", @@ -11998,7 +11860,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, "requires": { "argparse": "^2.0.1" } @@ -12011,8 +11872,7 @@ "json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" }, "json-parse-even-better-errors": { "version": "2.3.1", @@ -12023,14 +11883,12 @@ "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 + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, "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": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" }, "json5": { "version": "2.2.3", @@ -12054,7 +11912,6 @@ "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, "requires": { "json-buffer": "3.0.1" } @@ -12084,7 +11941,6 @@ "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" @@ -12117,7 +11973,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, "requires": { "p-locate": "^5.0.0" } @@ -12137,8 +11992,7 @@ "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" }, "loose-envify": { "version": "1.4.0", @@ -12215,7 +12069,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -12240,8 +12093,7 @@ "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" }, "natural-compare-lite": { "version": "1.4.0", @@ -12358,7 +12210,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, "requires": { "wrappy": "1" } @@ -12367,7 +12218,6 @@ "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", - "dev": true, "requires": { "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", @@ -12381,7 +12231,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, "requires": { "yocto-queue": "^0.1.0" } @@ -12390,7 +12239,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, "requires": { "p-limit": "^3.0.2" } @@ -12405,7 +12253,6 @@ "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" } @@ -12425,20 +12272,17 @@ "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" }, "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 + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" }, "path-parse": { "version": "1.0.7", @@ -12538,7 +12382,8 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", - "dev": true + "dev": true, + "requires": {} }, "postcss-modules-local-by-default": { "version": "4.0.4", @@ -12588,8 +12433,7 @@ "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 + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" }, "prop-types": { "version": "15.8.1", @@ -12610,14 +12454,12 @@ "punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==" }, "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" }, "randombytes": { "version": "2.1.0", @@ -12796,20 +12638,17 @@ "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 + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" }, "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" }, "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" } @@ -12818,7 +12657,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, "requires": { "queue-microtask": "^1.2.2" } @@ -12926,7 +12764,6 @@ "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" } @@ -12934,8 +12771,7 @@ "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 + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" }, "side-channel": { "version": "1.0.6", @@ -13037,7 +12873,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "requires": { "ansi-regex": "^5.0.1" } @@ -13051,14 +12886,14 @@ "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 + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" }, "style-loader": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.4.tgz", "integrity": "sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==", - "dev": true + "dev": true, + "requires": {} }, "supports-color": { "version": "5.5.0", @@ -13128,8 +12963,7 @@ "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" }, "to-fast-properties": { "version": "2.0.0", @@ -13187,7 +13021,6 @@ "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" } @@ -13195,8 +13028,7 @@ "type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" }, "typed-array-buffer": { "version": "1.0.2", @@ -13250,6 +13082,13 @@ "possible-typed-array-names": "^1.0.0" } }, + "typescript": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", + "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", + "dev": true, + "peer": true + }, "unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -13310,7 +13149,6 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, "requires": { "punycode": "^2.1.0" } @@ -13449,7 +13287,6 @@ "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" } @@ -13521,8 +13358,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "yallist": { "version": "3.1.1", @@ -13539,8 +13375,7 @@ "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" } } } diff --git a/packages/react-form-composer/package-lock.json b/packages/react-form-composer/package-lock.json index 3c722aeaa..0ff7f92d9 100644 --- a/packages/react-form-composer/package-lock.json +++ b/packages/react-form-composer/package-lock.json @@ -5,6 +5,7 @@ "requires": true, "packages": { "": { + "name": "react-form-composer", "version": "1.0.0", "license": "ISC", "dependencies": { From d9078dc16016b650ff3e2e342ea90f9b59be684e Mon Sep 17 00:00:00 2001 From: Paul Abumov Date: Wed, 26 Jun 2024 15:52:39 -0400 Subject: [PATCH 2/3] Improved histograms appearance --- .../guides/how_to_use/review_app/overview.md | 6 + .../review_app/screenshots/task_stats.png | Bin 0 -> 79376 bytes .../how_to_use/review_app/server_api.md | 28 ++- mephisto/generators/form_composer/stats.py | 14 ++ .../src/pages/TaskStatsPage/Histogram.tsx | 220 ++++++++++-------- .../src/pages/TaskStatsPage/TaskStatsPage.css | 9 +- .../src/pages/TaskStatsPage/TaskStatsPage.tsx | 34 ++- .../client/src/pages/TasksPage/TasksPage.tsx | 11 +- .../review_app/client/src/types/tasks.d.ts | 9 +- .../review_app/server/api/views/tasks_view.py | 27 ++- 10 files changed, 236 insertions(+), 122 deletions(-) create mode 100644 docs/web/docs/guides/how_to_use/review_app/screenshots/task_stats.png diff --git a/docs/web/docs/guides/how_to_use/review_app/overview.md b/docs/web/docs/guides/how_to_use/review_app/overview.md index 88a53fdde..a5d036420 100644 --- a/docs/web/docs/guides/how_to_use/review_app/overview.md +++ b/docs/web/docs/guides/how_to_use/review_app/overview.md @@ -63,3 +63,9 @@ _Note that a custom view of Task results is included (at the bottom) only if you ![Submission reject dialog](./screenshots/submission_reject_dialog.png)

+ +### Task statistics + +![Task statistics](./screenshots/task_stats.png) +
+
diff --git a/docs/web/docs/guides/how_to_use/review_app/screenshots/task_stats.png b/docs/web/docs/guides/how_to_use/review_app/screenshots/task_stats.png new file mode 100644 index 0000000000000000000000000000000000000000..b5c0b2365f7876327f5019eea07f493df7abb896 GIT binary patch literal 79376 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 Sf(Rk%E3-vX)>-S9 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 O@J9N_^@?, + "has_stats": , "id": , - "name": , "is_reviewed": , - "unit_count": , - "created_at": + "name": , + "unit_count": }, ... // more tasks ] @@ -90,6 +91,27 @@ Serve a single composed file with reviewed task results (API response is a file --- +### `GET /api/tasks/{id}/{n_units}/stats-results` + +Assemble stats with results for a Task. + +``` +{ + "stats": { + : { + : | , + ... + }, + ... + }, + "task_id": , + "task_name": , + "workers_count": +} +``` + +--- + ### `GET /api/tasks/{id}/worker-units-ids` Get full, unpaginated list of unit IDs within a task (for subsequent client-side grouping by worker_id and `GET /task-units` pagination) diff --git a/mephisto/generators/form_composer/stats.py b/mephisto/generators/form_composer/stats.py index dd22e7f3a..ddb1605b5 100644 --- a/mephisto/generators/form_composer/stats.py +++ b/mephisto/generators/form_composer/stats.py @@ -94,3 +94,17 @@ def collect_task_stats(task: Task) -> dict: "task_name": task.task_name, "workers_count": len(set(([u.worker_id for u in units]))), } + + +def check_task_has_fields_for_stats(task: Task) -> bool: + data_browser = DataBrowser(db=task.db) + + units: List[Unit] = task.db.find_units(task_id=task.db_id) + for unit in units: + unit_data = _get_unit_data(data_browser, unit) + unit_inputs = unit_data["unit_inputs"] + unit_fields_for_histogram = _get_unit_fields_for_histogram(unit_inputs) + if unit_fields_for_histogram: + return True + + return False diff --git a/mephisto/review_app/client/src/pages/TaskStatsPage/Histogram.tsx b/mephisto/review_app/client/src/pages/TaskStatsPage/Histogram.tsx index 775042c0d..08e7d3dac 100644 --- a/mephisto/review_app/client/src/pages/TaskStatsPage/Histogram.tsx +++ b/mephisto/review_app/client/src/pages/TaskStatsPage/Histogram.tsx @@ -1,116 +1,142 @@ -import { useEffect, useRef } from "react"; +import * as d3 from "d3"; import * as React from "react"; -import { - ScaleBand, - ScaleLinear, - axisBottom, - axisLeft, - format, - scaleBand, - scaleLinear, - select, -} from "d3"; +import { useEffect, useMemo } from "react"; -interface HistogramPropsType { - data: HistogramData[]; - height: number; - width: number; -} +const MARGIN = { top: 30, right: 30, bottom: 30, left: 120 }; -interface AxisBottomPropsType { - scale: ScaleBand; - transform: string; -} - -interface AxisLeftPropsType { - maxValue: number; - scale: ScaleLinear; -} +const BAR_PADDING = 0.2; -interface BarsPropsType { - data: HistogramPropsType["data"]; - height: number; - scaleX: AxisBottomPropsType["scale"]; - scaleY: AxisLeftPropsType["scale"]; -} +const TRUNCATE_LABEL_LENGTH = 20; -function truncateLabel(str, n) { - return str.length > n ? str.slice(0, n - 1) + "..." : str; +function truncateLabel(text: string, n: number): string { + return text.length > n ? text.slice(0, n - 1) + "..." : text; } -function AxisBottom(props: AxisBottomPropsType) { - const { scale, transform } = props; - const ref = useRef(null); - - useEffect(() => { - if (ref.current) { - select(ref.current).call(axisBottom(scale)); - } - }, [scale]); - - return ; +interface HistogramPropsType { + className?: string; + data: HistogramData[]; + width: number; } -function AxisLeft(props: AxisLeftPropsType) { - const { maxValue, scale } = props; - const ref = useRef(null); - - const tickValues = Array.from({ length: maxValue + 1 }, (v, i) => i); - - useEffect(() => { - if (ref.current) { - select(ref.current).call( - axisLeft(scale).tickValues(tickValues).tickFormat(format("d")) - ); +export function Histogram(props: HistogramPropsType) { + const { className, width, data } = props; + + // bounds = area inside the graph axis = calculated by substracting the margins + const calculatedHeight = data?.length * 40; + const boundsWidth = width - MARGIN.right - MARGIN.left; + const boundsHeight = calculatedHeight - MARGIN.top - MARGIN.bottom; + + // Y axis is for groups since the barplot is horizontal + const groups = data + .sort((a, b) => b.value - a.value) + .map((d: HistogramData) => truncateLabel(d.label, TRUNCATE_LABEL_LENGTH)); + + const yScale = useMemo(() => { + return d3 + .scaleBand() + .domain(groups) + .range([0, boundsHeight]) + .padding(BAR_PADDING); + }, [data, calculatedHeight]); + + // X axis + const xScale = useMemo(() => { + const [min, max] = d3.extent(data.map((d: HistogramData) => d.value)); + return d3 + .scaleLinear() + .domain([0, max || 10]) + .range([0, boundsWidth]); + }, [data, width]); + + // Build the shapes + const allShapes = data.map((d: HistogramData, i: number) => { + const truncatedLabel = truncateLabel(d.label, TRUNCATE_LABEL_LENGTH); + + const y = yScale(truncatedLabel); + if (y === undefined) { + return null; } - }, [scale]); - - return ; -} - -function Bars(props: BarsPropsType) { - const { data, height, scaleX, scaleY } = props; - return ( - <> - {data.map(({ value, label }) => ( + return ( + - ))} - - ); -} - -export function Histogram(props: HistogramPropsType) { - const { data, height, width } = props; - const margin = { top: 20, right: 0, bottom: 20, left: 40 }; - const _width = width - margin.left - margin.right; - const _height = height - margin.top - margin.bottom; - - const scaleX = scaleBand() - .domain(data.map(({ label }) => truncateLabel(label, 25))) - .range([0, _width]) - .padding(0.5); + + {d.value} + + + {truncatedLabel} + + + ); + }); - const maxScaleYValue = Math.max(...data.map(({ value }) => value)); - const scaleY = scaleLinear().domain([0, maxScaleYValue]).range([_height, 0]); + useEffect(() => { + d3.selectAll(".label") + .on("mouseover", (e) => { + // TODO: Fix logic of showing tooltip + const label = d3.select(e.target).text(); + const fullLabel = d3.select(e.target).attr("data-label"); + const coordinates = d3.pointer(e); + + if (label !== fullLabel) { + d3.selectAll(`.${className} .tooltip`) + .html(fullLabel) + .attr("x", coordinates[0] - 20) + .attr("y", coordinates[1] - 20) + .style("visibility", "visible"); + } + }) + .on("mouseout", (e) => { + d3.selectAll(".tooltip").style("visibility", "hidden"); + }); + }, []); return ( - - - - - - - +

); } diff --git a/mephisto/review_app/client/src/pages/TaskStatsPage/TaskStatsPage.css b/mephisto/review_app/client/src/pages/TaskStatsPage/TaskStatsPage.css index 08390bf57..1dac91136 100644 --- a/mephisto/review_app/client/src/pages/TaskStatsPage/TaskStatsPage.css +++ b/mephisto/review_app/client/src/pages/TaskStatsPage/TaskStatsPage.css @@ -46,7 +46,7 @@ } .task-stats .content .stats .field-stats { - padding-bottom: 40px; + padding-bottom: 20px; } .task-stats .content .stats .field-stats .histogram-name { @@ -55,6 +55,13 @@ padding-bottom: 20px; } +.task-stats .content .stats .field-stats .histogram-no-responses { + padding-left: 20px; + font-size: 19px; + color: #888888; + font-style: italic; +} + .task-stats .loading { width: 100%; height: 100px; diff --git a/mephisto/review_app/client/src/pages/TaskStatsPage/TaskStatsPage.tsx b/mephisto/review_app/client/src/pages/TaskStatsPage/TaskStatsPage.tsx index c138ed20a..f0c7a3976 100644 --- a/mephisto/review_app/client/src/pages/TaskStatsPage/TaskStatsPage.tsx +++ b/mephisto/review_app/client/src/pages/TaskStatsPage/TaskStatsPage.tsx @@ -14,6 +14,8 @@ import TasksHeader from "../TasksPage/TasksHeader/TasksHeader"; import { Histogram } from "./Histogram"; import "./TaskStatsPage.css"; +const HISTOGRAM_WIDTH = 700; + type ParamsType = { id: string; }; @@ -98,13 +100,15 @@ function TaskStatsPage(props: PropsType) { {hasStats ? (
{Object.entries(taskStats.stats).map( - ([histogramName, data]) => { - if (!Object.values(data).filter(Boolean).length) { - return; - } + ([histogramName, data], index: number) => { + // No users answered this question + const allValuesZero = !Object.values(data).filter(Boolean) + .length; - const width = Object.values(data).length > 10 ? 1400 : 700; - const height = 300; + const width = + Object.values(data).length > 10 + ? HISTOGRAM_WIDTH * 2 + : HISTOGRAM_WIDTH; const histogramData: HistogramData[] = Object.entries( data @@ -122,18 +126,24 @@ function TaskStatsPage(props: PropsType) { >
{histogramName}
- + {!allValuesZero ? ( + + ) : ( +
+ No responses were provided for this question. +
+ )}
); } )} ) : ( -
This task has no statistics yet.
+
This task has no available statistics yet.
)} )} diff --git a/mephisto/review_app/client/src/pages/TasksPage/TasksPage.tsx b/mephisto/review_app/client/src/pages/TasksPage/TasksPage.tsx index c6c6c02e1..8ea536d66 100644 --- a/mephisto/review_app/client/src/pages/TasksPage/TasksPage.tsx +++ b/mephisto/review_app/client/src/pages/TasksPage/TasksPage.tsx @@ -134,9 +134,14 @@ function TasksPage(props: PropsType) { {task.unit_count} {date} - - Show - + {task.has_stats && ( + + Show + + )} {task.is_reviewed && diff --git a/mephisto/review_app/client/src/types/tasks.d.ts b/mephisto/review_app/client/src/types/tasks.d.ts index 8ff99dabb..7fd11c03c 100644 --- a/mephisto/review_app/client/src/types/tasks.d.ts +++ b/mephisto/review_app/client/src/types/tasks.d.ts @@ -5,19 +5,20 @@ */ declare type TaskType = { + created_at: string; + has_stats: boolean; id: string; - name: string; is_reviewed: boolean; + name: string; unit_count: number; - created_at: string; }; declare type TaskStatsType = { - total_count: number; - reviewed_count: number; approved_count: number; rejected_count: number; + reviewed_count: number; soft_rejected_count: number; + total_count: number; }; declare type TaskRusultStatsType = { diff --git a/mephisto/review_app/server/api/views/tasks_view.py b/mephisto/review_app/server/api/views/tasks_view.py index 99c3772cd..80b1d4cd9 100644 --- a/mephisto/review_app/server/api/views/tasks_view.py +++ b/mephisto/review_app/server/api/views/tasks_view.py @@ -9,9 +9,12 @@ from dateutil.parser import parse from flask import current_app as app from flask.views import MethodView +from omegaconf import DictConfig from mephisto.abstractions.databases.local_database import StringIDRow from mephisto.data_model.constants.assignment_state import AssignmentState +from mephisto.data_model.task import Task +from mephisto.data_model.task_run import TaskRun from mephisto.review_app.server.db_queries import find_units @@ -39,6 +42,24 @@ def find_completed_units(task_id: int) -> List[StringIDRow]: ) +def _check_task_has_stats(task_id: str) -> bool: + task: Task = Task.get(db=app.db, db_id=task_id) + task_runs: List[TaskRun] = task.get_runs() + + if not task_runs: + return False + + last_task_run: TaskRun = task_runs[-1] + last_task_run_config: DictConfig = last_task_run.get_task_args() + + if "form-composer" in last_task_run_config.task_tags: + from mephisto.generators.form_composer.stats import check_task_has_fields_for_stats + + return check_task_has_fields_for_stats(task) + + return False + + class TasksView(MethodView): def get(self) -> dict: """Get all available tasks (to select one for review)""" @@ -55,14 +76,16 @@ def get(self) -> dict: is_reviewed = unit_count > 0 and all( [u["status"] != AssignmentState.COMPLETED for u in db_units] ) + has_stats = _check_task_has_stats(task_id=t["task_id"]) tasks.append( { + "created_at": parse(t["creation_date"]).isoformat(), + "has_stats": has_stats, "id": t["task_id"], - "name": t["task_name"], "is_reviewed": is_reviewed, + "name": t["task_name"], "unit_count": unit_count, - "created_at": parse(t["creation_date"]).isoformat(), } ) From b7043708a6877a25829221608e7d4a9075ada990 Mon Sep 17 00:00:00 2001 From: Paul Abumov Date: Thu, 27 Jun 2024 09:41:19 -0400 Subject: [PATCH 3/3] Added API unittest for Task response stats --- mephisto/utils/testing.py | 5 +- test/review_app/server/api/test_stats_view.py | 2 +- .../api/test_task_stats_results_view.py | 109 ++++++++++++++++++ test/review_app/server/api/test_tasks_view.py | 1 + .../server/api/test_units_details_view.py | 2 +- test/review_app/server/api/test_units_view.py | 10 +- 6 files changed, 121 insertions(+), 8 deletions(-) create mode 100644 test/review_app/server/api/test_task_stats_results_view.py diff --git a/mephisto/utils/testing.py b/mephisto/utils/testing.py index fe64649e2..dbb1ac776 100644 --- a/mephisto/utils/testing.py +++ b/mephisto/utils/testing.py @@ -94,6 +94,7 @@ def get_test_task_run( db: MephistoDB, task_id: Optional[str] = None, requester_id: Optional[str] = None, + init_params: Optional[str] = None, ) -> str: """Helper to create a task run for tests""" if not task_id: @@ -102,7 +103,9 @@ def get_test_task_run( if not requester_id: _, requester_id = get_test_requester(db) - init_params = OmegaConf.to_yaml(OmegaConf.structured(MOCK_CONFIG)) + if not init_params: + init_params = OmegaConf.to_yaml(OmegaConf.structured(MOCK_CONFIG)) + return db.new_task_run(task_id, requester_id, json.dumps(init_params), "mock", "mock") diff --git a/test/review_app/server/api/test_stats_view.py b/test/review_app/server/api/test_stats_view.py index c803ab7e3..1cade74c2 100644 --- a/test/review_app/server/api/test_stats_view.py +++ b/test/review_app/server/api/test_stats_view.py @@ -31,7 +31,7 @@ def test_stats_success(self, *args, **kwargs): self.db.update_unit_review(unit_id, qualification_id, worker_id) with self.app_context: - url = url_for("stats") + f"?task_id={unit.task_id}" + url = url_for("review-stats") + f"?task_id={unit.task_id}" response = self.client.get(url) result = response.json diff --git a/test/review_app/server/api/test_task_stats_results_view.py b/test/review_app/server/api/test_task_stats_results_view.py new file mode 100644 index 000000000..bed10b84d --- /dev/null +++ b/test/review_app/server/api/test_task_stats_results_view.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python3 + +# Copyright (c) Meta Platforms and its affiliates. +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +import unittest +from unittest.mock import patch + +from flask import url_for +from omegaconf import OmegaConf + +from mephisto.abstractions.providers.prolific.api import status +from mephisto.data_model.task import Task +from mephisto.data_model.task_run import TaskRunArgs +from mephisto.data_model.unit import Unit +from mephisto.operations.hydra_config import MephistoConfig +from mephisto.utils.testing import get_test_task +from mephisto.utils.testing import get_test_task_run +from mephisto.utils.testing import get_test_worker +from mephisto.utils.testing import make_completed_unit +from mephisto.utils.testing import MOCK_ARCHITECT_ARGS +from mephisto.utils.testing import MOCK_BLUEPRINT_ARGS +from mephisto.utils.testing import MOCK_PROVIDER_ARGS +from test.review_app.server.api.base_test_api_view_case import BaseTestApiViewCase + +MOCK_TASK_ARGS = TaskRunArgs( + task_title="title", + task_description="This is a description", + task_reward=0.3, + task_tags="1,2,3,form-composer", +) + +MOCK_CONFIG = MephistoConfig( + provider=MOCK_PROVIDER_ARGS, + blueprint=MOCK_BLUEPRINT_ARGS, + architect=MOCK_ARCHITECT_ARGS, + task=MOCK_TASK_ARGS, +) + + +class TestTaskStatsResultsView(BaseTestApiViewCase): + def test_task_stats_result_not_found_error(self, *args, **kwargs): + with self.app_context: + url = url_for("task_stats_results", task_id=999) + response = self.client.get(url) + + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) + + def test_task_stats_result_not_reviews_error(self, *args, **kwargs): + _, task_id = get_test_task(self.db) + + with self.app_context: + url = url_for("task_stats_results", task_id=task_id) + response = self.client.get(url) + result = response.json + + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + self.assertEqual( + result["error"], + "This task has never been launched before.", + ) + + def test_task_stats_result_not_form_composer(self, *args, **kwargs): + _, worker_id = get_test_worker(self.db) + get_test_task_run(self.db) + unit_id = make_completed_unit(self.db) + unit: Unit = Unit.get(self.db, unit_id) + + with self.app_context: + url = url_for("task_stats_results", task_id=unit.task_id) + response = self.client.get(url) + result = response.json + + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + self.assertEqual( + result["error"], + "Statistics for tasks of this type are not yet supported.", + ) + + @patch("mephisto.generators.form_composer.stats.collect_task_stats") + def test_task_stats_result_success(self, mock_collect_task_stats, *args, **kwargs): + _, worker_id = get_test_worker(self.db) + init_params = OmegaConf.to_yaml(OmegaConf.structured(MOCK_CONFIG)) + get_test_task_run(self.db, init_params=init_params) + unit_id = make_completed_unit(self.db) + unit: Unit = Unit.get(self.db, unit_id) + task: Task = Task.get(self.db, unit.task_id) + + expected_value = { + "stats": {}, + "task_id": task.db_id, + "task_name": task.task_name, + "workers_count": 1, + } + + mock_collect_task_stats.return_value = expected_value + + with self.app_context: + url = url_for("task_stats_results", task_id=unit.task_id) + response = self.client.get(url) + result = response.json + + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(result, expected_value) + + +if __name__ == "__main__": + unittest.main() diff --git a/test/review_app/server/api/test_tasks_view.py b/test/review_app/server/api/test_tasks_view.py index c901b0acb..e82b284ed 100644 --- a/test/review_app/server/api/test_tasks_view.py +++ b/test/review_app/server/api/test_tasks_view.py @@ -39,6 +39,7 @@ def test_one_task_success(self, *args, **kwargs): self.assertTrue("created_at" in first_response_task) self.assertTrue("is_reviewed" in first_response_task) self.assertTrue("unit_count" in first_response_task) + self.assertTrue("has_stats" in first_response_task) if __name__ == "__main__": diff --git a/test/review_app/server/api/test_units_details_view.py b/test/review_app/server/api/test_units_details_view.py index 79f73a1d6..b22485551 100644 --- a/test/review_app/server/api/test_units_details_view.py +++ b/test/review_app/server/api/test_units_details_view.py @@ -52,7 +52,7 @@ def test_one_unit_success(self, *args, **kwargs): first_unit = result["units"][0] self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(result["units"]), 1) - self.assertEqual(first_unit["id"], int(unit_id)) + self.assertEqual(first_unit["id"], unit_id) unit_fields = [ "has_task_source_review", diff --git a/test/review_app/server/api/test_units_view.py b/test/review_app/server/api/test_units_view.py index 3a4955388..ee7ce4736 100644 --- a/test/review_app/server/api/test_units_view.py +++ b/test/review_app/server/api/test_units_view.py @@ -53,9 +53,9 @@ def test_one_unit_with_task_id_success(self, *args, **kwargs): self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(result["units"]), 1) - self.assertEqual(first_response_unit["id"], int(unit_id)) + self.assertEqual(first_response_unit["id"], unit_id) self.assertEqual(first_response_unit["worker_id"], unit.worker_id) - self.assertEqual(first_response_unit["task_id"], int(unit.task_id)) + self.assertEqual(first_response_unit["task_id"], unit.task_id) self.assertEqual(first_response_unit["status"], unit.db_status) self.assertTrue("pay_amount" in first_response_unit) @@ -97,7 +97,7 @@ def test_one_unit_with_unit_ids_success(self, *args, **kwargs): first_response_unit = result["units"][0] self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(result["units"]), 1) - self.assertEqual(first_response_unit["id"], int(unit_1_id)) + self.assertEqual(first_response_unit["id"], unit_1_id) def test_two_units_with_unit_ids_success(self, *args, **kwargs): # Create 2 COMPLETED units @@ -127,8 +127,8 @@ def test_two_units_with_unit_ids_success(self, *args, **kwargs): second_response_unit = result["units"][1] self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(result["units"]), 2) - self.assertEqual(first_response_unit["id"], int(unit_1_id)) - self.assertEqual(second_response_unit["id"], int(unit_2_id)) + self.assertEqual(first_response_unit["id"], unit_1_id) + self.assertEqual(second_response_unit["id"], unit_2_id) if __name__ == "__main__":