diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d73b84870..1735df2d1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,7 +5,7 @@ default_language_version: repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v2.5.0 + rev: v4.4.0 hooks: - id: trailing-whitespace - id: check-ast @@ -31,7 +31,7 @@ repos: language: system - repo: https://github.com/Lucas-C/pre-commit-hooks - rev: v1.1.7 + rev: v1.5.1 hooks: - id: insert-license files: \.py$ @@ -45,31 +45,31 @@ repos: - docs/license_header.txt - --comment-style - /*| *| */ -- repo: https://gitlab.com/pycqa/flake8 - rev: 3.7.9 +- repo: https://github.com/pycqa/flake8 + rev: 6.1.0 hooks: - id: flake8 - repo: https://github.com/asottile/pyupgrade - rev: v2.2.1 + rev: v3.10.1 hooks: - id: pyupgrade args: ['--py36-plus'] - repo: https://github.com/timothycrosley/isort - rev: 5.10.1 + rev: 5.12.0 hooks: - id: isort exclude: ^website - repo: https://github.com/ambv/black - rev: 22.3.0 + rev: 23.7.0 hooks: - id: black language_version: python3 - repo: https://github.com/pre-commit/mirrors-prettier - rev: v2.3.0 + rev: v3.0.0 hooks: - id: prettier files: \.[jt]sx?$ @@ -84,7 +84,7 @@ repos: - stylelint-config-standard@20.0.0 - repo: https://github.com/pre-commit/mirrors-eslint - rev: v7.21.0 + rev: v8.46.0 hooks: - id: eslint args: [--fix --silent] diff --git a/backend/app/api/endpoints/auth.py b/backend/app/api/endpoints/auth.py index 170cf59b0..ee96950a1 100644 --- a/backend/app/api/endpoints/auth.py +++ b/backend/app/api/endpoints/auth.py @@ -5,7 +5,7 @@ from fastapi import APIRouter, Depends from fastapi.security import OAuth2PasswordRequestForm -from app.domain.auth.authentication import Login +from app.domain.auth.authentication import LoginService from app.domain.schemas.auth.auth import ( CreateUserRequest, CreateUserResponse, @@ -19,14 +19,14 @@ @router.post("/login", response_model=LoginResponse) async def login(model: OAuth2PasswordRequestForm = Depends()): - return Login().login(model.username, model.password) + return LoginService().login(model.username, model.password) @router.post("/create_user", response_model=CreateUserResponse) async def create_user(model: CreateUserRequest): - return Login().create_user(model.email, model.password, model.username) + return LoginService().create_user(model.email, model.password, model.username) @router.post("/is_admin_or_owner", response_model=bool) async def is_admin_or_owner(model: IsAdminOrOwnerRequest): - return Login().is_admin_or_owner(model.user_id, model.task_id) + return LoginService().is_admin_or_owner(model.user_id, model.task_id) diff --git a/backend/app/api/endpoints/base/context.py b/backend/app/api/endpoints/base/context.py index bf044d7df..ce8d0e935 100644 --- a/backend/app/api/endpoints/base/context.py +++ b/backend/app/api/endpoints/base/context.py @@ -2,7 +2,12 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -from fastapi import APIRouter +import asyncio +import json + +from fastapi import APIRouter, WebSocket +from fastapi.responses import JSONResponse +from sse_starlette.sse import EventSourceResponse from app.domain.schemas.base.context import ( GetContextRequest, @@ -26,7 +31,33 @@ async def get_context_configuration(task_id: int): return context_config +@router.websocket("/ws/get_generative_contexts") +async def websocket_generative_context(websocket: WebSocket): + await websocket.accept() + model_info = await websocket.receive_json() + model_info = dict(model_info) + for _ in range(4): + data = ContextService().get_generative_contexts( + model_info["type"], model_info["artifacts"] + ) + await websocket.send_json(data) + await websocket.close() + + @router.post("/get_generative_contexts") async def get_generative_contexts(model: GetGenerativeContextRequest): image_list = ContextService().get_generative_contexts(model.type, model.artifacts) - return image_list + return JSONResponse(content=image_list, headers={"Cache-Control": "private"}) + + +@router.post("/stream") +async def stream_images(model_info: GetGenerativeContextRequest): + async def event_generator(): + for _ in range(2): + data = ContextService().get_generative_contexts( + model_info.type, model_info.artifacts + ) + yield json.dumps(data) + await asyncio.sleep(1) + + return EventSourceResponse(event_generator()) diff --git a/backend/app/api/endpoints/base/example.py b/backend/app/api/endpoints/base/example.py index b01426351..0f86a2eeb 100644 --- a/backend/app/api/endpoints/base/example.py +++ b/backend/app/api/endpoints/base/example.py @@ -11,7 +11,7 @@ DownloadAllExamplesRequest, DownloadExamplesRequest, GetExampleRequest, - PartiallyCreationExampleGenerativeRequest, + PartialCreationExampleRequest, UpdateCreationExampleGenerativeRequest, ValidateExampleRequest, ) @@ -53,7 +53,7 @@ def validate_example(model: ValidateExampleRequest): @router.post("/partial_creation_generative_example", response_model={}) def partial_creation_generative_example( - model: PartiallyCreationExampleGenerativeRequest, + model: PartialCreationExampleRequest, ): return ExampleService().partial_creation_generative_example( model.example_info, diff --git a/backend/app/api/endpoints/base/model.py b/backend/app/api/endpoints/base/model.py index 3ef5fa20e..cf462b7e8 100644 --- a/backend/app/api/endpoints/base/model.py +++ b/backend/app/api/endpoints/base/model.py @@ -11,6 +11,7 @@ ModelPredictionPerDatasetRequest, SingleModelEvaluationRequest, SingleModelEvaluationResponse, + UpdateModelInfoRequest, UploadModelToS3AndEvaluateRequest, ) from app.domain.services.base.model import ModelService @@ -89,9 +90,9 @@ def initiate_lambda_models() -> None: return ModelService().initiate_lambda_models() -@router.post("/get_model_prediction_per_dataset") -def get_model_prediction_per_dataset(model: ModelPredictionPerDatasetRequest): - file_name = ModelService().get_model_prediction_per_dataset( +@router.post("/get_model_prediction_by_dataset") +def get_model_prediction_by_dataset(model: ModelPredictionPerDatasetRequest): + file_name = ModelService().get_model_prediction_by_dataset( model.user_id, model.model_id, model.dataset_id ) return FileResponse( @@ -101,9 +102,9 @@ def get_model_prediction_per_dataset(model: ModelPredictionPerDatasetRequest): ) -@router.get("/get_amount_of_models_per_task/{task_id}", response_model=int) -def get_amount_of_models_per_task(task_id: int): - return ModelService().get_amount_of_models_per_task(task_id) +@router.get("/get_amount_of_models_by_task/{task_id}", response_model=int) +def get_amount_of_models_by_task(task_id: int): + return ModelService().get_amount_of_models_by_task(task_id) @router.post("/upload_prediction_to_s3") @@ -117,7 +118,6 @@ def upload_prediction_to_s3( @router.post("/conversation_with_buffer_memory") def conversation_with_buffer_memory(model: ConversationWithBufferMemoryRequest): - print("model.history", model.history) return ModelService().conversation_with_buffer_memory( model.history, model.model_name, model.provider, model.prompt, model.num_answers ) @@ -126,3 +126,32 @@ def conversation_with_buffer_memory(model: ConversationWithBufferMemoryRequest): @router.get("/update_model_status/{model_id}") def update_model_status(model_id: int): return ModelService().update_model_status(model_id) + + +@router.get("/get_models_by_user_id/{user_id}") +def get_models_by_user_id(user_id: int): + return ModelService().get_models_by_user_id(user_id) + + +@router.get("/delete_model/{model_id}") +def delete_model(model_id: int): + return ModelService().delete_model(model_id) + + +@router.get("/get_all_model_info_by_id/{model_id}") +def get_all_model_info_by_id(model_id: int): + return ModelService().get_all_model_info_by_id(model_id) + + +@router.post("/update_model_info") +def update_model_info(model: UpdateModelInfoRequest): + return ModelService().update_model_info( + model.model_id, + model.name, + model.desc, + model.longdesc, + model.params, + model.languages, + model.license, + model.source_url, + ) diff --git a/backend/app/api/endpoints/base/score.py b/backend/app/api/endpoints/base/score.py index a8a67ff6c..ddbaadec7 100644 --- a/backend/app/api/endpoints/base/score.py +++ b/backend/app/api/endpoints/base/score.py @@ -10,6 +10,6 @@ router = APIRouter() -@router.get("/get_maximun_principal_score_per_task/{task_id}", response_model={}) -async def get_maximun_principal_score_per_task(task_id: int): - return ScoreService().get_maximun_principal_score_per_task(task_id) +@router.get("/get_maximun_principal_score_by_task/{task_id}", response_model={}) +async def get_maximun_principal_score_by_task(task_id: int): + return ScoreService().get_maximun_principal_score_by_task(task_id) diff --git a/backend/app/api/endpoints/base/task.py b/backend/app/api/endpoints/base/task.py index bae6d71c5..3435f3bc3 100644 --- a/backend/app/api/endpoints/base/task.py +++ b/backend/app/api/endpoints/base/task.py @@ -85,3 +85,8 @@ async def get_challenges_types(): @router.get("/get_tasks_with_samples_created_by_user/{user_id}", response_model={}) async def get_tasks_with_samples_created_by_user(user_id: int): return TaskService().get_tasks_with_samples_created_by_user(user_id) + + +@router.get("/get_active_tasks_by_user_id/{user_id}", response_model={}) +async def get_active_tasks_by_user_id(user_id: str): + return TaskService().get_active_tasks_by_user_id(user_id) diff --git a/backend/app/api/endpoints/base/task_proposals.py b/backend/app/api/endpoints/base/task_proposals.py new file mode 100644 index 000000000..6a95f8edd --- /dev/null +++ b/backend/app/api/endpoints/base/task_proposals.py @@ -0,0 +1,24 @@ +# Copyright (c) MLCommons 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 fastapi import APIRouter + +from app.domain.services.base.task_proposals import TaskProposalService + + +router = APIRouter() + + +@router.get("/validate_no_duplicate_task_code/{task_code}", response_model={}) +async def validate_no_duplicate_task_code(task_code: str): + return TaskProposalService().validate_no_duplicate_task_code(task_code) + + +@router.post("/add_task_proposal", response_model={}) +async def add_task_proposal( + user_id: int, task_code: str, name: str, desc: str, longdesc: str +): + return TaskProposalService().add_task_proposal( + user_id, task_code, name, desc, longdesc + ) diff --git a/backend/app/api/endpoints/base/user.py b/backend/app/api/endpoints/base/user.py new file mode 100644 index 000000000..25feedfdb --- /dev/null +++ b/backend/app/api/endpoints/base/user.py @@ -0,0 +1,32 @@ +# Copyright (c) MLCommons 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 fastapi import APIRouter + +from app.domain.auth.authentication import LoginService +from app.domain.schemas.auth.auth import CreateUserRequest, LoginRequest +from app.domain.services.base.user import UserService + + +router = APIRouter() + + +@router.get("/get_user_with_badges/{user_id}", response_model={}) +async def get_task_id_by_task_code(user_id: str): + return UserService().get_user_with_badges(user_id) + + +@router.get("/get_stats_by_user_id/{user_id}", response_model={}) +async def get_stats_by_user_id(user_id: str): + return UserService().get_stats_by_user_id(user_id) + + +@router.post("/authenticate") +async def authenticate(model: LoginRequest): + return LoginService().login(model.email, model.password) + + +@router.post("/create_user") +async def create_user(model: CreateUserRequest): + return LoginService().create_user(model.email, model.password, model.username) diff --git a/backend/app/domain/auth/authentication.py b/backend/app/domain/auth/authentication.py index d099e51a6..6627130f0 100644 --- a/backend/app/domain/auth/authentication.py +++ b/backend/app/domain/auth/authentication.py @@ -15,12 +15,13 @@ user_with_email_already_exists, ) from app.domain.services.base.user import UserService +from app.infrastructure.repositories.badge import BadgeRepository from app.infrastructure.repositories.taskuserpermission import ( TaskUserPermissionRepository, ) -class Login: +class LoginService: def __init__(self) -> None: self.AUTH_JWT_SECRET_KEY = os.getenv("AUTH_JWT_SECRET_KEY") self.ACCESS_TOKEN_EXPIRE_MINUTES = os.getenv("AUTH_ACCESS_TOKEN_EXPIRE_MINUTES") @@ -30,6 +31,7 @@ def __init__(self) -> None: self.AUTH_HASH_ALGORITHM = os.getenv("AUTH_HASH_ALGORITHM") self.users_service = UserService() self.task_user_permission_repository = TaskUserPermissionRepository() + self.badges_repository = BadgeRepository() def get_hashed_password(self, password: str) -> str: return generate_password_hash(password) @@ -70,7 +72,8 @@ def create_user(self, email: str, password: str, username: str) -> dict: if user: user_with_email_already_exists(email) password = self.get_hashed_password(password) - return self.users_service.create_user(email, password, username) + user_id = self.users_service.create_user(email, password, username)["id"] + self.badges_repository.add_badge(user_id, "WELCOME_NOOB") def login(self, email: str, password: str) -> dict: user = self.users_service.get_by_email(email) @@ -80,8 +83,8 @@ def login(self, email: str, password: str) -> dict: if not self.verify_password(password, hashed_pass): password_is_incorrect() return { - "access_token": self.create_access_token(user["email"]), - "token_type": "bearer", + "token": self.create_access_token(user["email"]), + "user": user, } def is_admin_or_owner(self, user_id: int, task_id: int): diff --git a/backend/app/domain/helpers/email_templates/model_evaluation_failed.txt b/backend/app/domain/helpers/email_templates/model_evaluation_failed.txt new file mode 100644 index 000000000..d726a06cf --- /dev/null +++ b/backend/app/domain/helpers/email_templates/model_evaluation_failed.txt @@ -0,0 +1,8 @@ +Hi there + +Your model $name has failed evaluating. Please check your model and try again. If you think this is a mistake, please contact +the task organizer. + +Thanks, + +The Dynabench Team diff --git a/backend/app/domain/helpers/email_templates/model_evaluation_sucessful.txt b/backend/app/domain/helpers/email_templates/model_evaluation_sucessful.txt new file mode 100644 index 000000000..796a04884 --- /dev/null +++ b/backend/app/domain/helpers/email_templates/model_evaluation_sucessful.txt @@ -0,0 +1,8 @@ +Hi there + +Your model $name has been successfully evaluated. +You can find and publish the model at https://dynabench.org/models/$model_id. + +Thanks, + +The Dynabench Team diff --git a/backend/app/domain/helpers/email_templates/task_proposal_update.txt b/backend/app/domain/helpers/email_templates/task_proposal_update.txt new file mode 100644 index 000000000..f394570d4 --- /dev/null +++ b/backend/app/domain/helpers/email_templates/task_proposal_update.txt @@ -0,0 +1,7 @@ +Greetings, + +You're task $name with the code $code has been successfully created with the following description: $desc. + +Thanks, + +The Dynabench Team diff --git a/backend/app/domain/schemas/auth/auth.py b/backend/app/domain/schemas/auth/auth.py index dad5993ac..e9b12ea29 100644 --- a/backend/app/domain/schemas/auth/auth.py +++ b/backend/app/domain/schemas/auth/auth.py @@ -18,7 +18,7 @@ class CreateUserResponse(BaseModel): class LoginRequest(BaseModel): - username: EmailStr + email: EmailStr password: str diff --git a/backend/app/domain/schemas/base/example.py b/backend/app/domain/schemas/base/example.py index 6474511bf..f0ed60883 100644 --- a/backend/app/domain/schemas/base/example.py +++ b/backend/app/domain/schemas/base/example.py @@ -37,7 +37,7 @@ class CreateExampleRequest(BaseModel): tag: Optional[str] = "generative" -class PartiallyCreationExampleGenerativeRequest(BaseModel): +class PartialCreationExampleRequest(BaseModel): example_info: dict context_id: int user_id: int diff --git a/backend/app/domain/schemas/base/model.py b/backend/app/domain/schemas/base/model.py index 8e130120a..d988463c9 100644 --- a/backend/app/domain/schemas/base/model.py +++ b/backend/app/domain/schemas/base/model.py @@ -70,3 +70,14 @@ class ConversationWithBufferMemoryRequest(BaseModel): provider: str prompt: str num_answers: int + + +class UpdateModelInfoRequest(BaseModel): + model_id: int + name: Optional[str] + desc: Optional[str] + longdesc: Optional[str] + params: Optional[int] + languages: Optional[str] + license: Optional[str] + source_url: Optional[str] = "" diff --git a/backend/app/domain/services/base/context.py b/backend/app/domain/services/base/context.py index f22380f33..cb1f8520c 100644 --- a/backend/app/domain/services/base/context.py +++ b/backend/app/domain/services/base/context.py @@ -5,9 +5,9 @@ import base64 import hashlib import json -import multiprocessing import os import random +import time import boto3 import yaml @@ -15,11 +15,8 @@ from app.domain.services.base.task import TaskService from app.domain.services.utils.constant import black_image, forbidden_image -from app.domain.services.utils.image_generators import ( - OpenAIImageProvider, - StableDiffusionImageProvider, -) from app.domain.services.utils.llm import OpenAIProvider +from app.domain.services.utils.multi_generator import ImageGenerator from app.infrastructure.repositories.context import ContextRepository from app.infrastructure.repositories.round import RoundRepository @@ -29,10 +26,6 @@ def __init__(self): self.context_repository = ContextRepository() self.round_repository = RoundRepository() self.task_service = TaskService() - self.image_providers = [ - StableDiffusionImageProvider(), - OpenAIImageProvider(), - ] self.llm_provider = OpenAIProvider() self.session = boto3.Session( aws_access_key_id=os.getenv("AWS_ACCESS_KEY_ID"), @@ -119,27 +112,16 @@ def get_nibbler_contexts( self, prompt: str, user_id: int, num_images: int, models: list, endpoint: str ) -> dict: images = [] - for generator in self.image_providers: - if generator.provider_name() == "openai": - n = 2 - generated_images = generator.generate_images( - prompt, n, models, endpoint - ) - else: - n = 8 - with multiprocessing.Pool(2) as p: - generated_images = p.starmap( - generator.generate_images, - [(prompt, n, models, endpoint)] * 2, - ) - p.close() - p.join() - generated_images = [ - image for sublist in generated_images for image in sublist - ] - for image in generated_images: + start = time.time() + multi_generator = ImageGenerator() + generated_images = multi_generator.generate_all_images( + prompt, num_images, models, endpoint + ) + images = [] + for generator_dict in generated_images: + for image in generator_dict["images"]: image_id = ( - generator.provider_name() + generator_dict["generator"] + "_" + prompt + "_" @@ -167,6 +149,7 @@ def get_nibbler_contexts( ) images.append(new_dict) random.shuffle(images) + print(f"Time to generate images: {time.time() - start}") return images def get_perdi_contexts( @@ -186,14 +169,17 @@ def get_perdi_contexts( all_answers.append(answer) return all_answers + async def generate_images_stream(self, model_info): + yield self.get_generative_contexts(model_info["type"], model_info["artifacts"]) + def get_generative_contexts(self, type: str, artifacts: dict) -> dict: if type == "nibbler": return self.get_nibbler_contexts( prompt=artifacts["prompt"], user_id=artifacts["user_id"], models=artifacts["model"], - endpoint=artifacts["endpoint"], - num_images=30, + endpoint=artifacts["model"], + num_images=6, ) elif type == "perdi": return self.get_perdi_contexts( diff --git a/backend/app/domain/services/base/model.py b/backend/app/domain/services/base/model.py index 5ce52149a..4baf8b383 100644 --- a/backend/app/domain/services/base/model.py +++ b/backend/app/domain/services/base/model.py @@ -280,7 +280,7 @@ def initiate_lambda_models(self): print("Finished") time.sleep(320) - def get_model_prediction_per_dataset( + def get_model_prediction_by_dataset( self, user_id: int, model_id: int, dataset_id: int ): model_info = self.model_repository.get_model_info_by_id(model_id) @@ -297,8 +297,8 @@ def get_model_prediction_per_dataset( ) return final_file - def get_amount_of_models_per_task(self, task_id: int): - return self.model_repository.get_amount_of_models_per_task(task_id) + def get_amount_of_models_by_task(self, task_id: int): + return self.model_repository.get_amount_of_models_by_task(task_id) def get_model_name_by_id(self, model_id: int): return self.model_repository.get_model_name_by_id(model_id) @@ -333,10 +333,17 @@ def upload_prediction_to_s3( Key=model_path, ContentType=predictions.content_type, ) + self.email_helper.send( + contact=user_email, + cc_contact="dynabench-site@mlcommons.org", + template_name="model_upload_successful.txt", + msg_dict={"name": model_name}, + subject=f"Model {model_name} upload succeeded.", + ) centralize_host = os.getenv("CENTRALIZED_HOST") endpoint = "/builder_evaluation/evaluation/evaluate_downstream_tasks" url = f"{centralize_host}{endpoint}" - requests.post( + evaluate_model = requests.post( url, json={ "task_id": task_id, @@ -344,13 +351,25 @@ def upload_prediction_to_s3( "model_id": model["id"], }, ) - self.email_helper.send( - contact=user_email, - cc_contact="dynabench-site@mlcommons.org", - template_name="model_upload_successful.txt", - msg_dict={"name": model_name}, - subject=f"Model {model_name} upload succeeded.", - ) + if evaluate_model.status_code == 200: + self.email_helper.send( + contact=user_email, + cc_contact="dynabench-site@mlcommons.org", + template_name="model_evaluation_sucessful.txt", + msg_dict={"name": model_name, "model_id": model["id"]}, + subject=f"Model {model_name} evaluation succeeded.", + ) + else: + self.email_helper.send( + contact=user_email, + cc_contact="dynabench-site@mlcommons.org", + template_name="model_evaluation_failed.txt", + msg_dict={"name": model_name}, + subject=f"Model {model_name} evaluation failed.", + ) + raise HTTPException( + status_code=400, detail="Model evaluation fail, please try again" + ) return "Model evaluate successfully" def conversation_with_buffer_memory( @@ -389,3 +408,27 @@ def update_model_status(self, model_id: int): self.model_repository.update_published_status(model_id) else: raise HTTPException(status_code=400, detail="Model no has all the scores") + + def get_models_by_user_id(self, user_id: int): + return self.model_repository.get_models_by_user_id(user_id) + + def delete_model(self, model_id: int): + return self.model_repository.delete_model(model_id) + + def get_all_model_info_by_id(self, model_id: int): + return self.model_repository.get_all_model_info_by_id(model_id) + + def update_model_info( + self, + model_id: int, + name: str, + desc: str, + longdesc: str, + params: float, + languages: str, + license: str, + source_url: str, + ): + return self.model_repository.update_model_info( + model_id, name, desc, longdesc, params, languages, license, source_url + ) diff --git a/backend/app/domain/services/base/score.py b/backend/app/domain/services/base/score.py index 8818d2f24..9efb0c02d 100644 --- a/backend/app/domain/services/base/score.py +++ b/backend/app/domain/services/base/score.py @@ -28,7 +28,6 @@ def get_scores_by_dataset_and_model_id( order_metric_with_weight: dict, perf_metric_field_name: str, ): - scores_by_dataset_and_model_id[ perf_metric_field_name ] = scores_by_dataset_and_model_id.pop("perf") @@ -37,11 +36,19 @@ def get_scores_by_dataset_and_model_id( for row in order_metric_with_weight ] for metric_with_score_and_weight in metrics_with_score_and_weight: - print(scores_by_dataset_and_model_id["metadata_json"]) - score = json.loads(scores_by_dataset_and_model_id["metadata_json"])[ - metric_with_score_and_weight["field_name"] - ] - metric_with_score_and_weight["score"] = score + if metric_with_score_and_weight["field_name"] in [ + "examples_per_second", + "memory_utilization", + ]: + score = scores_by_dataset_and_model_id[ + metric_with_score_and_weight["field_name"] + ] + metric_with_score_and_weight["score"] = score + else: + score = json.loads(scores_by_dataset_and_model_id["metadata_json"])[ + metric_with_score_and_weight["field_name"] + ] + metric_with_score_and_weight["score"] = score return metrics_with_score_and_weight def get_score_info_by_dataset_and_model_id( @@ -72,7 +79,6 @@ def get_score_info_by_dataset_and_model_id( scores = [ metric_score["score"] for metric_score in metrics_with_score_and_weight ] - final_scores_by_dataset_and_model_id["scores"] = scores final_scores_by_dataset_and_model_id["variances"] = [0] * len(scores) if dataset_has_downstream: @@ -122,6 +128,7 @@ def get_dynaboard_info_for_all_the_models( offset: int, limit: int, metrics: list, + perf_metric_info: dict, ): models_dynaboard_info = [] for model_id in model_ids: @@ -154,6 +161,11 @@ def get_dynaboard_info_for_all_the_models( ] # Sort + if isinstance(perf_metric_info, list): + perf_metric_info = perf_metric_info[0] + utility_direction = perf_metric_info.get("utility_direction", None) + if utility_direction == -1: + sort_direction = "desc" if sort_direction == "asc" else "asc" if sort_by != "dynascore": models_dynaboard_info = sorted( models_dynaboard_info, @@ -192,6 +204,7 @@ def get_model_dynaboard_info( dataset_id, model_id, order_metric_with_weight, perf_metric_field_name ) datasets_info.append(dataset_info) + averaged_scores = self.get_averaged_scores( datasets_info, order_scoring_datasets_with_weight ) @@ -279,10 +292,10 @@ def calculate_dynascore( ) return converted_data - def get_maximun_principal_score_per_task(self, task_id: int) -> float: + def get_maximun_principal_score_by_task(self, task_id: int) -> float: scoring_datasets = self.dataset_service.get_scoring_datasets_by_task_id(task_id) scoring_datasets = [dataset["id"] for dataset in scoring_datasets] - scores = self.score_repository.get_maximun_principal_score_per_task( + scores = self.score_repository.get_maximun_principal_score_by_task( task_id, scoring_datasets ) if scores: diff --git a/backend/app/domain/services/base/task.py b/backend/app/domain/services/base/task.py index db613a93b..cb27a6e87 100644 --- a/backend/app/domain/services/base/task.py +++ b/backend/app/domain/services/base/task.py @@ -14,10 +14,12 @@ meta_metrics_dict, ) from app.infrastructure.repositories.dataset import DatasetRepository +from app.infrastructure.repositories.example import ExampleRepository from app.infrastructure.repositories.model import ModelRepository from app.infrastructure.repositories.task import TaskRepository from app.infrastructure.repositories.taskcategories import TaskCategoriesRepository from app.infrastructure.repositories.user import UserRepository +from app.infrastructure.repositories.validation import ValidationRepository class TaskService: @@ -25,9 +27,11 @@ def __init__(self): self.task_repository = TaskRepository() self.dataset_repository = DatasetRepository() self.model_repository = ModelRepository() + self.example_repository = ExampleRepository() self.score_services = ScoreService() self.task_categories_repository = TaskCategoriesRepository() self.user_repository = UserRepository() + self.validation_repository = ValidationRepository() def update_last_activity_date(self, task_id: int): self.task_repository.update_last_activity_date(task_id) @@ -102,7 +106,7 @@ def get_order_metrics_by_task_id(self, task_id: int): ).get("aws_metrics", []) ordered_metric_field_names = ( - type_values + delta_perf_metrics_type + aws_metric_names + type_values + aws_metric_names + delta_perf_metrics_type ) metrics_metadata = { metric: meta_metrics_dict.get(metric)(task_info) @@ -166,6 +170,9 @@ def get_dynaboard_info_by_task_id( dynaboard_info = {} ordered_metrics = self.get_order_metrics_by_task_id(task_id) ordered_scoring_datasets = self.get_order_scoring_datasets_by_task_id(task_id) + task_info = self.get_task_info_by_task_id(task_id).__dict__ + task_configuration = yaml.load(task_info.get("config_yaml"), yaml.SafeLoader) + perf_metric_info = task_configuration.get("perf_metric", {}) order_metric_with_weight = [ dict({"weight": weight}, **metric) for weight, metric in zip(ordered_metric_weights, ordered_metrics) @@ -191,6 +198,7 @@ def get_dynaboard_info_by_task_id( offset, limit, metrics, + perf_metric_info, ) dynaboard_info["data"] = data return dynaboard_info @@ -209,10 +217,34 @@ def get_task_instructions(self, task_id: int): instructions = self.task_repository.get_task_instructions( task_id ).general_instructions - return literal_eval(instructions) + try: + return literal_eval(instructions) + except Exception as e: + print(e) + return {} def update_task_instructions(self, task_id: int, instructions: dict): return self.task_repository.update_task_instructions(task_id, instructions) def get_tasks_with_samples_created_by_user(self, user_id: int): return self.task_repository.get_tasks_with_samples_created_by_user(user_id) + + def get_active_tasks_by_user_id(self, user_id: int): + tasks_with_models_activity = self.model_repository.get_active_tasks_by_user_id( + user_id + ) + tasks_with_examples_activity = ( + self.example_repository.get_active_tasks_by_user_id(user_id) + ) + tasks_with_validation_activity = ( + self.validation_repository.get_active_tasks_by_user_id(user_id) + ) + active_tasks = list( + tasks_with_models_activity + + tasks_with_examples_activity + + tasks_with_validation_activity + ) + active_tasks = [task[0] for task in active_tasks] + all_tasks = self.get_active_tasks_with_round_info() + active_tasks = [task for task in all_tasks if task["id"] in active_tasks] + return active_tasks diff --git a/backend/app/domain/services/base/task_proposals.py b/backend/app/domain/services/base/task_proposals.py new file mode 100644 index 000000000..bb62c3d44 --- /dev/null +++ b/backend/app/domain/services/base/task_proposals.py @@ -0,0 +1,36 @@ +# Copyright (c) MLCommons 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 app.domain.helpers.email import EmailHelper +from app.infrastructure.repositories.task import TaskRepository +from app.infrastructure.repositories.taskproposal import TaskProposalRepository + + +class TaskProposalService: + def __init__(self): + self.task_proposal_repository = TaskProposalRepository() + self.task_repository = TaskRepository() + self.email_helper = EmailHelper() + + def validate_no_duplicate_task_code(self, task_code: str): + return ( + False + if self.task_repository.validate_no_duplicate_task_code(task_code) + is not None + else True + ) + + def add_task_proposal( + self, user_id: int, task_code: str, name: str, desc: str, longdesc: str + ): + self.email_helper.send( + contact="juan.ciro@factored.ai", + cc_contact="dynabench-site@mlcommons.org", + template_name="task_proposal_update.txt", + msg_dict={"name": name, "code": task_code, "desc": longdesc}, + subject=f"Proposal for task {task_code}", + ) + return self.task_proposal_repository.add_task_proposal( + user_id, task_code, name, desc, longdesc + ) diff --git a/backend/app/domain/services/base/user.py b/backend/app/domain/services/base/user.py index ca3c2d95d..164cd5f32 100644 --- a/backend/app/domain/services/base/user.py +++ b/backend/app/domain/services/base/user.py @@ -2,12 +2,18 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. +from app.infrastructure.repositories.example import ExampleRepository +from app.infrastructure.repositories.model import ModelRepository from app.infrastructure.repositories.user import UserRepository +from app.infrastructure.repositories.validation import ValidationRepository class UserService: def __init__(self): self.user_repository = UserRepository() + self.example_repository = ExampleRepository() + self.validation_repository = ValidationRepository() + self.model_repository = ModelRepository() def increment_examples_fooled(self, user_id: int): self.user_repository.increment_examples_fooled(user_id) @@ -38,3 +44,25 @@ def create_user(self, email: str, password: str, username: str): def get_is_admin(self, user_id: int): return self.user_repository.get_is_admin(user_id) + + def get_user_with_badges(self, user_id: int): + user_info = self.user_repository.get_info_by_user_id(user_id).__dict__ + badges = self.user_repository.get_badges_by_user_id(user_id) + user_info["badges"] = [badge for badge in badges] + return user_info + + def get_stats_by_user_id(self, user_id: int): + stats_by_user = {} + stats_by_user[ + "total_examples" + ] = self.example_repository.get_total_examples_by_user_id(user_id) + stats_by_user[ + "total_validations" + ] = self.validation_repository.get_total_validations_by_user_id(user_id) + stats_by_user[ + "total_models" + ] = self.model_repository.get_total_models_by_user_id(user_id) + stats_by_user[ + "model_fooling_rate" + ] = self.example_repository.get_model_fooling_rate_by_user_id(user_id) + return stats_by_user diff --git a/backend/app/domain/services/utils/image_generators.py b/backend/app/domain/services/utils/image_generators.py index f2bdc79f2..c495a1c16 100644 --- a/backend/app/domain/services/utils/image_generators.py +++ b/backend/app/domain/services/utils/image_generators.py @@ -2,6 +2,7 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. +import base64 import os from abc import ABC, abstractmethod @@ -35,21 +36,122 @@ def __init__(self): def generate_images( self, prompt: str, num_images: int, models: list = [], endpoint: str = "" ) -> list: + openai.api_key = self.api_key try: response = openai.Image.create( - prompt=prompt, n=num_images, size="256x256", response_format="b64_json" + prompt=prompt, n=1, size="256x256", response_format="b64_json" ) image_response = [x["b64_json"] for x in response["data"]] - return image_response + return {"generator": self.provider_name(), "images": image_response} - except openai.error.OpenAIError as e: - print(e) - return [forbidden_image] * num_images + except Exception as e: + print(e, "This was the exception") + images = [forbidden_image] + return {"generator": self.provider_name(), "images": images} def provider_name(self): return "openai" +class DynabenchImageProvider(ImageProvider): + def __init__(self): + pass + + def generate_images(self, prompt: str, num_images: int, model, endpoint) -> list: + payload = {"prompt": prompt, "num_images": 1} + response = requests.post(f"{endpoint['dynabench']['endpoint']}", json=payload) + if response.status_code == 200: + return {"generator": self.provider_name(), "images": response.json()} + + def provider_name(self): + return "dynabench" + + +class SDVariableAutoEncoder(ImageProvider): + def __init__(self): + self.api_key = os.getenv("HF") + + def generate_images(self, prompt: str, num_images: int, model, endpoint) -> list: + print("Trying model", endpoint["hf_inference_1"]["endpoint"]) + payload = {"inputs": prompt, "steps": 30} + headers = {"Authorization": self.api_key} + response = requests.post( + f"{endpoint['hf_inference_1']['endpoint']}", json=payload, headers=headers + ) + if response.status_code == 200: + new_image = response.json()[0]["image"]["images"][0] + return {"generator": self.provider_name(), "images": [new_image]} + + def provider_name(self): + return "sd+vae_ft_mse" + + +class SDXL(ImageProvider): + def __init__(self): + self.api_key = os.getenv("HF") + + def generate_images(self, prompt: str, num_images: int, model, endpoint) -> list: + print("Trying model", endpoint["hf_inference_2"]["endpoint"]) + payload = {"inputs": prompt, "steps": 30} + headers = {"Authorization": self.api_key} + response = requests.post( + f"{endpoint['hf_inference_2']['endpoint']}", json=payload, headers=headers + ) + if response.status_code == 200: + new_image = response.json()[0]["image"]["images"][0] + return {"generator": self.provider_name(), "images": [new_image]} + + def provider_name(self): + return "sdxl_1.0" + + +class HFInferenceEndpointImageProvider(ImageProvider): + def __init__(self): + self.api_key = os.getenv("HF") + + def generate_images(self, prompt: str, num_images: int, model, endpoint) -> list: + print("Trying model", endpoint["hf_inference_1"]["endpoint"]) + payload = {"inputs": prompt, "steps": 30} + headers = {"Authorization": self.api_key} + response = requests.post( + f"{endpoint['hf_inference_1']['endpoint']}", json=payload, headers=headers + ) + if response.status_code == 200: + new_image = response.json()[0]["image"]["images"][0] + return {"generator": self.provider_name(), "images": [new_image]} + + def provider_name(self): + return "sd+vae_ft_mse" + + +class HFImageProvider(ImageProvider): + def __init__(self): + self.api_key = os.getenv("HF") + + def generate_images( + self, prompt: str, num_images: int, models: list, endpoint: str + ): + payload = {"inputs": prompt} + headers = { + "Authorization": self.api_key, + "Cache-Control": "no-cache", + "Pragma": "no-cache", + "x-use-cache": "false", + } + model = models["huggingface"]["models"][0] + endpoint = f"{endpoint['huggingface']['endpoint']}/{model}" + response = requests.post(endpoint, json=payload, headers=headers) + images = [] + print("Trying model", endpoint, "with status code", response.status_code) + if response.status_code == 200: + base64_image = base64.b64encode(response.content) + images.append(base64_image.decode("utf-8")) + return {"generator": self.provider_name(), "images": images} + + def provider_name(self): + return "hf" + + class StableDiffusionImageProvider(ImageProvider): def __init__(self): self.api_key = os.getenv("STABLE_DIFFUSION") @@ -57,7 +159,7 @@ def __init__(self): def generate_images( self, prompt: str, num_images: int, models: list, endpoint: str ) -> list: - for model in models: + for model in models["together"]["models"]: print(f"Trying model {model}") res = requests.post( endpoint, diff --git a/backend/app/domain/services/utils/multi_generator.py b/backend/app/domain/services/utils/multi_generator.py new file mode 100644 index 000000000..c88e5b1e8 --- /dev/null +++ b/backend/app/domain/services/utils/multi_generator.py @@ -0,0 +1,40 @@ +# Copyright (c) MLCommons 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 multiprocessing import Pool + +from app.domain.services.utils.image_generators import ( + DynabenchImageProvider, + HFImageProvider, + OpenAIImageProvider, + SDVariableAutoEncoder, +) + +class ImageGenerator(): + def __init__(self): + self.image_providers = [ + HFImageProvider(), + DynabenchImageProvider(), + OpenAIImageProvider(), + SDVariableAutoEncoder(), + ] + + def generate_images_parallel(self, generator, prompt, num_images, models, endpoint): + return generator.generate_images(prompt, num_images, models, endpoint) + + def generate_all_images( + self, prompt: str, num_images: int, models: list, endpoint: str + ) -> list: + with Pool(len(self.image_providers)) as _: + with Pool() as pool: + results = pool.starmap( + self.generate_images_parallel, + [ + (generator, prompt, num_images, models, endpoint) + for generator in self.image_providers + ], + ) + pool.close() + pool.join() + return results diff --git a/backend/app/infrastructure/models/models.py b/backend/app/infrastructure/models/models.py index 67894762f..3ad2b1864 100644 --- a/backend/app/infrastructure/models/models.py +++ b/backend/app/infrastructure/models/models.py @@ -182,7 +182,7 @@ class Badge(Base): uid = Column(ForeignKey("users.id"), index=True) name = Column(String(255)) metadata_json = Column(Text) - awarded = Column(DateTime) + awarded = Column(DateTime, server_default=func.now(), default=func.now()) user = relationship("User") diff --git a/backend/app/infrastructure/repositories/badge.py b/backend/app/infrastructure/repositories/badge.py index 9987ebfc9..214aa984f 100644 --- a/backend/app/infrastructure/repositories/badge.py +++ b/backend/app/infrastructure/repositories/badge.py @@ -13,3 +13,9 @@ class BadgeRepository(AbstractRepository): def __init__(self) -> None: super().__init__(Badge) + + def add_badge(self, user_id: int, name: str) -> None: + model = self.model(uid=user_id, name=name) + self.session.add(model) + self.session.flush() + self.session.commit() diff --git a/backend/app/infrastructure/repositories/example.py b/backend/app/infrastructure/repositories/example.py index 39d458991..60a376492 100644 --- a/backend/app/infrastructure/repositories/example.py +++ b/backend/app/infrastructure/repositories/example.py @@ -9,7 +9,7 @@ from pydantic import Json from sqlalchemy import func -from app.infrastructure.models.models import Context, Example, Round +from app.infrastructure.models.models import Context, Example, Round, Validation from app.infrastructure.repositories.abstract import AbstractRepository @@ -45,12 +45,18 @@ def create_example( } ) + def get_validates_examples_by_user_id(self, user_id: int): + return ( + self.session.query(Validation.eid).filter(Validation.uid == user_id).all() + ) + def get_example_to_validate( self, real_round_id: int, user_id: int, num_matching_validations: int, ): + validated_examples = self.get_validates_examples_by_user_id(user_id) return ( self.session.query(Example, Context) .join(Context, Example.cid == Context.id) @@ -58,6 +64,7 @@ def get_example_to_validate( .filter(Example.uid != user_id) .filter(Example.retracted == 0) .filter(Example.total_verified < num_matching_validations) + .filter(~Example.id.in_([item[0] for item in validated_examples])) .order_by(func.random()) .first() ) @@ -65,6 +72,8 @@ def get_example_to_validate( def get_example_to_validate_fooling( self, real_round_id: int, user_id: int, num_matching_validations: int ): + validated_examples = self.get_validates_examples_by_user_id(user_id) + return ( self.session.query(Example, Context) .join(Context, Example.cid == Context.id) @@ -73,6 +82,7 @@ def get_example_to_validate_fooling( .filter(Example.retracted == 0) .filter(Example.total_verified < num_matching_validations) .filter(Example.model_wrong == 1) + .filter(~Example.id.in_([item[0] for item in validated_examples])) .order_by(func.random()) .first() ) @@ -81,21 +91,25 @@ def increment_counter_total_verified(self, example_id: int): self.session.query(self.model).filter(self.model.id == example_id).update( {self.model.total_verified: self.model.total_verified + 1} ) + self.session.commit() def increment_counter_total_correct(self, example_id: int): self.session.query(self.model).filter(self.model.id == example_id).update( {self.model.verified_correct: self.model.verified_correct + 1} ) + self.session.commit() def increment_counter_total_incorrect(self, example_id: int): self.session.query(self.model).filter(self.model.id == example_id).update( {self.model.verified_incorrect: self.model.verified_incorrect + 1} ) + self.session.commit() def increment_counter_total_flagged(self, example_id: int): self.session.query(self.model).filter(self.model.id == example_id).update( {self.model.verified_flagged: self.model.verified_flagged + 1} ) + self.session.commit() def mark_as_verified(self, example_id: int): example = self.get_by_id(example_id) @@ -130,3 +144,34 @@ def download_all_created_examples(self, task_id: int): .filter(Round.tid == task_id) .all() ) + + def get_active_tasks_by_user_id(self, user_id: int): + return ( + self.session.query(Round.tid) + .join(Context, Round.id == Context.r_realid) + .join(Example, Context.id == Example.cid) + .filter(Example.uid == user_id) + .distinct() + .all() + ) + + def get_total_examples_by_user_id(self, user_id: int): + return ( + self.session.query(func.count(Example.id)) + .filter(Example.uid == user_id) + .scalar() + ) + + def get_model_fooling_rate_by_user_id(self, user_id: int): + return ( + self.session.query( + func.round( + func.coalesce( + func.sum(Example.model_wrong) / func.count(Example.id), 0 + ), + 2, + ) + ) + .filter(Example.uid == user_id) + .scalar() + ) diff --git a/backend/app/infrastructure/repositories/model.py b/backend/app/infrastructure/repositories/model.py index 83f119d7b..1babe2c0e 100644 --- a/backend/app/infrastructure/repositories/model.py +++ b/backend/app/infrastructure/repositories/model.py @@ -8,7 +8,13 @@ from sqlalchemy.sql import func -from app.infrastructure.models.models import Model +from app.infrastructure.models.models import ( + ChallengesTypes, + Dataset, + Model, + Score, + Task, +) from app.infrastructure.repositories.abstract import AbstractRepository @@ -20,8 +26,7 @@ def get_model_info_by_id(self, model_id: int) -> dict: instance = ( self.session.query(self.model).filter(self.model.id == model_id).one() ) - instance = self.instance_converter.instance_to_dict(instance) - return instance + return self.instance_converter.instance_to_dict(instance) def get_model_in_the_loop(self, task_id: int) -> dict: models_in_the_loop = ( @@ -104,7 +109,7 @@ def get_model_name_by_id(self, id: int) -> str: def get_user_id_by_model_id(self, id: int) -> int: return self.session.query(self.model.uid).filter(self.model.id == id).first() - def get_amount_of_models_per_task(self, task_id: int) -> int: + def get_amount_of_models_by_task(self, task_id: int) -> int: return ( self.session.query(self.model) .filter( @@ -133,3 +138,108 @@ def update_published_status(self, model_id: int): ) self.session.flush() self.session.commit() + + def get_models_by_user_id(self, user_id: int) -> list: + return ( + self.session.query( + Model.id, + Model.name, + Model.is_published, + Model.upload_datetime, + ChallengesTypes.name.label("community"), + Task.name.label("task"), + func.avg(Score.perf).label("score"), + ) + .join(Task, Task.id == self.model.tid) + .join(ChallengesTypes, ChallengesTypes.id == Task.challenge_type) + .join(Score, Score.mid == self.model.id) + .filter(self.model.uid == user_id) + .group_by(self.model.id) + .order_by(self.model.id.desc()) + .all() + ) + + def get_active_tasks_by_user_id(self, user_id): + return ( + self.session.query(self.model.tid) + .filter(self.model.uid == user_id) + .distinct() + .all() + ) + + def get_total_models_by_user_id(self, user_id): + return self.session.query(self.model).filter(self.model.uid == user_id).count() + + def delete_model(self, model_id: int): + self.session.query(Score).filter(Score.mid == model_id).delete() + self.session.query(self.model).filter(self.model.id == model_id).delete() + self.session.flush() + self.session.commit() + + def get_all_model_info_by_id(self, model_id: int): + valid_datasets = ( + self.session.query(Dataset.id) + .join(Model, Model.tid == Dataset.tid) + .join(Task, Task.id == Model.tid) + .filter(Dataset.access_type == "scoring") + .filter(Dataset.tid == Task.id) + .filter(Model.id == model_id) + .all() + ) + has_scores = self.session.query(Score.mid).filter(Score.mid == model_id).all() + query = ( + self.session.query( + Model.id, + Model.name, + Model.desc, + Model.longdesc, + Model.params, + Model.languages, + Model.license, + Model.source_url, + Model.light_model, + Model.deployment_status, + Model.is_in_the_loop, + Model.is_published, + Model.upload_datetime, + ChallengesTypes.name.label("community"), + Task.name.label("task"), + func.coalesce(func.avg(Score.perf), 0).label("score"), + ) + .join(Task, Task.id == self.model.tid) + .join(ChallengesTypes, ChallengesTypes.id == Task.challenge_type) + .outerjoin(Score, Score.mid == self.model.id) + .filter(self.model.id == model_id) + .group_by(self.model.id) + ) + if len(has_scores) != 0: + query = query.filter(Score.did.in_([item[0] for item in valid_datasets])) + return query.one() + + def update_model_info( + self, + model_id: int, + name: str, + desc: str, + longdesc: str, + params: float, + languages: str, + license: str, + source_url: str, + ): + ( + self.session.query(self.model) + .filter(self.model.id == model_id) + .update( + { + "name": name, + "desc": desc, + "longdesc": longdesc, + "params": params, + "languages": languages, + "license": license, + "source_url": source_url, + } + ) + ) + return self.session.commit() diff --git a/backend/app/infrastructure/repositories/score.py b/backend/app/infrastructure/repositories/score.py index c3ddd5ca3..0109a7c92 100644 --- a/backend/app/infrastructure/repositories/score.py +++ b/backend/app/infrastructure/repositories/score.py @@ -42,7 +42,7 @@ def get_scores_by_dataset_and_model_id(self, dataset_id: int, model_id: int): .all() ) - def get_maximun_principal_score_per_task(self, task_id: int, datasets: list): + def get_maximun_principal_score_by_task(self, task_id: int, datasets: list): return ( self.session.query(Model.name, func.avg(Score.perf).label("perf")) .filter(Score.did.in_(datasets)) @@ -65,6 +65,6 @@ def get_downstream_scores(self, dataset_id: int, model_id: int): def check_if_model_has_all_scoring_datasets( self, model_id: int, scoring_datasets: list ) -> bool: - return self.session.query(Score).filter(Score.mid == model_id).filter( - Score.did.in_(scoring_datasets) - ).count() == len(scoring_datasets) + return self.session.query(func.count(Score.did.distinct())).filter( + Score.mid == model_id + ).filter(Score.did.in_(scoring_datasets)).scalar() == len(scoring_datasets) diff --git a/backend/app/infrastructure/repositories/task.py b/backend/app/infrastructure/repositories/task.py index 4ab019e74..ea9bea126 100644 --- a/backend/app/infrastructure/repositories/task.py +++ b/backend/app/infrastructure/repositories/task.py @@ -129,3 +129,10 @@ def get_tasks_with_samples_created_by_user(self, user_id: int): .distinct() .all() ) + + def validate_no_duplicate_task_code(self, task_code: str): + return ( + self.session.query(self.model) + .filter(self.model.task_code == task_code) + .first() + ) diff --git a/backend/app/infrastructure/repositories/taskproposal.py b/backend/app/infrastructure/repositories/taskproposal.py index bbea78ed0..443cf1dce 100644 --- a/backend/app/infrastructure/repositories/taskproposal.py +++ b/backend/app/infrastructure/repositories/taskproposal.py @@ -13,3 +13,16 @@ class TaskProposalRepository(AbstractRepository): def __init__(self) -> None: super().__init__(TaskProposal) + + def add_task_proposal( + self, user_id: int, task_code: str, name: str, desc: str, longdesc: str + ): + return self.add( + { + "uid": user_id, + "task_code": task_code, + "name": name, + "desc": desc, + "longdesc": longdesc, + } + ) diff --git a/backend/app/infrastructure/repositories/user.py b/backend/app/infrastructure/repositories/user.py index 86a68c352..fbacc3259 100644 --- a/backend/app/infrastructure/repositories/user.py +++ b/backend/app/infrastructure/repositories/user.py @@ -6,7 +6,7 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -from app.infrastructure.models.models import User +from app.infrastructure.models.models import Badge, User from app.infrastructure.repositories.abstract import AbstractRepository @@ -93,3 +93,9 @@ def increment_examples_created(self, user_id: int): {self.model.examples_submitted: self.model.examples_submitted + 1} ) self.session.commit() + + def get_badges_by_user_id(self, user_id: int) -> dict: + return self.session.query(Badge).filter(Badge.uid == user_id).all() + + def get_info_by_user_id(self, user_id: int) -> dict: + return self.session.query(self.model).filter(self.model.id == user_id).first() diff --git a/backend/app/infrastructure/repositories/validation.py b/backend/app/infrastructure/repositories/validation.py index c76261e71..bd01695c7 100644 --- a/backend/app/infrastructure/repositories/validation.py +++ b/backend/app/infrastructure/repositories/validation.py @@ -6,7 +6,7 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -from app.infrastructure.models.models import Validation +from app.infrastructure.models.models import Context, Example, Round, Validation from app.infrastructure.repositories.abstract import AbstractRepository @@ -26,3 +26,17 @@ def create_validation( "eid": example_id, } ) + + def get_active_tasks_by_user_id(self, user_id: int): + return ( + self.session.query(Round.tid) + .join(Context, Round.id == Context.r_realid) + .join(Example, Context.id == Example.cid) + .join(self.model, Example.id == self.model.eid) + .filter(Validation.uid == user_id) + .distinct() + .all() + ) + + def get_total_validations_by_user_id(self, user_id: int): + return self.session.query(Validation).filter(Validation.uid == user_id).count() diff --git a/backend/app/main.py b/backend/app/main.py index ddb691af5..5f9ac61b6 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -19,6 +19,8 @@ rounduserexample, score, task, + task_proposals, + user, ) from app.api.endpoints.builder_and_evaluation import evaluation @@ -60,3 +62,7 @@ def read_root(): app.include_router( evaluation.router, prefix="/builder_evaluation/evaluation", tags=["evaluation"] ) +app.include_router(user.router, prefix="/user", tags=["user"]) +app.include_router( + task_proposals.router, prefix="/task_proposals", tags=["task_proposals"] +) diff --git a/dynalab/base-model/Dockerfile b/backend/dynalab/base-model/Dockerfile similarity index 100% rename from dynalab/base-model/Dockerfile rename to backend/dynalab/base-model/Dockerfile diff --git a/dynalab/base-model/Dockerfile.aws.lambda b/backend/dynalab/base-model/Dockerfile.aws.lambda similarity index 100% rename from dynalab/base-model/Dockerfile.aws.lambda rename to backend/dynalab/base-model/Dockerfile.aws.lambda diff --git a/dynalab/base-model/app/api/schemas/__init__.py b/backend/dynalab/base-model/app/__init__.py similarity index 50% rename from dynalab/base-model/app/api/schemas/__init__.py rename to backend/dynalab/base-model/app/__init__.py index 5bc990a69..863195263 100644 --- a/dynalab/base-model/app/api/schemas/__init__.py +++ b/backend/dynalab/base-model/app/__init__.py @@ -1,3 +1,7 @@ +# Copyright (c) MLCommons 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. + # Copyright (c) Facebook, Inc. 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. diff --git a/backend/dynalab/base-model/app/api/__init__.py b/backend/dynalab/base-model/app/api/__init__.py new file mode 100644 index 000000000..863195263 --- /dev/null +++ b/backend/dynalab/base-model/app/api/__init__.py @@ -0,0 +1,7 @@ +# Copyright (c) MLCommons 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. + +# Copyright (c) Facebook, Inc. 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. diff --git a/backend/dynalab/base-model/app/api/endpoints/__init__.py b/backend/dynalab/base-model/app/api/endpoints/__init__.py new file mode 100644 index 000000000..863195263 --- /dev/null +++ b/backend/dynalab/base-model/app/api/endpoints/__init__.py @@ -0,0 +1,7 @@ +# Copyright (c) MLCommons 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. + +# Copyright (c) Facebook, Inc. 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. diff --git a/dynalab/base-model/app/api/endpoints/model.py b/backend/dynalab/base-model/app/api/endpoints/model.py similarity index 76% rename from dynalab/base-model/app/api/endpoints/model.py rename to backend/dynalab/base-model/app/api/endpoints/model.py index 82d5da0e3..3c0208d16 100644 --- a/dynalab/base-model/app/api/endpoints/model.py +++ b/backend/dynalab/base-model/app/api/endpoints/model.py @@ -1,3 +1,7 @@ +# Copyright (c) MLCommons 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. + # Copyright (c) Facebook, Inc. 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. diff --git a/backend/dynalab/base-model/app/api/schemas/__init__.py b/backend/dynalab/base-model/app/api/schemas/__init__.py new file mode 100644 index 000000000..863195263 --- /dev/null +++ b/backend/dynalab/base-model/app/api/schemas/__init__.py @@ -0,0 +1,7 @@ +# Copyright (c) MLCommons 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. + +# Copyright (c) Facebook, Inc. 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. diff --git a/dynalab/base-model/app/api/schemas/model.py b/backend/dynalab/base-model/app/api/schemas/model.py similarity index 65% rename from dynalab/base-model/app/api/schemas/model.py rename to backend/dynalab/base-model/app/api/schemas/model.py index 1adee580b..040f81935 100644 --- a/dynalab/base-model/app/api/schemas/model.py +++ b/backend/dynalab/base-model/app/api/schemas/model.py @@ -1,3 +1,7 @@ +# Copyright (c) MLCommons 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. + # Copyright (c) Facebook, Inc. 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. diff --git a/dynalab/base-model/app/app.py b/backend/dynalab/base-model/app/app.py similarity index 72% rename from dynalab/base-model/app/app.py rename to backend/dynalab/base-model/app/app.py index bd1d29396..9ab790fd5 100644 --- a/dynalab/base-model/app/app.py +++ b/backend/dynalab/base-model/app/app.py @@ -1,3 +1,7 @@ +# Copyright (c) MLCommons 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. + # Copyright (c) Facebook, Inc. 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. diff --git a/backend/dynalab/base-model/app/domain/__init__.py b/backend/dynalab/base-model/app/domain/__init__.py new file mode 100644 index 000000000..863195263 --- /dev/null +++ b/backend/dynalab/base-model/app/domain/__init__.py @@ -0,0 +1,7 @@ +# Copyright (c) MLCommons 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. + +# Copyright (c) Facebook, Inc. 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. diff --git a/dynalab/base-model/app/domain/model.py b/backend/dynalab/base-model/app/domain/model.py similarity index 70% rename from dynalab/base-model/app/domain/model.py rename to backend/dynalab/base-model/app/domain/model.py index e95e3e0e1..6ec6986a4 100644 --- a/dynalab/base-model/app/domain/model.py +++ b/backend/dynalab/base-model/app/domain/model.py @@ -1,3 +1,7 @@ +# Copyright (c) MLCommons 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. + # Copyright (c) Facebook, Inc. 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. diff --git a/dynalab/base-model/requirements.txt b/backend/dynalab/base-model/requirements.txt similarity index 100% rename from dynalab/base-model/requirements.txt rename to backend/dynalab/base-model/requirements.txt diff --git a/dynalab/example/README.md b/backend/dynalab/example/README.md similarity index 100% rename from dynalab/example/README.md rename to backend/dynalab/example/README.md diff --git a/dynalab/example/base-model-nli/Dockerfile b/backend/dynalab/example/base-model-nli/Dockerfile similarity index 100% rename from dynalab/example/base-model-nli/Dockerfile rename to backend/dynalab/example/base-model-nli/Dockerfile diff --git a/dynalab/example/base-model-nli/Dockerfile.aws.lambda b/backend/dynalab/example/base-model-nli/Dockerfile.aws.lambda similarity index 100% rename from dynalab/example/base-model-nli/Dockerfile.aws.lambda rename to backend/dynalab/example/base-model-nli/Dockerfile.aws.lambda diff --git a/dynalab/example/base-model-nli/README.md b/backend/dynalab/example/base-model-nli/README.md similarity index 100% rename from dynalab/example/base-model-nli/README.md rename to backend/dynalab/example/base-model-nli/README.md diff --git a/backend/dynalab/example/base-model-nli/app/__init__.py b/backend/dynalab/example/base-model-nli/app/__init__.py new file mode 100644 index 000000000..863195263 --- /dev/null +++ b/backend/dynalab/example/base-model-nli/app/__init__.py @@ -0,0 +1,7 @@ +# Copyright (c) MLCommons 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. + +# Copyright (c) Facebook, Inc. 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. diff --git a/backend/dynalab/example/base-model-nli/app/api/__init__.py b/backend/dynalab/example/base-model-nli/app/api/__init__.py new file mode 100644 index 000000000..863195263 --- /dev/null +++ b/backend/dynalab/example/base-model-nli/app/api/__init__.py @@ -0,0 +1,7 @@ +# Copyright (c) MLCommons 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. + +# Copyright (c) Facebook, Inc. 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. diff --git a/backend/dynalab/example/base-model-nli/app/api/endpoints/__init__.py b/backend/dynalab/example/base-model-nli/app/api/endpoints/__init__.py new file mode 100644 index 000000000..863195263 --- /dev/null +++ b/backend/dynalab/example/base-model-nli/app/api/endpoints/__init__.py @@ -0,0 +1,7 @@ +# Copyright (c) MLCommons 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. + +# Copyright (c) Facebook, Inc. 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. diff --git a/dynalab/example/base-model-nli/app/api/endpoints/model.py b/backend/dynalab/example/base-model-nli/app/api/endpoints/model.py similarity index 77% rename from dynalab/example/base-model-nli/app/api/endpoints/model.py rename to backend/dynalab/example/base-model-nli/app/api/endpoints/model.py index f61110b0b..9c4620c93 100644 --- a/dynalab/example/base-model-nli/app/api/endpoints/model.py +++ b/backend/dynalab/example/base-model-nli/app/api/endpoints/model.py @@ -1,3 +1,7 @@ +# Copyright (c) MLCommons 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. + # Copyright (c) Facebook, Inc. 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. diff --git a/backend/dynalab/example/base-model-nli/app/api/schemas/__init__.py b/backend/dynalab/example/base-model-nli/app/api/schemas/__init__.py new file mode 100644 index 000000000..863195263 --- /dev/null +++ b/backend/dynalab/example/base-model-nli/app/api/schemas/__init__.py @@ -0,0 +1,7 @@ +# Copyright (c) MLCommons 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. + +# Copyright (c) Facebook, Inc. 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. diff --git a/dynalab/example/base-model-nli/app/api/schemas/model.py b/backend/dynalab/example/base-model-nli/app/api/schemas/model.py similarity index 74% rename from dynalab/example/base-model-nli/app/api/schemas/model.py rename to backend/dynalab/example/base-model-nli/app/api/schemas/model.py index e18d6c6d3..8d45598c5 100644 --- a/dynalab/example/base-model-nli/app/api/schemas/model.py +++ b/backend/dynalab/example/base-model-nli/app/api/schemas/model.py @@ -1,3 +1,7 @@ +# Copyright (c) MLCommons 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. + # Copyright (c) Facebook, Inc. 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. diff --git a/dynalab/example/base-model-nli/app/app.py b/backend/dynalab/example/base-model-nli/app/app.py similarity index 72% rename from dynalab/example/base-model-nli/app/app.py rename to backend/dynalab/example/base-model-nli/app/app.py index 56a97d8a4..d8056c8a1 100644 --- a/dynalab/example/base-model-nli/app/app.py +++ b/backend/dynalab/example/base-model-nli/app/app.py @@ -1,3 +1,7 @@ +# Copyright (c) MLCommons 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. + # Copyright (c) Facebook, Inc. 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. diff --git a/backend/dynalab/example/base-model-nli/app/domain/__init__.py b/backend/dynalab/example/base-model-nli/app/domain/__init__.py new file mode 100644 index 000000000..863195263 --- /dev/null +++ b/backend/dynalab/example/base-model-nli/app/domain/__init__.py @@ -0,0 +1,7 @@ +# Copyright (c) MLCommons 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. + +# Copyright (c) Facebook, Inc. 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. diff --git a/dynalab/example/base-model-nli/app/domain/model.py b/backend/dynalab/example/base-model-nli/app/domain/model.py similarity index 80% rename from dynalab/example/base-model-nli/app/domain/model.py rename to backend/dynalab/example/base-model-nli/app/domain/model.py index a9c07ad5b..9e04c8b73 100644 --- a/dynalab/example/base-model-nli/app/domain/model.py +++ b/backend/dynalab/example/base-model-nli/app/domain/model.py @@ -1,3 +1,7 @@ +# Copyright (c) MLCommons 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. + # Copyright (c) Facebook, Inc. 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. diff --git a/dynalab/example/base-model-nli/requirements.txt b/backend/dynalab/example/base-model-nli/requirements.txt similarity index 100% rename from dynalab/example/base-model-nli/requirements.txt rename to backend/dynalab/example/base-model-nli/requirements.txt diff --git a/dynalab/example/roberta-model-nli/Dockerfile b/backend/dynalab/example/roberta-model-nli/Dockerfile similarity index 100% rename from dynalab/example/roberta-model-nli/Dockerfile rename to backend/dynalab/example/roberta-model-nli/Dockerfile diff --git a/dynalab/example/roberta-model-nli/Dockerfile.aws.lambda b/backend/dynalab/example/roberta-model-nli/Dockerfile.aws.lambda similarity index 100% rename from dynalab/example/roberta-model-nli/Dockerfile.aws.lambda rename to backend/dynalab/example/roberta-model-nli/Dockerfile.aws.lambda diff --git a/backend/dynalab/example/roberta-model-nli/app/__init__.py b/backend/dynalab/example/roberta-model-nli/app/__init__.py new file mode 100644 index 000000000..863195263 --- /dev/null +++ b/backend/dynalab/example/roberta-model-nli/app/__init__.py @@ -0,0 +1,7 @@ +# Copyright (c) MLCommons 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. + +# Copyright (c) Facebook, Inc. 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. diff --git a/backend/dynalab/example/roberta-model-nli/app/api/__init__.py b/backend/dynalab/example/roberta-model-nli/app/api/__init__.py new file mode 100644 index 000000000..863195263 --- /dev/null +++ b/backend/dynalab/example/roberta-model-nli/app/api/__init__.py @@ -0,0 +1,7 @@ +# Copyright (c) MLCommons 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. + +# Copyright (c) Facebook, Inc. 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. diff --git a/backend/dynalab/example/roberta-model-nli/app/api/endpoints/__init__.py b/backend/dynalab/example/roberta-model-nli/app/api/endpoints/__init__.py new file mode 100644 index 000000000..863195263 --- /dev/null +++ b/backend/dynalab/example/roberta-model-nli/app/api/endpoints/__init__.py @@ -0,0 +1,7 @@ +# Copyright (c) MLCommons 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. + +# Copyright (c) Facebook, Inc. 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. diff --git a/dynalab/example/roberta-model-nli/app/api/endpoints/helloworld_router.py b/backend/dynalab/example/roberta-model-nli/app/api/endpoints/helloworld_router.py similarity index 64% rename from dynalab/example/roberta-model-nli/app/api/endpoints/helloworld_router.py rename to backend/dynalab/example/roberta-model-nli/app/api/endpoints/helloworld_router.py index 887eb557e..3d5c65111 100644 --- a/dynalab/example/roberta-model-nli/app/api/endpoints/helloworld_router.py +++ b/backend/dynalab/example/roberta-model-nli/app/api/endpoints/helloworld_router.py @@ -1,3 +1,7 @@ +# Copyright (c) MLCommons 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. + # Copyright (c) Facebook, Inc. 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. diff --git a/dynalab/example/roberta-model-nli/app/api/endpoints/model.py b/backend/dynalab/example/roberta-model-nli/app/api/endpoints/model.py similarity index 80% rename from dynalab/example/roberta-model-nli/app/api/endpoints/model.py rename to backend/dynalab/example/roberta-model-nli/app/api/endpoints/model.py index 0211bbdc4..1f5be1f5a 100644 --- a/dynalab/example/roberta-model-nli/app/api/endpoints/model.py +++ b/backend/dynalab/example/roberta-model-nli/app/api/endpoints/model.py @@ -1,3 +1,7 @@ +# Copyright (c) MLCommons 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. + # Copyright (c) Facebook, Inc. 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. diff --git a/backend/dynalab/example/roberta-model-nli/app/api/schemas/__init__.py b/backend/dynalab/example/roberta-model-nli/app/api/schemas/__init__.py new file mode 100644 index 000000000..863195263 --- /dev/null +++ b/backend/dynalab/example/roberta-model-nli/app/api/schemas/__init__.py @@ -0,0 +1,7 @@ +# Copyright (c) MLCommons 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. + +# Copyright (c) Facebook, Inc. 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. diff --git a/dynalab/example/roberta-model-nli/app/api/schemas/model.py b/backend/dynalab/example/roberta-model-nli/app/api/schemas/model.py similarity index 62% rename from dynalab/example/roberta-model-nli/app/api/schemas/model.py rename to backend/dynalab/example/roberta-model-nli/app/api/schemas/model.py index 323e20465..f406903ba 100644 --- a/dynalab/example/roberta-model-nli/app/api/schemas/model.py +++ b/backend/dynalab/example/roberta-model-nli/app/api/schemas/model.py @@ -1,3 +1,7 @@ +# Copyright (c) MLCommons 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. + # Copyright (c) Facebook, Inc. 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. diff --git a/dynalab/example/roberta-model-nli/app/app.py b/backend/dynalab/example/roberta-model-nli/app/app.py similarity index 76% rename from dynalab/example/roberta-model-nli/app/app.py rename to backend/dynalab/example/roberta-model-nli/app/app.py index 206bae849..8c6f79bfd 100644 --- a/dynalab/example/roberta-model-nli/app/app.py +++ b/backend/dynalab/example/roberta-model-nli/app/app.py @@ -1,3 +1,7 @@ +# Copyright (c) MLCommons 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. + # Copyright (c) Facebook, Inc. 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. diff --git a/backend/dynalab/example/roberta-model-nli/app/domain/__init__.py b/backend/dynalab/example/roberta-model-nli/app/domain/__init__.py new file mode 100644 index 000000000..863195263 --- /dev/null +++ b/backend/dynalab/example/roberta-model-nli/app/domain/__init__.py @@ -0,0 +1,7 @@ +# Copyright (c) MLCommons 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. + +# Copyright (c) Facebook, Inc. 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. diff --git a/dynalab/example/roberta-model-nli/app/domain/model.py b/backend/dynalab/example/roberta-model-nli/app/domain/model.py similarity index 89% rename from dynalab/example/roberta-model-nli/app/domain/model.py rename to backend/dynalab/example/roberta-model-nli/app/domain/model.py index 6ecde480c..f996f9039 100644 --- a/dynalab/example/roberta-model-nli/app/domain/model.py +++ b/backend/dynalab/example/roberta-model-nli/app/domain/model.py @@ -1,3 +1,7 @@ +# Copyright (c) MLCommons 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. + # Copyright (c) Facebook, Inc. 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. diff --git a/dynalab/example/roberta-model-nli/requirements.txt b/backend/dynalab/example/roberta-model-nli/requirements.txt similarity index 100% rename from dynalab/example/roberta-model-nli/requirements.txt rename to backend/dynalab/example/roberta-model-nli/requirements.txt diff --git a/dynalab/img/check_output.png b/backend/dynalab/img/check_output.png similarity index 100% rename from dynalab/img/check_output.png rename to backend/dynalab/img/check_output.png diff --git a/dynalab/img/fast_api_swager.png b/backend/dynalab/img/fast_api_swager.png similarity index 100% rename from dynalab/img/fast_api_swager.png rename to backend/dynalab/img/fast_api_swager.png diff --git a/dynalab/img/fill_request.png b/backend/dynalab/img/fill_request.png similarity index 100% rename from dynalab/img/fill_request.png rename to backend/dynalab/img/fill_request.png diff --git a/dynalab/img/input_format.png b/backend/dynalab/img/input_format.png similarity index 100% rename from dynalab/img/input_format.png rename to backend/dynalab/img/input_format.png diff --git a/dynalab/img/output_format.png b/backend/dynalab/img/output_format.png similarity index 100% rename from dynalab/img/output_format.png rename to backend/dynalab/img/output_format.png diff --git a/dynalab/img/output_schema.png b/backend/dynalab/img/output_schema.png similarity index 100% rename from dynalab/img/output_schema.png rename to backend/dynalab/img/output_schema.png diff --git a/dynalab/img/requirements.png b/backend/dynalab/img/requirements.png similarity index 100% rename from dynalab/img/requirements.png rename to backend/dynalab/img/requirements.png diff --git a/dynalab/img/resources_folder.png b/backend/dynalab/img/resources_folder.png similarity index 100% rename from dynalab/img/resources_folder.png rename to backend/dynalab/img/resources_folder.png diff --git a/dynalab/img/schema.png b/backend/dynalab/img/schema.png similarity index 100% rename from dynalab/img/schema.png rename to backend/dynalab/img/schema.png diff --git a/dynalab/img/try_out.png b/backend/dynalab/img/try_out.png similarity index 100% rename from dynalab/img/try_out.png rename to backend/dynalab/img/try_out.png diff --git a/dynalab/readme.md b/backend/dynalab/readme.md similarity index 100% rename from dynalab/readme.md rename to backend/dynalab/readme.md diff --git a/backend/requirements.txt b/backend/requirements.txt index c2cf9fb72..bca62a76a 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -14,10 +14,10 @@ werkzeug==2.0.2 docker==5.0.3 sqlacodegen==2.3.0 PyYaml==6.0 -numpy==1.21.2 +numpy sacrebleu==2.3.1 sentencepiece==0.1.96 -scikit-learn==1.1.3 +scikit-learn cloudwatch==1.0.5 jsonlines==3.1.0 gunicorn==20.1.0 @@ -27,3 +27,4 @@ python-jose openai==0.27.2 nltk==3.6.5 langchain==0.0.218 +sse_starlette==0.0.17 \ No newline at end of file diff --git a/dynalab/base-model/app/__init__.py b/dynalab/base-model/app/__init__.py deleted file mode 100644 index 5bc990a69..000000000 --- a/dynalab/base-model/app/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright (c) Facebook, Inc. 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. diff --git a/dynalab/base-model/app/api/__init__.py b/dynalab/base-model/app/api/__init__.py deleted file mode 100644 index 5bc990a69..000000000 --- a/dynalab/base-model/app/api/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright (c) Facebook, Inc. 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. diff --git a/dynalab/base-model/app/api/endpoints/__init__.py b/dynalab/base-model/app/api/endpoints/__init__.py deleted file mode 100644 index 5bc990a69..000000000 --- a/dynalab/base-model/app/api/endpoints/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright (c) Facebook, Inc. 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. diff --git a/dynalab/base-model/app/domain/__init__.py b/dynalab/base-model/app/domain/__init__.py deleted file mode 100644 index 5bc990a69..000000000 --- a/dynalab/base-model/app/domain/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright (c) Facebook, Inc. 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. diff --git a/dynalab/example/base-model-nli/app/__init__.py b/dynalab/example/base-model-nli/app/__init__.py deleted file mode 100644 index 5bc990a69..000000000 --- a/dynalab/example/base-model-nli/app/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright (c) Facebook, Inc. 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. diff --git a/dynalab/example/base-model-nli/app/api/__init__.py b/dynalab/example/base-model-nli/app/api/__init__.py deleted file mode 100644 index 5bc990a69..000000000 --- a/dynalab/example/base-model-nli/app/api/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright (c) Facebook, Inc. 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. diff --git a/dynalab/example/base-model-nli/app/api/endpoints/__init__.py b/dynalab/example/base-model-nli/app/api/endpoints/__init__.py deleted file mode 100644 index 5bc990a69..000000000 --- a/dynalab/example/base-model-nli/app/api/endpoints/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright (c) Facebook, Inc. 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. diff --git a/dynalab/example/base-model-nli/app/api/schemas/__init__.py b/dynalab/example/base-model-nli/app/api/schemas/__init__.py deleted file mode 100644 index 5bc990a69..000000000 --- a/dynalab/example/base-model-nli/app/api/schemas/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright (c) Facebook, Inc. 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. diff --git a/dynalab/example/base-model-nli/app/domain/__init__.py b/dynalab/example/base-model-nli/app/domain/__init__.py deleted file mode 100644 index 5bc990a69..000000000 --- a/dynalab/example/base-model-nli/app/domain/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright (c) Facebook, Inc. 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. diff --git a/dynalab/example/roberta-model-nli/app/__init__.py b/dynalab/example/roberta-model-nli/app/__init__.py deleted file mode 100644 index 5bc990a69..000000000 --- a/dynalab/example/roberta-model-nli/app/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright (c) Facebook, Inc. 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. diff --git a/dynalab/example/roberta-model-nli/app/api/__init__.py b/dynalab/example/roberta-model-nli/app/api/__init__.py deleted file mode 100644 index 5bc990a69..000000000 --- a/dynalab/example/roberta-model-nli/app/api/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright (c) Facebook, Inc. 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. diff --git a/dynalab/example/roberta-model-nli/app/api/endpoints/__init__.py b/dynalab/example/roberta-model-nli/app/api/endpoints/__init__.py deleted file mode 100644 index 5bc990a69..000000000 --- a/dynalab/example/roberta-model-nli/app/api/endpoints/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright (c) Facebook, Inc. 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. diff --git a/dynalab/example/roberta-model-nli/app/api/schemas/__init__.py b/dynalab/example/roberta-model-nli/app/api/schemas/__init__.py deleted file mode 100644 index 5bc990a69..000000000 --- a/dynalab/example/roberta-model-nli/app/api/schemas/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright (c) Facebook, Inc. 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. diff --git a/dynalab/example/roberta-model-nli/app/domain/__init__.py b/dynalab/example/roberta-model-nli/app/domain/__init__.py deleted file mode 100644 index 5bc990a69..000000000 --- a/dynalab/example/roberta-model-nli/app/domain/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright (c) Facebook, Inc. 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. diff --git a/frontends/web/package-lock.json b/frontends/web/package-lock.json index e0e53e4e5..0c77159dc 100644 --- a/frontends/web/package-lock.json +++ b/frontends/web/package-lock.json @@ -8,6 +8,11 @@ "name": "Dynabench-frontend", "version": "0.1.0", "dependencies": { + "@emotion/react": "^11.11.1", + "@emotion/styled": "^11.11.0", + "@microsoft/fetch-event-source": "^2.0.1", + "@mui/icons-material": "^5.14.3", + "@mui/material": "^5.14.3", "@tailwindcss/line-clamp": "^0.4.2", "@testing-library/jest-dom": "^4.2.4", "@testing-library/react": "^9.5.0", @@ -18,13 +23,14 @@ "bootstrap-switch-button-react": "^1.2.0", "css-loader": "^3.6.0", "downloadjs": "^1.4.7", - "formik": "^2.1.4", + "formik": "^2.4.2", "framer-motion": "^10.11.2", "highcharts": "^9.1.0", "highcharts-react-official": "^3.0.0", "html-react-parser": "^3.0.15", "js-yaml": "^4.1.0", "jwt-decode": "^2.2.0", + "material-react-table": "^1.14.0", "mephisto-task": "^1.0.10", "moment": "^2.24.0", "prop-types": "^15.7.2", @@ -51,6 +57,7 @@ "react-router-hash-link": "^2.4.3", "react-scripts": "5.0.1", "react-scroll": "^1.8.9", + "react-scroll-parallax": "^3.4.2", "react-select": "^5.2.1", "react-spinners": "^0.13.8", "react-string-diff": "^0.2.0", @@ -61,7 +68,8 @@ "style-loader": "^1.2.1", "sweetalert2": "^11.6.14", "typescript": "^4.9.5", - "use-http": "^1.0.27" + "use-http": "^1.0.27", + "yup": "^1.2.0" }, "devDependencies": { "@babel/core": "^7.10.5", @@ -1823,9 +1831,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.20.13", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.13.tgz", - "integrity": "sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz", + "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==", "dependencies": { "regenerator-runtime": "^0.13.11" }, @@ -2342,22 +2350,69 @@ "postcss-selector-parser": "^6.0.10" } }, + "node_modules/@emotion/babel-plugin": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", + "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/serialize": "^1.1.2", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/babel-plugin/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==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + }, "node_modules/@emotion/cache": { - "version": "11.6.0", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.6.0.tgz", - "integrity": "sha512-ElbsWY1KMwEowkv42vGo0UPuLgtPYfIs9BxxVrmvsaJVvktknsHYYlx5NQ5g6zLDcOTyamlDc7FkRg2TAcQDKQ==", + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", + "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", "dependencies": { - "@emotion/memoize": "^0.7.4", - "@emotion/sheet": "^1.1.0", - "@emotion/utils": "^1.0.0", - "@emotion/weak-memoize": "^0.2.5", - "stylis": "^4.0.10" + "@emotion/memoize": "^0.8.1", + "@emotion/sheet": "^1.2.2", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "stylis": "4.2.0" } }, + "node_modules/@emotion/cache/node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + }, "node_modules/@emotion/hash": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", - "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==" + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", + "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" }, "node_modules/@emotion/is-prop-valid": { "version": "0.8.8", @@ -2373,67 +2428,107 @@ "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==" }, "node_modules/@emotion/memoize": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.5.tgz", - "integrity": "sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ==" + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" }, "node_modules/@emotion/react": { - "version": "11.6.0", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.6.0.tgz", - "integrity": "sha512-23MnRZFBN9+D1lHXC5pD6z4X9yhPxxtHr6f+iTGz6Fv6Rda0GdefPrsHL7otsEf+//7uqCdT5QtHeRxHCERzuw==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@emotion/cache": "^11.6.0", - "@emotion/serialize": "^1.0.2", - "@emotion/sheet": "^1.1.0", - "@emotion/utils": "^1.0.0", - "@emotion/weak-memoize": "^0.2.5", + "version": "11.11.1", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.1.tgz", + "integrity": "sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/cache": "^11.11.0", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", "hoist-non-react-statics": "^3.3.1" }, "peerDependencies": { - "@babel/core": "^7.0.0", "react": ">=16.8.0" }, "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, "@types/react": { "optional": true } } }, "node_modules/@emotion/serialize": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.0.2.tgz", - "integrity": "sha512-95MgNJ9+/ajxU7QIAruiOAdYNjxZX7G2mhgrtDWswA21VviYIRP1R5QilZ/bDY42xiKsaktP4egJb3QdYQZi1A==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.2.tgz", + "integrity": "sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==", "dependencies": { - "@emotion/hash": "^0.8.0", - "@emotion/memoize": "^0.7.4", - "@emotion/unitless": "^0.7.5", - "@emotion/utils": "^1.0.0", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/unitless": "^0.8.1", + "@emotion/utils": "^1.2.1", "csstype": "^3.0.2" } }, + "node_modules/@emotion/serialize/node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + }, "node_modules/@emotion/sheet": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.1.0.tgz", - "integrity": "sha512-u0AX4aSo25sMAygCuQTzS+HsImZFuS8llY8O7b9MDRzbJM0kVJlAz6KNDqcG7pOuQZJmj/8X/rAW+66kMnMW+g==" + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", + "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" + }, + "node_modules/@emotion/styled": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.0.tgz", + "integrity": "sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/is-prop-valid": "^1.2.1", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/styled/node_modules/@emotion/is-prop-valid": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz", + "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==", + "dependencies": { + "@emotion/memoize": "^0.8.1" + } }, "node_modules/@emotion/unitless": { "version": "0.7.5", "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", + "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", + "peerDependencies": { + "react": ">=16.8.0" + } + }, "node_modules/@emotion/utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.0.0.tgz", - "integrity": "sha512-mQC2b3XLDs6QCW+pDQDiyO/EdGZYOygE8s5N5rrzjSI4M3IejPE/JPndCBwRT9z982aqQNi6beWs1UeayrQxxA==" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", + "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" }, "node_modules/@emotion/weak-memoize": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz", - "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==" + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", + "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" }, "node_modules/@eslint/eslintrc": { "version": "1.4.1", @@ -3216,6 +3311,281 @@ "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" }, + "node_modules/@microsoft/fetch-event-source": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@microsoft/fetch-event-source/-/fetch-event-source-2.0.1.tgz", + "integrity": "sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA==" + }, + "node_modules/@mui/base": { + "version": "5.0.0-beta.8", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.8.tgz", + "integrity": "sha512-b4vVjMZx5KzzEMf4arXKoeV5ZegAMOoPwoy1vfUBwhvXc2QtaaAyBp50U7OA2L06Leubc1A+lEp3eqwZoFn87g==", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.22.6", + "@emotion/is-prop-valid": "^1.2.1", + "@mui/types": "^7.2.4", + "@mui/utils": "^5.14.1", + "@popperjs/core": "^2.11.8", + "clsx": "^2.0.0", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/base/node_modules/@emotion/is-prop-valid": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz", + "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==", + "dependencies": { + "@emotion/memoize": "^0.8.1" + } + }, + "node_modules/@mui/base/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/@mui/core-downloads-tracker": { + "version": "5.14.1", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.1.tgz", + "integrity": "sha512-mIa1WmDmNr1LoupV1Rbxt9bTFKMbIn10RHG1bnZ/FJCkAYpuU/D4n+R+ttiycgcZNngU++zyh/OQeJblzbQPzg==", + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + } + }, + "node_modules/@mui/icons-material": { + "version": "5.14.1", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.14.1.tgz", + "integrity": "sha512-xV/f26muQqtWzerzOIdGPrXoxp/OKaE2G2Wp9gnmG47mHua5Slup/tMc3fA4ZYUreGGrK6+tT81TEvt1Wsng8Q==", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.22.6" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@mui/material": "^5.0.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material": { + "version": "5.14.1", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.14.1.tgz", + "integrity": "sha512-WtsgYuageTunLfxH3Ri+o1RuQTFImtRHxMcVNyD0Hhd2/znjW6KODNz0XfjvLRnNCAynBxZNiflcoIBW40h9PQ==", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.22.6", + "@mui/base": "5.0.0-beta.8", + "@mui/core-downloads-tracker": "^5.14.1", + "@mui/system": "^5.14.1", + "@mui/types": "^7.2.4", + "@mui/utils": "^5.14.1", + "@types/react-transition-group": "^4.4.6", + "clsx": "^2.0.0", + "csstype": "^3.1.2", + "prop-types": "^15.8.1", + "react-is": "^18.2.0", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/@mui/private-theming": { + "version": "5.13.7", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.13.7.tgz", + "integrity": "sha512-qbSr+udcij5F9dKhGX7fEdx2drXchq7htLNr2Qg2Ma+WJ6q0ERlEqGSBiPiVDJkptcjeVL4DGmcf1wl5+vD4EA==", + "dependencies": { + "@babel/runtime": "^7.22.5", + "@mui/utils": "^5.13.7", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/styled-engine": { + "version": "5.13.2", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.13.2.tgz", + "integrity": "sha512-VCYCU6xVtXOrIN8lcbuPmoG+u7FYuOERG++fpY74hPpEWkyFQG97F+/XfTQVYzlR2m7nPjnwVUgATcTCMEaMvw==", + "dependencies": { + "@babel/runtime": "^7.21.0", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.2", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.3.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/system": { + "version": "5.14.1", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.14.1.tgz", + "integrity": "sha512-u+xlsU34Jdkgx1CxmBnIC4Y08uPdVX5iEd3S/1dggDFtOGp+Lj8xmKRJAQ8PJOOJLOh8pDwaZx4AwXikL4l1QA==", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.22.6", + "@mui/private-theming": "^5.13.7", + "@mui/styled-engine": "^5.13.2", + "@mui/types": "^7.2.4", + "@mui/utils": "^5.14.1", + "clsx": "^1.2.1", + "csstype": "^3.1.2", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/types": { + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.4.tgz", + "integrity": "sha512-LBcwa8rN84bKF+f5sDyku42w1NTxaPgPyYKODsh01U1fVstTClbUoSA96oyRBnSNyEiAVjKm6Gwx9vjR+xyqHA==", + "peerDependencies": { + "@types/react": "*" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "5.14.1", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.14.1.tgz", + "integrity": "sha512-39KHKK2JeqRmuUcLDLwM+c2XfVC136C5/yUyQXmO2PVbOb2Bol4KxtkssEqCbTwg87PSCG3f1Tb0keRsK7cVGw==", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.22.6", + "@types/prop-types": "^15.7.5", + "@types/react-is": "^18.2.1", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0" + } + }, + "node_modules/@mui/utils/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { "version": "5.1.1-v1", "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", @@ -3393,9 +3763,9 @@ } }, "node_modules/@popperjs/core": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.7.tgz", - "integrity": "sha512-Cr4OjIkipTtcXKjAsm8agyleBuDHvxzeBoa1v543lbv1YaIwQjESsVcmjiWiPEbC1FIeHOG/Op9kdCmAmiS3Kw==", + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" @@ -3811,6 +4181,76 @@ "tailwindcss": ">=2.0.0 || >=3.0.0 || >=3.0.0-alpha.1" } }, + "node_modules/@tanstack/match-sorter-utils": { + "version": "8.8.4", + "resolved": "https://registry.npmjs.org/@tanstack/match-sorter-utils/-/match-sorter-utils-8.8.4.tgz", + "integrity": "sha512-rKH8LjZiszWEvmi01NR72QWZ8m4xmXre0OOwlRGnjU01Eqz/QnN+cqpty2PJ0efHblq09+KilvyR7lsbzmXVEw==", + "dependencies": { + "remove-accents": "0.4.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kentcdodds" + } + }, + "node_modules/@tanstack/react-table": { + "version": "8.9.2", + "resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.9.2.tgz", + "integrity": "sha512-Irvw4wqVF9hhuYzmNrlae4IKdlmgSyoRWnApSLebvYzqHoi5tEsYzBj6YPd0hX78aB/L+4w/jgK2eBQVpGfThQ==", + "dependencies": { + "@tanstack/table-core": "8.9.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": ">=16", + "react-dom": ">=16" + } + }, + "node_modules/@tanstack/react-virtual": { + "version": "3.0.0-beta.54", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.0.0-beta.54.tgz", + "integrity": "sha512-D1mDMf4UPbrtHRZZriCly5bXTBMhylslm4dhcHqTtDJ6brQcgGmk8YD9JdWBGWfGSWPKoh2x1H3e7eh+hgPXtQ==", + "dependencies": { + "@tanstack/virtual-core": "3.0.0-beta.54" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@tanstack/table-core": { + "version": "8.9.2", + "resolved": "https://registry.npmjs.org/@tanstack/table-core/-/table-core-8.9.2.tgz", + "integrity": "sha512-ajc0OF+karBAdaSz7OK09rCoAHB1XI1+wEhu+tDNMPc+XcO+dTlXXN/Vc0a8vym4kElvEjXEDd9c8Zfgt4bekA==", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/virtual-core": { + "version": "3.0.0-beta.54", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.0.0-beta.54.tgz", + "integrity": "sha512-jtkwqdP2rY2iCCDVAFuaNBH3fiEi29aTn2RhtIoky8DTTiCdc48plpHHreLwmv1PICJ4AJUUESaq3xa8fZH8+g==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, "node_modules/@testing-library/dom": { "version": "8.6.0", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.6.0.tgz", @@ -4464,9 +4904,9 @@ "integrity": "sha512-ZTaqn/qSqUuAq1YwvOFQfVW1AR/oQJlLSZVustdjwI+GZ8kr0MSHBj0tsXPW1EqHubx50gtBEjbPGsdZwQwCjQ==" }, "node_modules/@types/prop-types": { - "version": "15.7.4", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz", - "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==" + "version": "15.7.5", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" }, "node_modules/@types/q": { "version": "1.5.5", @@ -4501,6 +4941,14 @@ "@types/react": "*" } }, + "node_modules/@types/react-is": { + "version": "18.2.1", + "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-18.2.1.tgz", + "integrity": "sha512-wyUkmaaSZEzFZivD8F2ftSyAfk6L+DfFliVj/mYdOXbVjRcS87fQJLTnhk6dRZPuJjI+9g6RZJO4PNCngUrmyw==", + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/react-lazy-load-image-component": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/@types/react-lazy-load-image-component/-/react-lazy-load-image-component-1.5.2.tgz", @@ -4542,9 +4990,9 @@ } }, "node_modules/@types/react-transition-group": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.3.tgz", - "integrity": "sha512-fUx5muOWSYP8Bw2BUQ9M9RK9+W1XBK/7FLJ8PTQpnpTEkn0ccyMffyEQvan4C3h53gHdx7KE5Qrxi/LnUGQtdg==", + "version": "4.4.6", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.6.tgz", + "integrity": "sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew==", "dependencies": { "@types/react": "*" } @@ -6444,6 +6892,11 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/bezier-easing": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/bezier-easing/-/bezier-easing-2.1.0.tgz", + "integrity": "sha512-gbIqZ/eslnUFC1tjEvtz0sgx+xTK20wDnYMIA27VA04R7w6xxXQPZDbibjA9DTWZRA2CXtwHykkVzlCaAJAZig==" + }, "node_modules/bfj": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/bfj/-/bfj-7.0.2.tgz", @@ -6963,6 +7416,14 @@ "node": ">=6" } }, + "node_modules/clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", + "engines": { + "node": ">=6" + } + }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -7726,9 +8187,9 @@ "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" }, "node_modules/csstype": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.9.tgz", - "integrity": "sha512-rpw6JPxK6Rfg1zLOYCSwle2GFOOsnjmDYDaBwEcwoOg4qlsIVCN789VkBZDJAGi4T07gI4YSutR43t9Zz4Lzuw==" + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" }, "node_modules/d3": { "version": "3.5.17", @@ -9858,6 +10319,11 @@ "url": "https://github.com/avajs/find-cache-dir?sponsor=1" } }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, "node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -10106,9 +10572,9 @@ } }, "node_modules/formik": { - "version": "2.2.9", - "resolved": "https://registry.npmjs.org/formik/-/formik-2.2.9.tgz", - "integrity": "sha512-LQLcISMmf1r5at4/gyJigGn0gOwFbeEAlji+N9InZF6LIMXnFNkO42sCI8Jt84YZggpD4cPWObAZaxpEFtSzNA==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/formik/-/formik-2.4.2.tgz", + "integrity": "sha512-C6nx0hifW2uENP3M6HpPmnAE6HFWCcd8/sqBZEOHZY6lpHJ5qehsfAy43ktpFLEmkBmhiZDei726utcUB9leqg==", "funding": [ { "type": "individual", @@ -10122,12 +10588,17 @@ "lodash-es": "^4.17.21", "react-fast-compare": "^2.0.1", "tiny-warning": "^1.0.2", - "tslib": "^1.10.0" + "tslib": "^2.0.0" }, "peerDependencies": { "react": ">=16.8.0" } }, + "node_modules/formik/node_modules/tslib": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz", + "integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==" + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -10999,6 +11470,15 @@ "react": ">=16.8.0" } }, + "node_modules/highlight-words": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/highlight-words/-/highlight-words-1.2.2.tgz", + "integrity": "sha512-Mf4xfPXYm8Ay1wTibCrHpNWeR2nUMynMVFkXCi4mbl+TEgmNOe+I4hV7W3OCZcSvzGL6kupaqpfHOemliMTGxQ==", + "engines": { + "node": ">= 16", + "npm": ">= 8" + } + }, "node_modules/history": { "version": "4.10.1", "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", @@ -14284,6 +14764,12 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/jquery": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.0.tgz", + "integrity": "sha512-umpJ0/k8X0MvD1ds0P9SfowREz2LenHsQaxSohMZ5OMNEU2r0tf8pdeEFTHMFxWVxKNyU9rTtK3CWzUCTKJUeQ==", + "peer": true + }, "node_modules/js-sdsl": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", @@ -14803,6 +15289,32 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/material-react-table": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/material-react-table/-/material-react-table-1.14.0.tgz", + "integrity": "sha512-DMajcZwsduHfT/pfp9BiSX4qSXvj6I4fGlg6UiD7x3Ubj1EY004UK83AQIU+s8ZIC+uXObHX3OL/MiMw+qjNJg==", + "dependencies": { + "@tanstack/match-sorter-utils": "8.8.4", + "@tanstack/react-table": "8.9.2", + "@tanstack/react-virtual": "3.0.0-beta.54", + "highlight-words": "1.2.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kevinvandy" + }, + "peerDependencies": { + "@emotion/react": ">=11", + "@emotion/styled": ">=11", + "@mui/icons-material": ">=5", + "@mui/material": ">=5", + "react": ">=17.0", + "react-dom": ">=17.0" + } + }, "node_modules/math-expression-evaluator": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.3.8.tgz", @@ -17099,6 +17611,17 @@ "node": ">=6" } }, + "node_modules/parallax-controller": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/parallax-controller/-/parallax-controller-1.7.0.tgz", + "integrity": "sha512-tIU/LgH9oIrvC6o+rvGQis8/NXxsHNuF5LODmcc5TjvEDUi2qiR/iisFmyaqI9LImQ3psdAv28k2ZEAnFekiig==", + "dependencies": { + "bezier-easing": "^2.1.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/param-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", @@ -17333,6 +17856,17 @@ "node": ">=4" } }, + "node_modules/popper.js": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz", + "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==", + "deprecated": "You can find the new Popper v2 at @popperjs/core, this package is dedicated to the legacy v1", + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, "node_modules/postcss": { "version": "8.4.21", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", @@ -19014,6 +19548,11 @@ "react-is": "^16.13.1" } }, + "node_modules/property-expr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.5.tgz", + "integrity": "sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA==" + }, "node_modules/property-information": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.2.0.tgz", @@ -20793,6 +21332,21 @@ "react-dom": "^15.5.4 || ^16.0.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/react-scroll-parallax": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/react-scroll-parallax/-/react-scroll-parallax-3.4.2.tgz", + "integrity": "sha512-jNltdM1a6y2TRHW4X4nyNT9BAzbLoISTvXaoB9YKGudVcAsGWManMI6UZ6PMd2si6bbWtTROgF/A9IoplZ2OLA==", + "dependencies": { + "parallax-controller": "^1.7.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": "^16.8.0-0 || >=17.0.1 || ^18.0.0", + "react-dom": "^16.8.0-0 || >=17.0.1 || ^18.0.0" + } + }, "node_modules/react-select": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.2.1.tgz", @@ -22649,6 +23203,11 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/remove-accents": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz", + "integrity": "sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA==" + }, "node_modules/renderkid": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", @@ -23875,11 +24434,6 @@ "react-dom": ">= 16.3.0" } }, - "node_modules/styled-components/node_modules/stylis": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-3.5.4.tgz", - "integrity": "sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q==" - }, "node_modules/stylehacks": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", @@ -24151,9 +24705,9 @@ } }, "node_modules/stylis": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.10.tgz", - "integrity": "sha512-m3k+dk7QeJw660eIKRRn3xPF6uuvHs/FFzjX3HQ5ove0qYsiygoAhwn5a3IYKaZPo5LrYD0rfVmtv1gNY1uYwg==" + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-3.5.4.tgz", + "integrity": "sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q==" }, "node_modules/stylis-rule-sheet": { "version": "0.0.10", @@ -24647,6 +25201,11 @@ "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" }, + "node_modules/tiny-case": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz", + "integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==" + }, "node_modules/tiny-invariant": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", @@ -24689,6 +25248,11 @@ "node": ">=0.6" } }, + "node_modules/toposort": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", + "integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==" + }, "node_modules/tough-cookie": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz", @@ -26376,6 +26940,28 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/yup": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/yup/-/yup-1.2.0.tgz", + "integrity": "sha512-PPqYKSAXjpRCgLgLKVGPA33v5c/WgEx3wi6NFjIiegz90zSwyMpvTFp/uGcVnnbx6to28pgnzp/q8ih3QRjLMQ==", + "dependencies": { + "property-expr": "^2.0.5", + "tiny-case": "^1.0.3", + "toposort": "^2.0.2", + "type-fest": "^2.19.0" + } + }, + "node_modules/yup/node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/zwitch": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", @@ -27545,9 +28131,9 @@ } }, "@babel/runtime": { - "version": "7.20.13", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.13.tgz", - "integrity": "sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz", + "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==", "requires": { "regenerator-runtime": "^0.13.11" } @@ -27809,22 +28395,64 @@ "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.1.1.tgz", "integrity": "sha512-jwx+WCqszn53YHOfvFMJJRd/B2GqkCBt+1MJSG6o5/s8+ytHMvDZXsJgUEWLk12UnLd7HYKac4BYU5i/Ron1Cw==" }, + "@emotion/babel-plugin": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", + "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", + "requires": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/serialize": "^1.1.2", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==" + }, + "stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + } + } + }, "@emotion/cache": { - "version": "11.6.0", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.6.0.tgz", - "integrity": "sha512-ElbsWY1KMwEowkv42vGo0UPuLgtPYfIs9BxxVrmvsaJVvktknsHYYlx5NQ5g6zLDcOTyamlDc7FkRg2TAcQDKQ==", + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", + "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", "requires": { - "@emotion/memoize": "^0.7.4", - "@emotion/sheet": "^1.1.0", - "@emotion/utils": "^1.0.0", - "@emotion/weak-memoize": "^0.2.5", - "stylis": "^4.0.10" + "@emotion/memoize": "^0.8.1", + "@emotion/sheet": "^1.2.2", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "stylis": "4.2.0" + }, + "dependencies": { + "stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + } } }, "@emotion/hash": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", - "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==" + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", + "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" }, "@emotion/is-prop-valid": { "version": "0.8.8", @@ -27842,55 +28470,91 @@ } }, "@emotion/memoize": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.5.tgz", - "integrity": "sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ==" + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" }, "@emotion/react": { - "version": "11.6.0", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.6.0.tgz", - "integrity": "sha512-23MnRZFBN9+D1lHXC5pD6z4X9yhPxxtHr6f+iTGz6Fv6Rda0GdefPrsHL7otsEf+//7uqCdT5QtHeRxHCERzuw==", - "requires": { - "@babel/runtime": "^7.13.10", - "@emotion/cache": "^11.6.0", - "@emotion/serialize": "^1.0.2", - "@emotion/sheet": "^1.1.0", - "@emotion/utils": "^1.0.0", - "@emotion/weak-memoize": "^0.2.5", + "version": "11.11.1", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.1.tgz", + "integrity": "sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==", + "requires": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/cache": "^11.11.0", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", "hoist-non-react-statics": "^3.3.1" } }, "@emotion/serialize": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.0.2.tgz", - "integrity": "sha512-95MgNJ9+/ajxU7QIAruiOAdYNjxZX7G2mhgrtDWswA21VviYIRP1R5QilZ/bDY42xiKsaktP4egJb3QdYQZi1A==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.2.tgz", + "integrity": "sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==", "requires": { - "@emotion/hash": "^0.8.0", - "@emotion/memoize": "^0.7.4", - "@emotion/unitless": "^0.7.5", - "@emotion/utils": "^1.0.0", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/unitless": "^0.8.1", + "@emotion/utils": "^1.2.1", "csstype": "^3.0.2" + }, + "dependencies": { + "@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + } } }, "@emotion/sheet": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.1.0.tgz", - "integrity": "sha512-u0AX4aSo25sMAygCuQTzS+HsImZFuS8llY8O7b9MDRzbJM0kVJlAz6KNDqcG7pOuQZJmj/8X/rAW+66kMnMW+g==" + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", + "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" + }, + "@emotion/styled": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.0.tgz", + "integrity": "sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==", + "requires": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/is-prop-valid": "^1.2.1", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1" + }, + "dependencies": { + "@emotion/is-prop-valid": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz", + "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==", + "requires": { + "@emotion/memoize": "^0.8.1" + } + } + } }, "@emotion/unitless": { "version": "0.7.5", "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" }, + "@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", + "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==" + }, "@emotion/utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.0.0.tgz", - "integrity": "sha512-mQC2b3XLDs6QCW+pDQDiyO/EdGZYOygE8s5N5rrzjSI4M3IejPE/JPndCBwRT9z982aqQNi6beWs1UeayrQxxA==" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", + "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" }, "@emotion/weak-memoize": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz", - "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==" + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", + "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" }, "@eslint/eslintrc": { "version": "1.4.1", @@ -28473,6 +29137,146 @@ "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" }, + "@microsoft/fetch-event-source": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@microsoft/fetch-event-source/-/fetch-event-source-2.0.1.tgz", + "integrity": "sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA==" + }, + "@mui/base": { + "version": "5.0.0-beta.8", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.8.tgz", + "integrity": "sha512-b4vVjMZx5KzzEMf4arXKoeV5ZegAMOoPwoy1vfUBwhvXc2QtaaAyBp50U7OA2L06Leubc1A+lEp3eqwZoFn87g==", + "peer": true, + "requires": { + "@babel/runtime": "^7.22.6", + "@emotion/is-prop-valid": "^1.2.1", + "@mui/types": "^7.2.4", + "@mui/utils": "^5.14.1", + "@popperjs/core": "^2.11.8", + "clsx": "^2.0.0", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "dependencies": { + "@emotion/is-prop-valid": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz", + "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==", + "requires": { + "@emotion/memoize": "^0.8.1" + } + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + } + } + }, + "@mui/core-downloads-tracker": { + "version": "5.14.1", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.1.tgz", + "integrity": "sha512-mIa1WmDmNr1LoupV1Rbxt9bTFKMbIn10RHG1bnZ/FJCkAYpuU/D4n+R+ttiycgcZNngU++zyh/OQeJblzbQPzg==", + "peer": true + }, + "@mui/icons-material": { + "version": "5.14.1", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.14.1.tgz", + "integrity": "sha512-xV/f26muQqtWzerzOIdGPrXoxp/OKaE2G2Wp9gnmG47mHua5Slup/tMc3fA4ZYUreGGrK6+tT81TEvt1Wsng8Q==", + "peer": true, + "requires": { + "@babel/runtime": "^7.22.6" + } + }, + "@mui/material": { + "version": "5.14.1", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.14.1.tgz", + "integrity": "sha512-WtsgYuageTunLfxH3Ri+o1RuQTFImtRHxMcVNyD0Hhd2/znjW6KODNz0XfjvLRnNCAynBxZNiflcoIBW40h9PQ==", + "peer": true, + "requires": { + "@babel/runtime": "^7.22.6", + "@mui/base": "5.0.0-beta.8", + "@mui/core-downloads-tracker": "^5.14.1", + "@mui/system": "^5.14.1", + "@mui/types": "^7.2.4", + "@mui/utils": "^5.14.1", + "@types/react-transition-group": "^4.4.6", + "clsx": "^2.0.0", + "csstype": "^3.1.2", + "prop-types": "^15.8.1", + "react-is": "^18.2.0", + "react-transition-group": "^4.4.5" + }, + "dependencies": { + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + } + } + }, + "@mui/private-theming": { + "version": "5.13.7", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.13.7.tgz", + "integrity": "sha512-qbSr+udcij5F9dKhGX7fEdx2drXchq7htLNr2Qg2Ma+WJ6q0ERlEqGSBiPiVDJkptcjeVL4DGmcf1wl5+vD4EA==", + "requires": { + "@babel/runtime": "^7.22.5", + "@mui/utils": "^5.13.7", + "prop-types": "^15.8.1" + } + }, + "@mui/styled-engine": { + "version": "5.13.2", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.13.2.tgz", + "integrity": "sha512-VCYCU6xVtXOrIN8lcbuPmoG+u7FYuOERG++fpY74hPpEWkyFQG97F+/XfTQVYzlR2m7nPjnwVUgATcTCMEaMvw==", + "requires": { + "@babel/runtime": "^7.21.0", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.2", + "prop-types": "^15.8.1" + } + }, + "@mui/system": { + "version": "5.14.1", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.14.1.tgz", + "integrity": "sha512-u+xlsU34Jdkgx1CxmBnIC4Y08uPdVX5iEd3S/1dggDFtOGp+Lj8xmKRJAQ8PJOOJLOh8pDwaZx4AwXikL4l1QA==", + "peer": true, + "requires": { + "@babel/runtime": "^7.22.6", + "@mui/private-theming": "^5.13.7", + "@mui/styled-engine": "^5.13.2", + "@mui/types": "^7.2.4", + "@mui/utils": "^5.14.1", + "clsx": "^1.2.1", + "csstype": "^3.1.2", + "prop-types": "^15.8.1" + } + }, + "@mui/types": { + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.4.tgz", + "integrity": "sha512-LBcwa8rN84bKF+f5sDyku42w1NTxaPgPyYKODsh01U1fVstTClbUoSA96oyRBnSNyEiAVjKm6Gwx9vjR+xyqHA==" + }, + "@mui/utils": { + "version": "5.14.1", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.14.1.tgz", + "integrity": "sha512-39KHKK2JeqRmuUcLDLwM+c2XfVC136C5/yUyQXmO2PVbOb2Bol4KxtkssEqCbTwg87PSCG3f1Tb0keRsK7cVGw==", + "peer": true, + "requires": { + "@babel/runtime": "^7.22.6", + "@types/prop-types": "^15.7.5", + "@types/react-is": "^18.2.1", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "dependencies": { + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + } + } + }, "@nicolo-ribaudo/eslint-scope-5-internals": { "version": "5.1.1-v1", "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", @@ -28576,9 +29380,9 @@ } }, "@popperjs/core": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.7.tgz", - "integrity": "sha512-Cr4OjIkipTtcXKjAsm8agyleBuDHvxzeBoa1v543lbv1YaIwQjESsVcmjiWiPEbC1FIeHOG/Op9kdCmAmiS3Kw==" + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==" }, "@restart/hooks": { "version": "0.4.9", @@ -28844,6 +29648,40 @@ "resolved": "https://registry.npmjs.org/@tailwindcss/line-clamp/-/line-clamp-0.4.2.tgz", "integrity": "sha512-HFzAQuqYCjyy/SX9sLGB1lroPzmcnWv1FHkIpmypte10hptf4oPUfucryMKovZh2u0uiS9U5Ty3GghWfEJGwVw==" }, + "@tanstack/match-sorter-utils": { + "version": "8.8.4", + "resolved": "https://registry.npmjs.org/@tanstack/match-sorter-utils/-/match-sorter-utils-8.8.4.tgz", + "integrity": "sha512-rKH8LjZiszWEvmi01NR72QWZ8m4xmXre0OOwlRGnjU01Eqz/QnN+cqpty2PJ0efHblq09+KilvyR7lsbzmXVEw==", + "requires": { + "remove-accents": "0.4.2" + } + }, + "@tanstack/react-table": { + "version": "8.9.2", + "resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.9.2.tgz", + "integrity": "sha512-Irvw4wqVF9hhuYzmNrlae4IKdlmgSyoRWnApSLebvYzqHoi5tEsYzBj6YPd0hX78aB/L+4w/jgK2eBQVpGfThQ==", + "requires": { + "@tanstack/table-core": "8.9.2" + } + }, + "@tanstack/react-virtual": { + "version": "3.0.0-beta.54", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.0.0-beta.54.tgz", + "integrity": "sha512-D1mDMf4UPbrtHRZZriCly5bXTBMhylslm4dhcHqTtDJ6brQcgGmk8YD9JdWBGWfGSWPKoh2x1H3e7eh+hgPXtQ==", + "requires": { + "@tanstack/virtual-core": "3.0.0-beta.54" + } + }, + "@tanstack/table-core": { + "version": "8.9.2", + "resolved": "https://registry.npmjs.org/@tanstack/table-core/-/table-core-8.9.2.tgz", + "integrity": "sha512-ajc0OF+karBAdaSz7OK09rCoAHB1XI1+wEhu+tDNMPc+XcO+dTlXXN/Vc0a8vym4kElvEjXEDd9c8Zfgt4bekA==" + }, + "@tanstack/virtual-core": { + "version": "3.0.0-beta.54", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.0.0-beta.54.tgz", + "integrity": "sha512-jtkwqdP2rY2iCCDVAFuaNBH3fiEi29aTn2RhtIoky8DTTiCdc48plpHHreLwmv1PICJ4AJUUESaq3xa8fZH8+g==" + }, "@testing-library/dom": { "version": "8.6.0", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.6.0.tgz", @@ -29413,9 +30251,9 @@ "integrity": "sha512-ZTaqn/qSqUuAq1YwvOFQfVW1AR/oQJlLSZVustdjwI+GZ8kr0MSHBj0tsXPW1EqHubx50gtBEjbPGsdZwQwCjQ==" }, "@types/prop-types": { - "version": "15.7.4", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz", - "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==" + "version": "15.7.5", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" }, "@types/q": { "version": "1.5.5", @@ -29450,6 +30288,14 @@ "@types/react": "*" } }, + "@types/react-is": { + "version": "18.2.1", + "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-18.2.1.tgz", + "integrity": "sha512-wyUkmaaSZEzFZivD8F2ftSyAfk6L+DfFliVj/mYdOXbVjRcS87fQJLTnhk6dRZPuJjI+9g6RZJO4PNCngUrmyw==", + "requires": { + "@types/react": "*" + } + }, "@types/react-lazy-load-image-component": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/@types/react-lazy-load-image-component/-/react-lazy-load-image-component-1.5.2.tgz", @@ -29491,9 +30337,9 @@ } }, "@types/react-transition-group": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.3.tgz", - "integrity": "sha512-fUx5muOWSYP8Bw2BUQ9M9RK9+W1XBK/7FLJ8PTQpnpTEkn0ccyMffyEQvan4C3h53gHdx7KE5Qrxi/LnUGQtdg==", + "version": "4.4.6", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.6.tgz", + "integrity": "sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew==", "requires": { "@types/react": "*" } @@ -30932,6 +31778,11 @@ "resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-2.0.3.tgz", "integrity": "sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==" }, + "bezier-easing": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/bezier-easing/-/bezier-easing-2.1.0.tgz", + "integrity": "sha512-gbIqZ/eslnUFC1tjEvtz0sgx+xTK20wDnYMIA27VA04R7w6xxXQPZDbibjA9DTWZRA2CXtwHykkVzlCaAJAZig==" + }, "bfj": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/bfj/-/bfj-7.0.2.tgz", @@ -31306,6 +32157,11 @@ "is-regexp": "^2.0.0" } }, + "clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==" + }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -31853,9 +32709,9 @@ } }, "csstype": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.9.tgz", - "integrity": "sha512-rpw6JPxK6Rfg1zLOYCSwle2GFOOsnjmDYDaBwEcwoOg4qlsIVCN789VkBZDJAGi4T07gI4YSutR43t9Zz4Lzuw==" + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" }, "d3": { "version": "3.5.17", @@ -33450,6 +34306,11 @@ "pkg-dir": "^4.1.0" } }, + "find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -33613,9 +34474,9 @@ } }, "formik": { - "version": "2.2.9", - "resolved": "https://registry.npmjs.org/formik/-/formik-2.2.9.tgz", - "integrity": "sha512-LQLcISMmf1r5at4/gyJigGn0gOwFbeEAlji+N9InZF6LIMXnFNkO42sCI8Jt84YZggpD4cPWObAZaxpEFtSzNA==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/formik/-/formik-2.4.2.tgz", + "integrity": "sha512-C6nx0hifW2uENP3M6HpPmnAE6HFWCcd8/sqBZEOHZY6lpHJ5qehsfAy43ktpFLEmkBmhiZDei726utcUB9leqg==", "requires": { "deepmerge": "^2.1.1", "hoist-non-react-statics": "^3.3.0", @@ -33623,7 +34484,14 @@ "lodash-es": "^4.17.21", "react-fast-compare": "^2.0.1", "tiny-warning": "^1.0.2", - "tslib": "^1.10.0" + "tslib": "^2.0.0" + }, + "dependencies": { + "tslib": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz", + "integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==" + } } }, "forwarded": { @@ -34235,6 +35103,11 @@ "resolved": "https://registry.npmjs.org/highcharts-react-official/-/highcharts-react-official-3.0.0.tgz", "integrity": "sha512-VefJgDY2hkT9gfppsQGrRF2g5u8d9dtfHGcx2/xqiP+PkZXCqalw9xOeKVCRvJKTOh0coiDFwvVjOvB7KaGl4A==" }, + "highlight-words": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/highlight-words/-/highlight-words-1.2.2.tgz", + "integrity": "sha512-Mf4xfPXYm8Ay1wTibCrHpNWeR2nUMynMVFkXCi4mbl+TEgmNOe+I4hV7W3OCZcSvzGL6kupaqpfHOemliMTGxQ==" + }, "history": { "version": "4.10.1", "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", @@ -36600,6 +37473,12 @@ } } }, + "jquery": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.0.tgz", + "integrity": "sha512-umpJ0/k8X0MvD1ds0P9SfowREz2LenHsQaxSohMZ5OMNEU2r0tf8pdeEFTHMFxWVxKNyU9rTtK3CWzUCTKJUeQ==", + "peer": true + }, "js-sdsl": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", @@ -37001,6 +37880,17 @@ "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz", "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==" }, + "material-react-table": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/material-react-table/-/material-react-table-1.14.0.tgz", + "integrity": "sha512-DMajcZwsduHfT/pfp9BiSX4qSXvj6I4fGlg6UiD7x3Ubj1EY004UK83AQIU+s8ZIC+uXObHX3OL/MiMw+qjNJg==", + "requires": { + "@tanstack/match-sorter-utils": "8.8.4", + "@tanstack/react-table": "8.9.2", + "@tanstack/react-virtual": "3.0.0-beta.54", + "highlight-words": "1.2.2" + } + }, "math-expression-evaluator": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.3.8.tgz", @@ -38576,6 +39466,14 @@ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, + "parallax-controller": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/parallax-controller/-/parallax-controller-1.7.0.tgz", + "integrity": "sha512-tIU/LgH9oIrvC6o+rvGQis8/NXxsHNuF5LODmcc5TjvEDUi2qiR/iisFmyaqI9LImQ3psdAv28k2ZEAnFekiig==", + "requires": { + "bezier-easing": "^2.1.0" + } + }, "param-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", @@ -38758,6 +39656,12 @@ } } }, + "popper.js": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz", + "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==", + "peer": true + }, "postcss": { "version": "8.4.21", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", @@ -39810,6 +40714,11 @@ "react-is": "^16.13.1" } }, + "property-expr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.5.tgz", + "integrity": "sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA==" + }, "property-information": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.2.0.tgz", @@ -40909,6 +41818,14 @@ "prop-types": "^15.7.2" } }, + "react-scroll-parallax": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/react-scroll-parallax/-/react-scroll-parallax-3.4.2.tgz", + "integrity": "sha512-jNltdM1a6y2TRHW4X4nyNT9BAzbLoISTvXaoB9YKGudVcAsGWManMI6UZ6PMd2si6bbWtTROgF/A9IoplZ2OLA==", + "requires": { + "parallax-controller": "^1.7.0" + } + }, "react-select": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.2.1.tgz", @@ -42225,6 +43142,11 @@ "mdast-util-to-markdown": "^0.6.0" } }, + "remove-accents": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz", + "integrity": "sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA==" + }, "renderkid": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", @@ -43142,13 +44064,6 @@ "stylis": "^3.5.0", "stylis-rule-sheet": "^0.0.10", "supports-color": "^5.5.0" - }, - "dependencies": { - "stylis": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-3.5.4.tgz", - "integrity": "sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q==" - } } }, "stylehacks": { @@ -43347,9 +44262,9 @@ } }, "stylis": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.10.tgz", - "integrity": "sha512-m3k+dk7QeJw660eIKRRn3xPF6uuvHs/FFzjX3HQ5ove0qYsiygoAhwn5a3IYKaZPo5LrYD0rfVmtv1gNY1uYwg==" + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-3.5.4.tgz", + "integrity": "sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q==" }, "stylis-rule-sheet": { "version": "0.0.10", @@ -43723,6 +44638,11 @@ "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" }, + "tiny-case": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz", + "integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==" + }, "tiny-invariant": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", @@ -43756,6 +44676,11 @@ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" }, + "toposort": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", + "integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==" + }, "tough-cookie": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz", @@ -45030,6 +45955,24 @@ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" }, + "yup": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/yup/-/yup-1.2.0.tgz", + "integrity": "sha512-PPqYKSAXjpRCgLgLKVGPA33v5c/WgEx3wi6NFjIiegz90zSwyMpvTFp/uGcVnnbx6to28pgnzp/q8ih3QRjLMQ==", + "requires": { + "property-expr": "^2.0.5", + "tiny-case": "^1.0.3", + "toposort": "^2.0.2", + "type-fest": "^2.19.0" + }, + "dependencies": { + "type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==" + } + } + }, "zwitch": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", diff --git a/frontends/web/package.json b/frontends/web/package.json index 6e15c6e6a..da816a71b 100644 --- a/frontends/web/package.json +++ b/frontends/web/package.json @@ -3,6 +3,11 @@ "version": "0.1.0", "private": true, "dependencies": { + "@emotion/react": "^11.11.1", + "@emotion/styled": "^11.11.0", + "@microsoft/fetch-event-source": "^2.0.1", + "@mui/icons-material": "^5.14.3", + "@mui/material": "^5.14.3", "@tailwindcss/line-clamp": "^0.4.2", "@testing-library/jest-dom": "^4.2.4", "@testing-library/react": "^9.5.0", @@ -13,13 +18,14 @@ "bootstrap-switch-button-react": "^1.2.0", "css-loader": "^3.6.0", "downloadjs": "^1.4.7", - "formik": "^2.1.4", + "formik": "^2.4.2", "framer-motion": "^10.11.2", "highcharts": "^9.1.0", "highcharts-react-official": "^3.0.0", "html-react-parser": "^3.0.15", "js-yaml": "^4.1.0", "jwt-decode": "^2.2.0", + "material-react-table": "^1.14.0", "mephisto-task": "^1.0.10", "moment": "^2.24.0", "prop-types": "^15.7.2", @@ -46,6 +52,7 @@ "react-router-hash-link": "^2.4.3", "react-scripts": "5.0.1", "react-scroll": "^1.8.9", + "react-scroll-parallax": "^3.4.2", "react-select": "^5.2.1", "react-spinners": "^0.13.8", "react-string-diff": "^0.2.0", @@ -56,7 +63,8 @@ "style-loader": "^1.2.1", "sweetalert2": "^11.6.14", "typescript": "^4.9.5", - "use-http": "^1.0.27" + "use-http": "^1.0.27", + "yup": "^1.2.0" }, "devDependencies": { "@babel/core": "^7.10.5", diff --git a/frontends/web/src/components/ProfilePageComponents/TaskSubPage.js b/frontends/web/src/components/ProfilePageComponents/TaskSubPage.js index b7e47d868..e42d28e8c 100644 --- a/frontends/web/src/components/ProfilePageComponents/TaskSubPage.js +++ b/frontends/web/src/components/ProfilePageComponents/TaskSubPage.js @@ -114,7 +114,9 @@ const TaskSubPage = (props) => { return ( <> -

Your Tasks

+

+ Your Challenges +

- - + - - - - ( - - )} - /> - {!showContentOnly && ( - - - - MLCommons Logo - - - Dynabench + + + + ( + + )} + /> + {!showContentOnly && ( + + - - - - - - - )} -
- - - - - - - - - - - } - /> - ( - - )} - /> - ( - - )} - /> - ( - - )} - /> - - - - - - - - - - + /> + ( + + )} + /> + ( + + )} + /> + + + + + + + + + + - - - - - - - - - - - - - - - -
- {!showContentOnly && ( -
- - -
- Copyright © 2023 MLCommons, Inc. -
-
- - Contact - -
-
- - Terms of Use - -
-
- - Data Policy - -
-
-
-
- )} -
-
-
-
+ + + + + + + + + + + + + + + + + {!showContentOnly && ( +
+ + +
+ Copyright © 2023 MLCommons, Inc. +
+
+ + Contact + +
+
+ + Terms of Use + +
+
+ + Data Policy + +
+
+
+
+ )} + + + + +
); diff --git a/frontends/web/src/containers/Badge.js b/frontends/web/src/containers/Badge.js index fe66052f8..9794b86d7 100644 --- a/frontends/web/src/containers/Badge.js +++ b/frontends/web/src/containers/Badge.js @@ -1,3 +1,9 @@ +/* + * Copyright (c) MLCommons 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. + */ + /* * Copyright (c) Facebook, Inc. and its affiliates. * This source code is licensed under the MIT license found in the @@ -8,9 +14,9 @@ import React from "react"; import { OverlayTrigger, Tooltip } from "react-bootstrap"; import Moment from "react-moment"; -const Badge = (props) => { +const Badge = ({ name, awarded }) => { var desc = "Unknown badge"; - switch (props.name) { + switch (name) { case "ALL_TASKS_COVERED": desc = "All tasks covered!"; break; @@ -167,10 +173,8 @@ const Badge = (props) => { default: break; } - var awarded = props.awarded; - return props.format && props.format === "text" ? ( - desc - ) : ( + + return ( { )} > - badge + <> + badge +

{desc}

+
); }; diff --git a/frontends/web/src/containers/BadgeGrid.js b/frontends/web/src/containers/BadgeGrid.js index 54496538b..217de5893 100644 --- a/frontends/web/src/containers/BadgeGrid.js +++ b/frontends/web/src/containers/BadgeGrid.js @@ -1,3 +1,9 @@ +/* + * Copyright (c) MLCommons 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. + */ + /* * Copyright (c) Facebook, Inc. and its affiliates. * This source code is licensed under the MIT license found in the diff --git a/frontends/web/src/containers/ModelPage.js b/frontends/web/src/containers/ModelPage.js index e22a97177..a15645722 100644 --- a/frontends/web/src/containers/ModelPage.js +++ b/frontends/web/src/containers/ModelPage.js @@ -103,8 +103,8 @@ const EvalStatusRow = ({ (error) => { console.log(error); setShowSpinner(false); - } - ) + }, + ), ); }} > @@ -131,8 +131,8 @@ const EvalStatusRow = ({ (error) => { console.log(error); setShowSpinner(false); - } - ) + }, + ), ); }} > @@ -179,7 +179,7 @@ const ScoreRow = ({ const downloadPrection = async (datasetId) => { setShowSpinner(true); await post( - "/model/get_model_prediction_per_dataset", + "/model/get_model_prediction_by_dataset", { user_id: user.id, model_id: modelId, @@ -187,7 +187,7 @@ const ScoreRow = ({ }, { responseType: "blob", - } + }, ); if (response.ok) { setShowSpinner(false); @@ -393,7 +393,7 @@ class ModelPage extends React.Component { this.props.history.replace({ pathname: this.props.location.pathname.replace( `/tasks/${taskCodeFromParams}`, - `/tasks/${result.task_code}` + `/tasks/${result.task_code}`, ), search: this.props.location.search, }); @@ -401,7 +401,7 @@ class ModelPage extends React.Component { }, (error) => { console.log(error); - } + }, ) .then( this.context.api.getAdminOrOwner(this.state.model.tid).then( @@ -412,8 +412,8 @@ class ModelPage extends React.Component { }, (error) => { console.log(error); - } - ) + }, + ), ); }); }, @@ -423,7 +423,7 @@ class ModelPage extends React.Component { if (error.status_code === 404 || error.status_code === 405) { this.props.history.push("/"); } - } + }, ); }; @@ -456,7 +456,7 @@ class ModelPage extends React.Component { }, (error) => { console.log(error); - } + }, ); }; @@ -473,25 +473,25 @@ class ModelPage extends React.Component { return axios .get(`${BASE_URL_2}/model/update_model_status/${this.state.modelId}`) - .then((res) => { - if (res.status === 200) { - Swal.fire({ - icon: "success", - title: "Model status change", - text: "Model status has been update successfully", - showConfirmButton: false, - timer: 1500, - }); - window.location.reload(); - } else { - Swal.fire({ - icon: "error", - title: "Model status change", - text: "Model status change failed", - showConfirmButton: false, - timer: 1500, - }); - } + .then(() => { + Swal.fire({ + icon: "success", + title: "Model status change", + text: "Model status has been update successfully", + showConfirmButton: false, + timer: 1500, + }); + window.location.reload(); + }) + .catch(() => { + Swal.fire({ + icon: "error", + title: "Model status change", + text: "Model status change failed", + showConfirmButton: false, + timer: 1500, + }); + window.location.reload(); }); // return this.context.api.toggleModelStatus(this.state.modelId).then( @@ -538,7 +538,7 @@ class ModelPage extends React.Component { scoresArr = (scoresArr || []).sort((a, b) => b.accuracy - a.accuracy); scoresArr.forEach((score) => { tableContentForScores += ` ${this.escapeLatexCharacters( - score.dataset_name + score.dataset_name, )} & ${score.accuracy} \\\\\n`; }); return tableContentForScores; @@ -553,7 +553,7 @@ class ModelPage extends React.Component { latexTableContent += this.processScoresArrayForLatex(leaderboard_scores); latexTableContent += this.processScoresArrayForLatex( - non_leaderboard_scores + non_leaderboard_scores, ); const modelUrl = window.location.href; @@ -569,14 +569,14 @@ class ModelPage extends React.Component { \\begin{tabular}{l|r} \\toprule \\textbf{Dataset} & \\textbf{${this.escapeLatexCharacters( - task.perf_metric_field_name + task.perf_metric_field_name, )}} \\\\ \\midrule ${latexTableContent} \\bottomrule \\end{tabular} \\caption{${this.escapeLatexCharacters( - taskName + taskName, )} results: \\url{${modelUrl}}} \\label{tab:results} \\end{table} @@ -614,7 +614,7 @@ ${latexTableContent} this.processScoresArrayForCsv( rows, non_leaderboard_scores, - "non-leaderboard" + "non-leaderboard", ); let csvContent = "data:text/csv;charset=utf-8,"; @@ -650,10 +650,10 @@ ${latexTableContent} const { non_leaderboard_evaluation_statuses } = this.state.model; const { hidden_evaluation_statuses } = this.state.model; let orderedLeaderboardScores = (leaderboard_scores || []).sort( - (a, b) => a.round_id - b.round_id + (a, b) => a.round_id - b.round_id, ); let orderedNonLeaderboardScores = (non_leaderboard_scores || []).sort( - (a, b) => a.round_id - b.round_id + (a, b) => a.round_id - b.round_id, ); return ( @@ -969,7 +969,7 @@ ${latexTableContent} isAdminOrTaskOwner={this.state.isAdminOrTaskOwner} modelId={this.state.modelId} /> - ) + ), )} {hidden_evaluation_statuses.length ? ( diff --git a/frontends/web/src/containers/ProfilePage.js b/frontends/web/src/containers/ProfilePage.js index e9dbccf64..309568a97 100644 --- a/frontends/web/src/containers/ProfilePage.js +++ b/frontends/web/src/containers/ProfilePage.js @@ -275,7 +275,7 @@ class ProfilePage extends React.Component { this.props.history.push( "/login?msg=" + encodeURIComponent("Please login first.") + - "&src=/account#profile" + "&src=/account#profile", ); } else { this.refreshData(); @@ -290,7 +290,7 @@ class ProfilePage extends React.Component { }, (error) => { console.log(error); - } + }, ); }; @@ -305,7 +305,7 @@ class ProfilePage extends React.Component { }, () => { this.fetchNotifications(this.state.notificationsPage); - } + }, ); }; @@ -323,12 +323,12 @@ class ProfilePage extends React.Component { function () { this.context.api.setNotificationsSeen(); this.context.user.unseen_notifications = 0; - } + }, ); }, (error) => { console.log(error); - } + }, ); }; @@ -349,24 +349,24 @@ class ProfilePage extends React.Component { console.log(error); setFieldError( "accept", - "Profile could not be updated (" + error.error + ")" + "Profile could not be updated (" + error.error + ")", ); setSubmitting(false); - } + }, ); }; handleProposalSubmit = ( values, { setFieldError, setSubmitting, resetForm }, - callback + callback, ) => { this.context.api .createTaskProposal( values.name, values.task_code, values.desc, - values.longdesc + values.longdesc, ) .then( (result) => { @@ -382,10 +382,10 @@ class ProfilePage extends React.Component { console.log(error); setFieldError( "accept", - "Profile could not be updated (" + error.error + ")" + "Profile could not be updated (" + error.error + ")", ); setSubmitting(false); - } + }, ); }; @@ -421,7 +421,7 @@ class ProfilePage extends React.Component { (error) => { console.log(error); this.setState({ invalidFileUpload: true, loader: false }); - } + }, ); }; @@ -449,11 +449,11 @@ class ProfilePage extends React.Component { }, { href: "#tasks", - buttonText: "Tasks", + buttonText: "Challenges", }, { href: "#admin_task_proposals", - buttonText: "Admin Task Proposals", + buttonText: "Admin Challenges Proposals", }, { href: "#examples", diff --git a/frontends/web/src/containers/UserContext.js b/frontends/web/src/containers/UserContext.js index 06e25df99..4599e3ba5 100644 --- a/frontends/web/src/containers/UserContext.js +++ b/frontends/web/src/containers/UserContext.js @@ -10,32 +10,8 @@ * LICENSE file in the root directory of this source tree. */ -import React from "react"; +import { createContext } from "react"; -const UserContext = React.createContext({ - user: { - admin: false, - affiliation: null, - avatar_url: null, - email: null, - examples_submitted: 0, - examples_verified: 0, - id: null, - metadata_json: null, - models_submitted: 0, - realname: null, - settings_json: null, - streak_days: 0, - streak_days_last_model_wrong: null, - streak_examples: 0, - task_permissions: [], - total_fooled: 0, - total_retracted: 0, - total_verified_fooled: 0, - total_verified_not_correct_fooled: 0, - unseen_notifications: 0, - username: null, - }, -}); +const UserContext = createContext(); export default UserContext; diff --git a/frontends/web/src/index.css b/frontends/web/src/index.css index 2fb69bd5c..5eef55e1f 100644 --- a/frontends/web/src/index.css +++ b/frontends/web/src/index.css @@ -113,11 +113,11 @@ h2.active { } .btn-primary:hover { - background-color: #ccebd4 !important; - color: #344854 !important; - border-color: inherit !important; - -webkit-box-shadow: none !important; - box-shadow: none !important; + background-color: #ccebd4; + color: #344854; + border-color: inherit; + -webkit-box-shadow: none; + box-shadow: none; } .btn-link { diff --git a/frontends/web/src/new_front/assets/Layer_5.svg b/frontends/web/src/new_front/assets/Layer_5.svg new file mode 100644 index 000000000..eb8b2356f --- /dev/null +++ b/frontends/web/src/new_front/assets/Layer_5.svg @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontends/web/src/new_front/assets/landing-1.png b/frontends/web/src/new_front/assets/landing-1.png new file mode 100644 index 000000000..9385ec8ee Binary files /dev/null and b/frontends/web/src/new_front/assets/landing-1.png differ diff --git a/frontends/web/src/new_front/assets/landing-2.png b/frontends/web/src/new_front/assets/landing-2.png new file mode 100644 index 000000000..d0ac24f6c Binary files /dev/null and b/frontends/web/src/new_front/assets/landing-2.png differ diff --git a/frontends/web/src/new_front/assets/landing-3.png b/frontends/web/src/new_front/assets/landing-3.png new file mode 100644 index 000000000..ff6bfd742 Binary files /dev/null and b/frontends/web/src/new_front/assets/landing-3.png differ diff --git a/frontends/web/src/new_front/assets/landing-4.png b/frontends/web/src/new_front/assets/landing-4.png new file mode 100644 index 000000000..177a72502 Binary files /dev/null and b/frontends/web/src/new_front/assets/landing-4.png differ diff --git a/frontends/web/src/new_front/assets/login.svg b/frontends/web/src/new_front/assets/login.svg new file mode 100644 index 000000000..57f5cb9fa --- /dev/null +++ b/frontends/web/src/new_front/assets/login.svg @@ -0,0 +1 @@ +into the night diff --git a/frontends/web/src/new_front/assets/model.svg b/frontends/web/src/new_front/assets/model.svg new file mode 100644 index 000000000..8a4aeac72 --- /dev/null +++ b/frontends/web/src/new_front/assets/model.svg @@ -0,0 +1 @@ + diff --git a/frontends/web/src/new_front/assets/register.svg b/frontends/web/src/new_front/assets/register.svg new file mode 100644 index 000000000..5d75f9bb3 --- /dev/null +++ b/frontends/web/src/new_front/assets/register.svg @@ -0,0 +1 @@ + diff --git a/frontends/web/src/new_front/components/Buttons/GeneralButton.tsx b/frontends/web/src/new_front/components/Buttons/GeneralButton.tsx index d07c8630a..436e3b8b6 100644 --- a/frontends/web/src/new_front/components/Buttons/GeneralButton.tsx +++ b/frontends/web/src/new_front/components/Buttons/GeneralButton.tsx @@ -5,15 +5,17 @@ type GeneralButtonProps = { text: string; className: string; onClick: () => void; + disabled?: boolean; }; const GeneralButton: FC = ({ text, className, onClick, + disabled, }) => { return ( - ); diff --git a/frontends/web/src/new_front/components/Cards/BadgetsCard.tsx b/frontends/web/src/new_front/components/Cards/BadgetsCard.tsx new file mode 100644 index 000000000..464b5f70a --- /dev/null +++ b/frontends/web/src/new_front/components/Cards/BadgetsCard.tsx @@ -0,0 +1,26 @@ +import React, { FC } from "react"; +import Badge from "containers/Badge"; + +type BadgeProps = { + badges: any[]; +}; + +const BadgetsCard: FC = ({ badges }) => { + return ( +
+ {badges ? ( +
+ {badges.map(({ name, awarded }, idx) => ( +
+ +
+ ))} +
+ ) : ( + "No badges yet" + )} +
+ ); +}; + +export default BadgetsCard; diff --git a/frontends/web/src/new_front/components/CreateSamples/CreateSamples/AnnotationInterfaces/Contexts/SelectBetweenImagesGenerative.tsx b/frontends/web/src/new_front/components/CreateSamples/CreateSamples/AnnotationInterfaces/Contexts/SelectBetweenImagesGenerative.tsx index 44c8130aa..e075c9590 100644 --- a/frontends/web/src/new_front/components/CreateSamples/CreateSamples/AnnotationInterfaces/Contexts/SelectBetweenImagesGenerative.tsx +++ b/frontends/web/src/new_front/components/CreateSamples/CreateSamples/AnnotationInterfaces/Contexts/SelectBetweenImagesGenerative.tsx @@ -17,6 +17,7 @@ import { getIdFromImageString } from "new_front/utils/helpers/functions/DataMani import { PacmanLoader } from "react-spinners"; import Swal from "sweetalert2"; import useFetch from "use-http"; +import useFetchSSE from "new_front/utils/helpers/functions/FetchSSE"; const SelectBetweenImagesGenerative: FC< ContextAnnotationFactoryType & ContextConfigType @@ -31,46 +32,97 @@ const SelectBetweenImagesGenerative: FC< setPartialSampleId, }) => { const [promptHistory, setPromptHistory] = useState([]); + const [firstMessageReceived, setFirstMessageReceived] = + useState(false); + const [allowsGeneration, setAllowsGeneration] = useState(true); const [showLoader, setShowLoader] = useState(false); const [showImages, setShowImages] = useState([]); const [artifactsInput, setArtifactsInput] = useState( - generative_context.artifacts + generative_context.artifacts, + ); + const [prompt, setPrompt] = useState( + "Type your prompt here (e.g. a kid sleeping in a red pool of paint)", ); - const [prompt, setPrompt] = useState("Type your prompt here"); const { post, response } = useFetch(); + const { post: postSSE, clear: clearCache } = useFetchSSE( + "http://localhost:8000", + ); const { user } = useContext(UserContext); const { modelInputs, metadataExample, updateModelInputs } = useContext( - CreateInterfaceContext + CreateInterfaceContext, ); const neccessaryFields = ["original_prompt"]; const [selectedImage, setSelectedImage] = useState(""); - const generateImages = async () => { if ( neccessaryFields.every( (item) => modelInputs.hasOwnProperty(item) || - metadataExample.hasOwnProperty(item) + metadataExample.hasOwnProperty(item), ) ) { + // await postSSE({ + // url: '/context/stream', + // body: { + // type: generative_context.type, + // artifacts: artifactsInput, + // }, + // setSaveData: setShowImages, + // setExternalLoading: setShowLoader, + // firstMessage: firstMessageReceived, + // setFirstMessage: setFirstMessageReceived, + // }) setShowLoader(true); - setIsGenerativeContext(true); - const generatedImages = await post("/context/get_generative_contexts", { - type: generative_context.type, - artifacts: artifactsInput, - }); - if (response.ok) { - setShowImages(generatedImages); - addElementToListInLocalStorage(artifactsInput.prompt, "promptHistory"); - setPromptHistory(getListFromLocalStorage("promptHistory")); - setShowLoader(false); - } else { + const socket = new WebSocket( + `${process.env.REACT_APP_WS_HOST}/context/ws/get_generative_contexts`, + ); + socket.onopen = () => { + setShowImages([]); + setAllowsGeneration(false); + console.log("WebSocket connection established"); + if (socket && socket.readyState === WebSocket.OPEN) { + socket.send( + JSON.stringify({ + type: generative_context.type, + artifacts: artifactsInput, + }), + ); + } + }; + socket.onmessage = (event) => { + if (!firstMessageReceived) { + setShowLoader(false); + setFirstMessageReceived(true); + } + const imageContent = JSON.parse(event.data); + setShowImages((prevImages) => [...prevImages, ...imageContent]); + }; + socket.onerror = (error) => { + console.error("WebSocket error:", error); Swal.fire({ icon: "error", title: "Oops...", text: "Something went wrong!", }); - } + setAllowsGeneration(true); + }; + socket.onclose = (event) => { + if (event.code === 1006) { + setAllowsGeneration(true); + setShowLoader(false); + Swal.fire({ + icon: "error", + title: "Oops...", + text: "Something went wrong! Try with another prompt", + }); + } else { + setAllowsGeneration(true); + setFirstMessageReceived(false); + } + }; + addElementToListInLocalStorage(artifactsInput.prompt, "promptHistory"); + setPromptHistory(getListFromLocalStorage("promptHistory")); + setIsGenerativeContext(true); } else { Swal.fire({ icon: "error", @@ -104,20 +156,54 @@ const SelectBetweenImagesGenerative: FC< [field_names_for_the_model.original_prompt ?? "original_prompt"]: prompt, }); setShowLoader(true); - const generatedImages = await post("/context/get_generative_contexts", { - type: generative_context.type, - artifacts: { - ...artifactsInput, - prompt: prompt, - user_id: user.id, - }, - }); - if (response.ok) { - setShowImages(generatedImages); - addElementToListInLocalStorage(artifactsInput.prompt, "promptHistory"); - setPromptHistory(getListFromLocalStorage("promptHistory")); - setShowLoader(false); - } + const socket = new WebSocket( + `${process.env.REACT_APP_WS_HOST}/context/ws/get_generative_contexts`, + ); + socket.onopen = () => { + setShowImages([]); + console.log("WebSocket connection established"); + setAllowsGeneration(false); + if (socket && socket.readyState === WebSocket.OPEN) { + socket.send( + JSON.stringify({ + type: generative_context.type, + artifacts: { + ...artifactsInput, + prompt: prompt, + user_id: user.id, + }, + }), + ); + } + }; + socket.onmessage = (event) => { + if (!firstMessageReceived) { + setShowLoader(false); + setFirstMessageReceived(true); + } + const imageContent = JSON.parse(event.data); + setShowImages((prevImages) => [...prevImages, ...imageContent]); + }; + socket.onerror = (error) => { + console.error("WebSocket error:", error); + setAllowsGeneration(true); + }; + socket.onclose = (event) => { + if (event.code === 1006) { + setAllowsGeneration(true); + setShowLoader(false); + Swal.fire({ + icon: "error", + title: "Oops...", + text: "Something went wrong! Try with another prompt", + }); + } else { + setAllowsGeneration(true); + setFirstMessageReceived(false); + } + }; + addElementToListInLocalStorage(artifactsInput.prompt, "promptHistory"); + setPromptHistory(getListFromLocalStorage("promptHistory")); setIsGenerativeContext(true); }; @@ -140,7 +226,7 @@ const SelectBetweenImagesGenerative: FC< user_id: user.id, round_id: realRoundId, task_id: taskId, - } + }, ); if (response.ok) { setPartialSampleId(partialSampleId.id); @@ -174,15 +260,16 @@ const SelectBetweenImagesGenerative: FC< }; useEffect(() => { + clearCache(); if (!localStorage.getItem("promptHistory")) { saveListToLocalStorage([], "promptHistory"); } setPromptHistory(getListFromLocalStorage("promptHistory")); saveListToLocalStorage( getListFromLocalStorage("promptHistory").filter( - (prompt: null) => prompt !== null + (prompt: null) => prompt !== null, ), - "promptHistory" + "promptHistory", ); }, []); @@ -203,6 +290,9 @@ const SelectBetweenImagesGenerative: FC< if (metadataExample) { console.log("metadataExample", metadataExample); } + console.log({ + artifactsInput, + }); }, [modelInputs, metadataExample]); return ( @@ -233,6 +323,8 @@ const SelectBetweenImagesGenerative: FC< onChange={handlePromptChange} onEnter={generateImages} placeholder={prompt} + value={prompt} + disabled={!allowsGeneration} />
@@ -252,6 +344,7 @@ const SelectBetweenImagesGenerative: FC< onClick={generateImages} text="Generate Images" className="mt-4 border-0 font-weight-bold light-gray-bg task-action-btn" + disabled={!allowsGeneration} />
@@ -282,13 +375,17 @@ const SelectBetweenImagesGenerative: FC< ) : (
- Images are being generated, bear with the model + High-resolution images are currently being generated in batches of{" "} +
+ three. To view additional images, please allow a few seconds after{" "} +
+ the initial batch appears.
)} diff --git a/frontends/web/src/new_front/components/Images/SelectImage.tsx b/frontends/web/src/new_front/components/Images/SelectImage.tsx index 9054d6903..a7a4731d2 100644 --- a/frontends/web/src/new_front/components/Images/SelectImage.tsx +++ b/frontends/web/src/new_front/components/Images/SelectImage.tsx @@ -40,9 +40,9 @@ const SelectImage: FC = ({ type="radio" name="image" value="" - checked={isSelected} + defaultChecked={isSelected} className={`items-center w-4 h-4 px-6`} - onClick={() => { + onChange={() => { handleOnClicked(image); }} /> diff --git a/frontends/web/src/new_front/components/Inputs/BasicInputRemain.tsx b/frontends/web/src/new_front/components/Inputs/BasicInputRemain.tsx index cfebacd9d..615a384f5 100644 --- a/frontends/web/src/new_front/components/Inputs/BasicInputRemain.tsx +++ b/frontends/web/src/new_front/components/Inputs/BasicInputRemain.tsx @@ -6,6 +6,7 @@ type BasicInputProps = { open?: boolean; disabled?: boolean; required?: boolean; + value?: string; onChange?: (e: React.ChangeEvent) => void; onEnter?: (e: React.KeyboardEvent) => void; }; @@ -15,12 +16,14 @@ const BasicInputRemain: FC = ({ open = true, disabled = false, required = true, + value = "", onChange, onEnter, }) => { return ( - {placeholder === "Type your prompt here" ? ( + {placeholder === + "Type your prompt here (e.g. a kid sleeping in a red pool of paint)" ? ( = ({ onEnter && onEnter(e); } }} + value="" disabled={disabled} required={required} /> diff --git a/frontends/web/src/new_front/components/Inputs/Dropdown.tsx b/frontends/web/src/new_front/components/Inputs/Dropdown.tsx index 281aecf56..0f0ef15eb 100644 --- a/frontends/web/src/new_front/components/Inputs/Dropdown.tsx +++ b/frontends/web/src/new_front/components/Inputs/Dropdown.tsx @@ -54,8 +54,9 @@ const Dropdown: FC = ({ aria-labelledby="menu-button" >
- {options.map((option) => ( + {options.map((option, key) => (
)} - + {images.map((image, index) => ( - +
void; +}; + +const CreateProposalTask: FC = ({ handleClose }) => { + const { user } = useContext(UserContext); + const history = useHistory(); + const { get, post, response } = useFetch(); + const initState = { + nameTask: "", + taskCode: "", + shortDescription: "", + description: "", + }; + + const { register, handleSubmit } = useForm({ + mode: "onTouched", + reValidateMode: "onSubmit", + defaultValues: initState, + }); + + const onSubmit = async (data: any) => { + if (!user) { + return; + } + const isValid = await get( + `task_proposals/validate_no_duplicate_task_code/${data.taskCode}`, + ); + if (isValid) { + await post("task_proposals/add_task_proposal", { + user_id: user.id, + task_code: data.taskCode, + name: data.nameTask, + desc: data.shortDescription, + longdesc: data.description, + }); + if (response.ok) { + Swal.fire({ + icon: "success", + title: "Success!", + text: "Your task proposal has been submitted", + confirmButtonText: "Ok", + }); + handleClose(); + } + } else { + Swal.fire({ + icon: "error", + title: "Oops...", + text: "Something happened, try with another task name or task code", + }); + } + }; + + const isLogin = async () => { + if (!user.id) { + await checkUserIsLoggedIn(history, `/`); + } + }; + + useEffect(() => { + isLogin(); + }, [user]); + + return ( +
+ + + Propose new task + + + + + + Model name + + + + + + Task code + + + + + + Short description + + + + + + Description + + + + + + + + + + ); +}; + +export default CreateProposalTask; diff --git a/frontends/web/src/new_front/components/Modals/SignContract.tsx b/frontends/web/src/new_front/components/Modals/SignContract.tsx new file mode 100644 index 000000000..0be36efd8 --- /dev/null +++ b/frontends/web/src/new_front/components/Modals/SignContract.tsx @@ -0,0 +1,150 @@ +import React, { FC, useContext, useEffect, useState } from "react"; +import { Button } from "react-bootstrap"; +import Form from "react-bootstrap/Form"; +import { useForm } from "react-hook-form"; +import Modal from "react-bootstrap/Modal"; +import useFetch from "use-http"; +import Swal from "sweetalert2"; +import UserContext from "containers/UserContext"; +import { useHistory } from "react-router-dom"; +import { checkUserIsLoggedIn } from "new_front/utils/helpers/functions/LoginFunctions"; + +type SignContractProps = { + contract: string; + handleClose: () => void; +}; + +const SignContract: FC = ({ contract, handleClose }) => { + const [checkboxDisabled, setCheckboxDisabled] = useState(true); + const { user } = useContext(UserContext); + const history = useHistory(); + const { get, post, response } = useFetch(); + const initState = { + nameTask: "", + taskCode: "", + shortDescription: "", + description: "", + }; + + const { register, handleSubmit } = useForm({ + mode: "onTouched", + reValidateMode: "onSubmit", + defaultValues: initState, + }); + + const onSubmit = async (data: any) => { + if (!user) { + return; + } + // const isValid = await get( + // `task_proposals/validate_no_duplicate_task_code/${data.taskCode}`, + // ) + // if (isValid) { + // await post('task_proposals/add_task_proposal', { + // user_id: user.id, + // task_code: data.taskCode, + // name: data.nameTask, + // desc: data.shortDescription, + // longdesc: data.description, + // }) + // if (response.ok) { + // Swal.fire({ + // icon: 'success', + // title: 'Success!', + // text: 'Your task proposal has been submitted', + // confirmButtonText: 'Ok', + // }) + // handleClose() + // } + // } else { + // Swal.fire({ + // icon: 'error', + // title: 'Oops...', + // text: 'Something happened, try with another task name or task code', + // }) + // } + }; + + const handleScroll = (e: any) => { + const element = e.target; + if (element.scrollHeight - element.scrollTop === element.clientHeight) { + setCheckboxDisabled(false); + } + }; + + const isLogin = async () => { + await checkUserIsLoggedIn(history, `/`); + }; + + useEffect(() => { + isLogin(); + }, []); + + return ( +
+ + + Contract + + + +
+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas id + velit ut velit dictum hendrerit. Fusce tincidunt lorem at velit + feugiat, id egestas felis facilisis. Nulla facilisi. Pellentesque + habitant morbi tristique senectus et netus et malesuada fames ac + turpis egestas. Vivamus nec libero eget tellus feugiat blandit. + Nulla sagittis felis a dolor consectetur consequat. Maecenas + consectetur, libero a tincidunt blandit, orci lectus vulputate + tortor, ut auctor dolor ex et nisl. Sed et euismod mi, a efficitur + est. Sed eu convallis eros, eget posuere odio. Nam vitae elit nec ex + tempus rhoncus. Nulla facilisi. Lorem ipsum dolor sit amet, + consectetur adipiscing elit. Maecenas id velit ut velit dictum + hendrerit. Fusce tincidunt lorem at velit feugiat, id egestas felis + facilisis. Nulla facilisi. Pellentesque habitant morbi tristique + senectus et netus et malesuada fames ac turpis egestas. Vivamus nec + libero eget tellus feugiat blandit. Nulla sagittis felis a dolor + consectetur consequat. Maecenas consectetur, libero a tincidunt + blandit, orci lectus vulputate tortor, ut auctor dolor ex et nisl. + Sed et euismod mi, a efficitur est. Sed eu convallis eros, eget + posuere odio. Nam vitae elit nec ex tempus rhoncus. Nulla facilisi. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas id + velit ut velit dictum hendrerit. Fusce tincidunt lorem at velit + feugiat, id egestas felis facilisis. Nulla facilisi. Pellentesque + habitant morbi tristique senectus et netus et malesuada fames ac + turpis egestas. Vivamus nec libero eget tellus feugiat blandit. + Nulla sagittis felis a dolor consectetur consequat. Maecenas + consectetur, libero a tincidunt blandit, orci lectus vulputate + tortor, ut auctor dolor ex et nisl. Sed et euismod mi, a efficitur + est. Sed eu convallis eros, eget posuere odio. Nam vitae elit nec ex + tempus rhoncus. Nulla facilisi. Lorem ipsum dolor sit amet, + consectetur adipiscing elit. Maecenas id velit ut velit dictum + hendrerit. Fusce tincidunt lorem at velit feugiat, id egestas felis + facilisis. Nulla facilisi. Pellentesque habitant morbi tristique + senectus et netus et malesuada fames ac turpis egestas. Vivamus nec + libero eget tellus feugiat blandit. Nulla sagittis felis a dolor + consectetur consequat. Maecenas consectetur, libero a tincidunt + blandit, orci lectus vulputate tortor, ut auctor dolor ex et nisl. + Sed et euismod mi, a efficitur est. Sed eu convallis eros, eget + posuere odio. Nam vitae elit nec ex tempus rhoncus. Nulla facilisi. +

+
+
+ +
+ + +
+
+
+ ); +}; + +export default SignContract; diff --git a/frontends/web/src/new_front/components/Modals/UpdateModelInfo.tsx b/frontends/web/src/new_front/components/Modals/UpdateModelInfo.tsx new file mode 100644 index 000000000..5b3b9cb51 --- /dev/null +++ b/frontends/web/src/new_front/components/Modals/UpdateModelInfo.tsx @@ -0,0 +1,145 @@ +import React, { FC } from "react"; +import { Button } from "react-bootstrap"; +import Form from "react-bootstrap/Form"; +import { useForm } from "react-hook-form"; +import Modal from "react-bootstrap/Modal"; +import useFetch from "use-http"; +import Swal from "sweetalert2"; + +type UpdateModelInfoProps = { + modelId: number; + name: string; + desc: string; + longdesc: string; + params: number; + languages: string; + license: string; + source_url: string; + handleClose: () => void; +}; + +const UpdateModelInfo: FC = ({ + modelId, + handleClose, + name, + desc, + longdesc, + params, + languages, + license, + source_url, +}) => { + console.log("source_url", source_url); + + const { post, response } = useFetch(); + const initialValues = { + name, + desc, + longdesc, + params, + languages, + license, + source_url, + }; + const { register, handleSubmit } = useForm({ + mode: "onTouched", + reValidateMode: "onSubmit", + defaultValues: initialValues, + }); + + const onSubmit = async (data: any) => { + await post("model/update_model_info", { + model_id: modelId, + name: data.name, + desc: data.desc, + longdesc: data.longdesc, + params: parseInt(data.params), + languages: data.languages, + license: data.license, + source_url: data.source_url, + }); + if (response.ok) { + Swal.fire({ + icon: "success", + title: "Success!", + text: "Your model info has been updated!", + confirmButtonText: "Ok", + }); + handleClose(); + window.location.reload(); + } else { + Swal.fire({ + icon: "error", + title: "Oops...", + text: "Something went wrong!", + }); + } + }; + + return ( +
+ + + + Model name + + + + + + Short description + + + + + + Description + + + + + + Params + + + + + + Languages + + + + + + License + + + + + + Source URL + + + + + + + + + + ); +}; + +export default UpdateModelInfo; diff --git a/frontends/web/src/new_front/components/Tables/Leaderboard/TaskModelLeaderboardTable.tsx b/frontends/web/src/new_front/components/Tables/Leaderboard/TaskModelLeaderboardTable.tsx index bac8f8796..79b339680 100644 --- a/frontends/web/src/new_front/components/Tables/Leaderboard/TaskModelLeaderboardTable.tsx +++ b/frontends/web/src/new_front/components/Tables/Leaderboard/TaskModelLeaderboardTable.tsx @@ -358,8 +358,8 @@ const TaskModelLeaderboardTable: FC = ({ )}
- {data?.map((data: any) => ( - + {data?.map((data: any, key: number) => ( + ))} diff --git a/frontends/web/src/new_front/components/Tables/ModelsTable.tsx b/frontends/web/src/new_front/components/Tables/ModelsTable.tsx new file mode 100644 index 000000000..371ec1594 --- /dev/null +++ b/frontends/web/src/new_front/components/Tables/ModelsTable.tsx @@ -0,0 +1,236 @@ +import React, { FC, useMemo } from "react"; +import { MaterialReactTable, MRT_ColumnDef } from "material-react-table"; +import { ModelsInfo } from "new_front/types/model/modelInfo"; +import useFetch from "use-http"; +import Swal from "sweetalert2"; + +type ModelsTableProps = { + modelsInfo: ModelsInfo[]; +}; + +const ModelsTable: FC = ({ modelsInfo }) => { + const { get, response, loading } = useFetch(); + + const columnsModels = useMemo[]>( + () => [ + { + accessorKey: "id", + header: "ID", + type: "number", + size: 100, + }, + { + accessorKey: "name", + header: "Name", + }, + { + accessorKey: "task", + header: "Task", + }, + { + accessorKey: "community", + header: "Community", + }, + { + accessorKey: "score", + header: "Score", + type: "number", + size: 100, + Cell: ({ renderedCellValue }) => { + // If there are an score, show it with just two decimals, otherwise show a 0 + return ( +
+ {typeof renderedCellValue === "number" + ? renderedCellValue.toFixed(2) + : "0"} +
+ ); + }, + }, + { + accessorKey: "upload_datetime", + header: "Date", + type: "date", + size: 120, + Cell: ({ renderedCellValue }) => { + const date = + typeof renderedCellValue === "string" + ? new Date(renderedCellValue) + : null; + const formattedDate = date ? date.toLocaleDateString() : ""; + return ( +
+ {renderedCellValue + ? new Date(formattedDate).toLocaleDateString() + : ""} +
+ ); + }, + }, + { + accessorKey: "is_published", + header: "Status", + size: 130, + Cell: ({ renderedCellValue, row }) => { + return ( +
+ {renderedCellValue ? ( + { + window.open(`/models/${row.original.id}`, "_blank"); + }} + > + Published + + ) : ( + { + window.open(`/models/${row.original.id}`, "_blank"); + }} + > + Not Published + + )} +
+ ); + }, + }, + ], + [] + ); + + const handleDeleteModel = async (modelId: number) => { + Swal.fire({ + title: "Are you sure?", + text: "This action will delete the model permanently", + icon: "warning", + showCancelButton: true, + confirmButtonText: "Yes, delete it!", + cancelButtonText: "Cancel", + }).then(async (result) => { + if (result.isConfirmed) { + const response = await get(`/models/delete_model/${modelId}`); + if (response.ok) { + Swal.fire({ + title: "Deleted!", + text: "The model has been deleted.", + icon: "success", + showConfirmButton: false, + timer: 1500, + }); + } else { + Swal.fire({ + title: "Error!", + text: "The model could not be deleted.", + icon: "error", + showConfirmButton: false, + timer: 1500, + }); + } + } + }); + }; + + return ( + ( +
+
window.open(`/models/${row.original.id}`, "_blank")} + className="cursor-pointer" + > + + + + + {" "} + {" "} + {" "} + {" "} + {" "} + + +
+
handleDeleteModel(row.original.id)} + className="cursor-pointer flex justify-around" + > + + + + + + + + + + +
+
+ )} + /> + ); +}; + +export default ModelsTable; diff --git a/frontends/web/src/new_front/pages/CreateSamples/CreateInterface.tsx b/frontends/web/src/new_front/pages/CreateSamples/CreateInterface.tsx index 9781457cf..9270532cc 100644 --- a/frontends/web/src/new_front/pages/CreateSamples/CreateInterface.tsx +++ b/frontends/web/src/new_front/pages/CreateSamples/CreateInterface.tsx @@ -59,14 +59,14 @@ const CreateInterface = () => { setTaskInfo(taskInfo); setTaskId(taskId); setIsGenerativeContext( - taskConfiguration.context.generative_context?.is_generative + taskConfiguration.context.generative_context?.is_generative, ); const amountsExamplesCreatedToday = await post( `/rounduserexample/amounts_examples_created_today`, { round_id: taskContextInfo.real_round_id, user_id: user.id!, - } + }, ); if (response.ok) { setAmountsExamplesCreatedToday(amountsExamplesCreatedToday); @@ -74,20 +74,22 @@ const CreateInterface = () => { } }; - const handleData = async () => { - const isLogin = await checkUserIsLoggedIn( - history, - `/tasks/${taskCode}/create` - ); - if (isLogin) { - loadTaskContextData(); + const isLogin = async () => { + if (!user.id) { + await checkUserIsLoggedIn(history, `/`); } }; useEffect(() => { - handleData(); + isLogin(); + }, [user]); + + useEffect(() => { + if (user.id) { + loadTaskContextData(); + } // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + }, [user.id]); return ( <> @@ -179,7 +181,7 @@ const CreateInterface = () => { isGenerativeContext={isGenerativeContext} userId={user.id!} accept_sandbox_creation={Boolean( - taskInfo.accept_sandbox_creation + taskInfo.accept_sandbox_creation, )} maxAmountExamplesOnADay={ taskInfo.max_amount_examples_on_a_day diff --git a/frontends/web/src/new_front/pages/CreateSamples/ValidateSamples.tsx b/frontends/web/src/new_front/pages/CreateSamples/ValidateSamples.tsx index a2f69245e..228e57160 100644 --- a/frontends/web/src/new_front/pages/CreateSamples/ValidateSamples.tsx +++ b/frontends/web/src/new_front/pages/CreateSamples/ValidateSamples.tsx @@ -13,6 +13,7 @@ import { checkUserIsLoggedIn } from "new_front/utils/helpers/functions/LoginFunc import { PacmanLoader } from "react-spinners"; import RadioButton from "new_front/components/Lists/RadioButton"; import { ExampleInfoType } from "new_front/types/createSamples/validateSamples/exampleInfo"; +import Swal from "sweetalert2"; const ValidateSamples: FC = () => { const [taskInfoName, setTaskInfoName] = useState(""); @@ -28,6 +29,7 @@ const ValidateSamples: FC = () => { useState(); const { hidden, setHidden } = useContext(OverlayContext); const { user } = useContext(UserContext); + let { taskCode } = useParams<{ taskCode: string }>(); const history = useHistory(); @@ -43,29 +45,46 @@ const ValidateSamples: FC = () => { get(`/example/get_validate_configuration?task_id=${taskId}`), get(`/task/get_task_with_round_info_by_task_id/${taskId}`), ]); - const infoExampleToValidate = await post( - "/example/get_example_to_validate", - { - real_round_id: taskInfo?.round.id, - user_id: 1675, - num_matching_validations: taskInfo?.num_matching_validations, - validate_non_fooling: Boolean(taskInfo?.validate_non_fooling), - task_id: taskId, - } - ); + const example = await post("/example/get_example_to_validate", { + real_round_id: taskInfo?.round.id, + user_id: user.id, + num_matching_validations: taskInfo?.num_matching_validations, + validate_non_fooling: Boolean(taskInfo?.validate_non_fooling), + task_id: taskId, + }); if (response.ok) { setTaskInfoName(taskInfo?.task_name); setRoundId(taskInfo?.round.id); setValidateNonFooling(Boolean(taskInfo?.validate_non_fooling)); setValidationConfigInfo(validationConfigInfo); - setInfoExampleToValidate(infoExampleToValidate); + } + console.log("example", example); + + if (example.example_id) { + setInfoExampleToValidate(example); + } else { + Swal.fire({ + icon: "error", + title: "Oops...", + text: "There are no examples to validate", + }); } }; + const isLogin = async () => { + if (!user.id) { + await checkUserIsLoggedIn(history, `/`); + } + }; + + useEffect(() => { + isLogin(); + }, [user]); + const handleData = async () => { const isLogin = await checkUserIsLoggedIn( history, - `/tasks/${taskCode}/validate` + `/tasks/${taskCode}/validate`, ); if (isLogin) { loadTaskContextData(); @@ -73,14 +92,18 @@ const ValidateSamples: FC = () => { }; useEffect(() => { - handleData(); + if (user.id) { + handleData(); + } // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + }, [user.id]); return ( <> - {loading || !validationConfigInfo || !infoExampleToValidate ? ( -
+ {loading || + !validationConfigInfo || + !infoExampleToValidate?.example_id ? ( +
) : ( @@ -138,7 +161,7 @@ const ValidateSamples: FC = () => { .toLowerCase() .replace( /([\u2700-\u27BF]|[\uE000-\uF8FF]|\uD83C[\uDC00-\uDFFF]|\uD83D[\uDC00-\uDFFF]|[\u2011-\u26FF]|\uD83E[\uDD10-\uDDFF])/g, - "" + "", ) .replace(" ", "")} metadataExample={metadataExample} diff --git a/frontends/web/src/new_front/pages/Landing/Communities.tsx b/frontends/web/src/new_front/pages/Landing/Communities.tsx index eb24e6dcc..4d4986bd8 100644 --- a/frontends/web/src/new_front/pages/Landing/Communities.tsx +++ b/frontends/web/src/new_front/pages/Landing/Communities.tsx @@ -10,8 +10,7 @@ import { Link } from "react-router-dom"; const Communities = () => { return ( <> -
-
+
{ -
-
+
+
{ >
-
+
-
+
-
+
{
-
+
-
+
{ return ( <> -
+

What can you do with Dynabench?

-
+
diff --git a/frontends/web/src/new_front/pages/Landing/Header.tsx b/frontends/web/src/new_front/pages/Landing/Header.tsx index 7417a160f..aa118bef9 100644 --- a/frontends/web/src/new_front/pages/Landing/Header.tsx +++ b/frontends/web/src/new_front/pages/Landing/Header.tsx @@ -1,64 +1,85 @@ -import React from "react"; +import React, { FC, useState } from "react"; import { motion } from "framer-motion"; import { fadeIn } from "new_front/utils/helpers/motion"; import { Button } from "react-bootstrap"; import { Link } from "react-router-dom"; import { Link as ScrollLink } from "react-scroll"; +import Landing1 from "new_front/assets/landing-1.png"; +import Modal from "react-bootstrap/Modal"; +import CreateProposalTask from "new_front/components/Modals/CreateProposalTask"; + +const Header: FC = () => { + const [showProposeTask, setShowProposeTask] = useState(false); + const handleClose = () => setShowProposeTask(false); + const handleShow = () => setShowProposeTask(true); -const Header = () => { return ( <> -
-
+ + + +
+
-

+

Challenging the Limits of Benchmarking AI

-

- Collaborate with fellow AI enthusiasts and experts, and work - together to create new and innovative solutions to the most - pressing challenges facing the field of AI today. +

+ Collaborate with AI enthusiasts and experts to solve pressing AI + challenges through innovation.

- - -
-
-

+
+ + +
+
+
+

20+

Challenges
-
-

+
+

40+

Partipants
-
-

- 50+ +
+

+ 100+

Models
+
+

+ 6 +

+
Communities
+

-
- +
+ Landing

@@ -69,22 +90,17 @@ const Header = () => { smooth={true} offset={-70} duration={1500} + className="flex items-center justify-center w-10 h-10 mx-auto text-gray-600 duration-300 transform border border-gray-400 rounded-full hover:text-deep-purple-accent-400 hover:border-deep-purple-accent-400 hover:shadow hover:scale-110 pointer" > - - - - - + +
diff --git a/frontends/web/src/new_front/pages/Landing/Landing.tsx b/frontends/web/src/new_front/pages/Landing/Landing.tsx index acc2f0b20..60699932e 100644 --- a/frontends/web/src/new_front/pages/Landing/Landing.tsx +++ b/frontends/web/src/new_front/pages/Landing/Landing.tsx @@ -1,26 +1,41 @@ -import React from "react"; +import React, { useEffect } from "react"; import Header from "new_front/pages/Landing/Header"; import TrustedBy from "new_front/pages/Landing/TrustedBy"; import Communities from "new_front/pages/Landing/Communities"; import Features from "new_front/pages/Landing/Features"; +import { ReactComponent as Layer5 } from "new_front/assets/Layer_5.svg"; +import { Parallax } from "react-scroll-parallax"; const Landing = () => { + useEffect(() => { + localStorage.setItem("originalPath", "/"); + }, []); + return ( <> -
-
-
-
- -
-
-
+
+
+
+
+
+
+
+ +
+
+
+ + + +
+
+
+
+ +
-
- -
); }; diff --git a/frontends/web/src/new_front/pages/Landing/TrustedBy.tsx b/frontends/web/src/new_front/pages/Landing/TrustedBy.tsx index 59309e9fd..2006e4afc 100644 --- a/frontends/web/src/new_front/pages/Landing/TrustedBy.tsx +++ b/frontends/web/src/new_front/pages/Landing/TrustedBy.tsx @@ -8,7 +8,7 @@ import "react-multi-carousel/lib/styles.css"; const TrustedBy = () => { return ( -
+

Used By

@@ -21,9 +21,13 @@ const TrustedBy = () => { className="w-full mx-auto" arrows={false} > - {companies.map((company) => ( -
- {company.name} + {companies.map((company, key) => ( +
+ {company.name}
))} diff --git a/frontends/web/src/new_front/pages/Login/LoginPage.tsx b/frontends/web/src/new_front/pages/Login/LoginPage.tsx new file mode 100644 index 000000000..36a2d34fe --- /dev/null +++ b/frontends/web/src/new_front/pages/Login/LoginPage.tsx @@ -0,0 +1,134 @@ +import React, { FC, useContext, useState } from "react"; +import { Link, useHistory } from "react-router-dom"; +import { Button } from "react-bootstrap"; +import { ReactComponent as Login } from "new_front/assets/login.svg"; +import axios from "axios"; +import UserContext from "containers/UserContext"; +import useFetch from "use-http"; +import Swal from "sweetalert2"; + +const LoginPage: FC = () => { + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + const { post, response } = useFetch(); + const { updateState } = useContext(UserContext); + const originalPath = localStorage.getItem("originalPath"); + const history = useHistory(); + + // const handleLogin = async () => { + // await post('user/authenticate', { + // email: email, + // password: password, + // }) + // if (response.ok) { + // localStorage.setItem('id_token', response.data.token) + // updateState({ + // user: response.data.user, + // }) + // if (originalPath) { + // history.push(originalPath) + // } else { + // history.goBack() + // } + // } else { + // Swal.fire({ + // icon: 'error', + // title: 'Oops...', + // text: 'Something went wrong! try another email or password', + // }) + // } + // } + + const handleLogin = () => { + axios + .post(`${process.env.REACT_APP_API_HOST}/authenticate`, { + email: email, + password: password, + }) + .then((response) => { + localStorage.setItem("id_token", response.data.token); + updateState({ + user: response.data.user, + }); + if (originalPath === "/") { + history.push("/account"); + } else { + history.goBack(); + } + }) + .catch((error) => { + Swal.fire({ + icon: "error", + title: "Oops...", + text: "Something went wrong! try another email or password", + }); + }); + }; + + return ( +
+
+
+
+ +
+
+

+ Welcome back! +

+
+
+ setEmail(e.target.value)} + /> + +
+
+ setPassword(e.target.value)} + /> + +
+
+
+

+ Don't have an account?{" "} + + Sign up + +

+

+ + Forgot Password? + +

+
+
+ + + +
+
+
+
+ ); +}; + +export default LoginPage; diff --git a/frontends/web/src/new_front/pages/Login/Register.tsx b/frontends/web/src/new_front/pages/Login/Register.tsx new file mode 100644 index 000000000..c3cb6d519 --- /dev/null +++ b/frontends/web/src/new_front/pages/Login/Register.tsx @@ -0,0 +1,155 @@ +import React, { useState } from "react"; +import { ReactComponent as RegisterLogo } from "new_front/assets/register.svg"; +import { Button } from "react-bootstrap"; +import { Link } from "react-router-dom"; +import { Formik, Form, Field, ErrorMessage } from "formik"; +import Swal from "sweetalert2"; +import * as Yup from "yup"; +import useFetch from "use-http"; +import UserContext from "containers/UserContext"; + +const Register = () => { + const [acceptTerms, setAcceptTerms] = useState(false); + const { post, response } = useFetch(); + + const schema = Yup.object().shape({ + username: Yup.string().min(3, "Username must be at least 3 characters"), + email: Yup.string().email("Invalid email format"), + password: Yup.string().min(8, "Password must be at least 8 characters"), + }); + + const initialValues = { + username: "", + email: "", + password: "", + }; + + const onSubmit = async (values: any) => { + await post("user/create_user", { + email: values.email, + password: values.password, + username: values.username, + }); + if (response.ok) { + Swal.fire({ + icon: "success", + title: "Success", + text: "User created successfully", + }); + window.location.href = "/"; + } else { + Swal.fire({ + icon: "error", + title: "Oops...", + text: "Something went wrong! try another email or username", + }); + } + }; + + const renderError = (message: string) => ( +

{message}

+ ); + + return ( +
+
+
+
+ +
+
+

+ Welcome to Dynabench! +

+ { + await onSubmit(values); + resetForm(); + }} + > +
+
+
+ + +
+ +
+
+ + + +
+
+ + + +
+
+ setAcceptTerms(e.target.checked)} + /> + I accept the + +   Terms of Use + +   and   + + Data Policy + + . +
+ +

+ Already have an account?   + + Login + +

+ +
+
+
+
+
+ ); +}; + +export default Register; diff --git a/frontends/web/src/new_front/pages/Model/ModelOverview.tsx b/frontends/web/src/new_front/pages/Model/ModelOverview.tsx new file mode 100644 index 000000000..9bac23a1c --- /dev/null +++ b/frontends/web/src/new_front/pages/Model/ModelOverview.tsx @@ -0,0 +1,217 @@ +import React, { FC, useState, useEffect } from "react"; +import { ReactComponent as Model } from "new_front/assets/model.svg"; +import { AllModelsInfo } from "new_front/types/model/modelInfo"; +import useFetch from "use-http"; +import { useParams } from "react-router-dom"; +import Swal from "sweetalert2"; +import { Button } from "react-bootstrap"; +import UpdateModelInfo from "new_front/components/Modals/UpdateModelInfo"; +import Modal from "react-bootstrap/Modal"; +import { PacmanLoader } from "react-spinners"; + +type ModelOverviewProps = { + modelId?: number; +}; + +const ModelOverview: FC = () => { + const { modelId } = useParams<{ modelId: string }>(); + + const [showUpdateModelInfo, setShowUpdateModelInfo] = useState(false); + const [modelInfo, setModelInfo] = useState( + {} as AllModelsInfo + ); + const { get, response, loading } = useFetch(); + + const getModelInfo = async () => { + const modelInfo = await get(`/model/get_all_model_info_by_id/${modelId}`); + if (response.ok) { + if (!modelInfo) { + Swal.fire({ + icon: "error", + title: "Oops...", + text: "This models does not exist!", + }); + } else { + setModelInfo(modelInfo); + } + } else { + Swal.fire({ + icon: "error", + title: "Oops...", + text: "Something went wrong!", + }); + } + }; + + const updateModelStatus = async () => { + await get(`/model/update_model_status/${modelId}`); + if (response.ok) { + Swal.fire({ + icon: "success", + title: "Success", + text: "Model status updated successfully", + }).then(() => { + window.location.reload(); + }); + } else { + Swal.fire({ + icon: "error", + title: "Oops...", + text: "Model is missing all the scores!", + }); + } + }; + + useEffect(() => { + if (modelId) { + getModelInfo(); + } + console.log(modelId); + }, [modelId]); + + return ( + <> + {!loading && Object.keys(modelInfo).length !== 0 ? ( + <> + setShowUpdateModelInfo(false)} + > + setShowUpdateModelInfo(false)} + name={modelInfo.name} + desc={modelInfo.desc} + longdesc={modelInfo.longdesc} + params={modelInfo.params} + languages={modelInfo.languages} + license={modelInfo.license} + source_url={modelInfo.source_url} + /> + +
+
+
+ +
+
+
+

+ {modelInfo.upload_datetime.substring(0, 10)} +

+
+ + + + + {" "} + {" "} + {" "} + + +

+ {modelInfo.score.toFixed(2)}   + + (General score) + +

+
+ + +
+

+ {modelInfo.name} +

+

{modelInfo.desc}

+

+ {modelInfo.longdesc} +

+
+ + Data + +
+
    +
  • + Community: {modelInfo.community} +
  • +
  • + Task: {modelInfo.task} +
  • +
  • + Params: {modelInfo.params} +
  • +
  • + Languagues: {modelInfo.languages} +
  • +
  • + License: {modelInfo.license} +
  • +
  • + Paper: {modelInfo.source_url} +
  • +
+
+ + {/* */} + +
+
+
+
+ + ) : ( +
+ +
+ )} + + ); +}; + +export default ModelOverview; diff --git a/frontends/web/src/new_front/pages/ProfilePage/ProfilePage.tsx b/frontends/web/src/new_front/pages/ProfilePage/ProfilePage.tsx new file mode 100644 index 000000000..ebee9982c --- /dev/null +++ b/frontends/web/src/new_front/pages/ProfilePage/ProfilePage.tsx @@ -0,0 +1,244 @@ +import React, { FC, useContext, useState, useEffect } from "react"; +import useFetch from "use-http"; +import UserContext from "containers/UserContext"; +import Swal from "sweetalert2"; +import { PacmanLoader } from "react-spinners"; +import { UserInfoProps, UserStatsProps } from "new_front/types/user/userInfo"; +import { checkUserIsLoggedIn } from "new_front/utils/helpers/functions/LoginFunctions"; +import { Link } from "react-scroll"; +import Carousel from "react-multi-carousel"; +import BadgetsCard from "new_front/components/Cards/BadgetsCard"; +import { TaskInfoType } from "new_front/types/task/taskInfo"; +import { responsiveCarousel } from "new_front/utils/constants"; +import TaskCard from "new_front/components/Cards/TaskCard"; +import { TaskCategories } from "new_front/types/task/taskCategories"; +import ExamplesCreated from "new_front/pages/ProfilePage/ExamplesCreated"; +import ModelsTable from "new_front/components/Tables/ModelsTable"; +import { ModelsInfo } from "new_front/types/model/modelInfo"; +import { useHistory } from "react-router-dom"; + +type Props = { + userName: string; + affiliation: string; +}; + +const ProfilePage: FC = () => { + const [userInfo, setUserInfo] = useState({} as UserInfoProps); + const [userStats, setUserStats] = useState( + {} as UserStatsProps, + ); + const [modelsInfo, setModelsInfo] = useState( + [] as ModelsInfo[], + ); + const [tasksCategories, setTasksCategories] = useState([]); + const [tasksInfo, setTasksInfo] = useState( + [] as TaskInfoType[], + ); + const { user } = useContext(UserContext); + const { get, response, loading } = useFetch(); + const history = useHistory(); + + const userId = user.id; + const getUserInfo = async () => { + if (!userId) { + return; + } + const [userInfo, tasksInfo, modelsInfo, userStats] = await Promise.all([ + get(`/user/get_user_with_badges/${userId}`), + get(`/task/get_active_tasks_by_user_id/${userId}`), + get(`/model/get_models_by_user_id/${userId}`), + get(`/user/get_stats_by_user_id/${userId}`), + ]); + if (response.ok) { + setUserInfo(userInfo); + setTasksInfo(tasksInfo); + setModelsInfo(modelsInfo); + setUserStats(userStats); + } else { + Swal.fire({ + icon: "error", + title: "Oops...", + text: "Something went wrong!", + }); + } + }; + + const handleData = async () => { + const isLogin = await checkUserIsLoggedIn(history, `/account`); + if (isLogin) { + getUserInfo(); + } + }; + + useEffect(() => { + handleData(); + }, [userId]); + + useEffect(() => { + localStorage.removeItem("originalPath"); + }, []); + + return ( + <> + {!loading && user ? ( +
+
+
+
+
+

+ Welcome {userInfo!.username}! +

+
    +
  • + {userInfo!.affiliation} +
  • +
+
+
+
+

+ {userStats!.total_examples} +

+

+ + Total examples + +

+
+
+
+
+

+ {userStats!.total_validations} +

+

+ Total validation examples +

+
+
+
+
+

+ {userStats!.total_models} +

+

+ + Models + +

+
+
+
+
+

+ {(userStats.model_fooling_rate * 100).toFixed(0)}% +

+

+ Model fooling rate +

+
+
+
+
+
+ + + + + + + +
+
+
+

+ Your Challenges +

+
+ + {tasksInfo.map((task) => ( +
+ +
+ ))} +
+
+
+
+

+ Badges +

+ +
+
+

+ Models +

+ +
+
+

+ Examples +

+ +
+
+
+
+ ) : ( +
+ +
+ )} + + ); +}; + +export default ProfilePage; diff --git a/frontends/web/src/new_front/pages/Submissions/SubmitPrediction.tsx b/frontends/web/src/new_front/pages/Submissions/SubmitPrediction.tsx index a87512c4e..4b2914cfb 100644 --- a/frontends/web/src/new_front/pages/Submissions/SubmitPrediction.tsx +++ b/frontends/web/src/new_front/pages/Submissions/SubmitPrediction.tsx @@ -27,57 +27,102 @@ const SubmitPrediction = () => { const handleData = async () => { const isLogin = await checkUserIsLoggedIn( history, - `/tasks/${taskCode}/submit_prediction` + `/tasks/${taskCode}/submit_prediction`, ); + if (!isLogin) { + return; + } }; - useEffect(() => { - handleData(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - const handleSubmitModel = async (modelData: any) => { setLoading(true); const formData = new FormData(); - formData.append("predictions", modelData.file[0]); - const BASE_URL_2 = process.env.REACT_APP_API_HOST_2; - await axios - .post(`${BASE_URL_2}/model/upload_prediction_to_s3`, formData, { - headers: { - "Content-Type": "multipart/form-data", - }, - params: { - user_id: user.id, - task_code: taskCode, - model_name: modelData.modelName.replace(/\s/g, "_"), - }, - }) - .then((response) => { - if (response.status === 200) { + const predictions = modelData.file[0]; + if (predictions === undefined) { + console.log("predictions", predictions); + Swal.fire({ + title: "Error!", + text: "Please click on the upload button to upload a file.", + icon: "error", + confirmButtonText: "Ok", + }).then(() => { + setLoading(false); + window.location.reload(); + }); + return; + } else { + const predictionsFormat = predictions.name.split(".").pop().toLowerCase(); + console.log("predictionsFormat", predictionsFormat); + if (predictionsFormat !== "json" && predictionsFormat !== "jsonl") { + Swal.fire({ + title: "Error!", + text: "Please, upload a json file.", + icon: "error", + confirmButtonText: "Ok", + }); + setLoading(false); + window.location.reload(); + return; + } + formData.append("predictions", predictions); + const BASE_URL_2 = process.env.REACT_APP_API_HOST_2; + await axios + .post(`${BASE_URL_2}/model/upload_prediction_to_s3`, formData, { + headers: { + "Content-Type": "multipart/form-data", + }, + params: { + user_id: user.id, + task_code: taskCode, + model_name: modelData.modelName.replace(/\s/g, "_"), + }, + }) + .then(() => { Swal.fire({ title: "Success!", - text: "Dataset uploaded successfully.", + text: "Predictions uploaded successfully.", icon: "success", confirmButtonText: "Ok", }).then(() => { window.location.reload(); }); - } else { - Swal.fire({ - title: "Error!", - text: "Something went wrong.", - icon: "error", - confirmButtonText: "Ok", - }); - } - setLoading(false); - }); + }) + .catch((error) => { + if (error.response.status === 400) { + Swal.fire({ + title: "Error!", + text: "Although uploaded, the submission failed to evaluate.", + icon: "error", + confirmButtonText: "Ok", + }).then(() => { + window.location.reload(); + }); + } else { + Swal.fire({ + title: "Error!", + text: "Something went wrong.", + icon: "error", + confirmButtonText: "Ok", + }).then(() => { + window.location.reload(); + }); + } + setLoading(false); + }); + } }; const onSubmit = (data: any) => { handleSubmitModel(data); }; + useEffect(() => { + if (user.id) { + handleData(); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [user]); + return ( <> {!loading ? ( @@ -145,7 +190,7 @@ const SubmitPrediction = () => {
{ ) : ( <> - Drag & drop your .json file with predictions here + Click here to upload your json file (please don't + drag and drop) { const tasksFilter = searchParams.get("task")?.toLowerCase() || ""; const { tasksData, tasksCategories } = useTasks(); + useEffect(() => { + localStorage.removeItem("originalPath"); + }, []); + return ( -
-
-

- Challenges -

-
-
-
-
-
- {tasksData - .filter((t) => - t.name.toString().toLowerCase().includes(tasksFilter) - ) - .map((task) => ( -
- -
- ))} +
+
+
+

+ Challenges +

+
+
+
+
+
+ {tasksData + .filter((t) => + t.name.toString().toLowerCase().includes(tasksFilter) + ) + .map((task) => ( +
+ +
+ ))} +
diff --git a/frontends/web/src/new_front/pages/Task/LeaderBoard.jsx b/frontends/web/src/new_front/pages/Task/LeaderBoard.jsx index e7c70fb76..8ace843fc 100644 --- a/frontends/web/src/new_front/pages/Task/LeaderBoard.jsx +++ b/frontends/web/src/new_front/pages/Task/LeaderBoard.jsx @@ -55,14 +55,14 @@ class Leaderboard extends React.Component { this.props.history.replace({ pathname: this.props.location.pathname.replace( `/tasks/${this.taskCode}`, - `/tasks/${this.state.taskCode}` + `/tasks/${this.state.taskCode}`, ), search: this.props.location.search, }); } this.state.loading = true; this.fetchTrend(); - } + }, ); this.context.api.getAdminOrOwner(result.id).then( (adminOrOwnerResult) => { @@ -72,7 +72,7 @@ class Leaderboard extends React.Component { }, (error) => { console.log(error); - } + }, ); }, (error) => { @@ -80,7 +80,7 @@ class Leaderboard extends React.Component { if (error.status_code === 404 || error.status_code === 405) { this.props.history.push("/"); } - } + }, ); }); } @@ -104,12 +104,11 @@ class Leaderboard extends React.Component { }, (error) => { console.log(error); - } + }, ); } render() { - console.log("this.state.task", this.state.task); const hasTrainFileUpload = this.state.task.config_yaml && yaml diff --git a/frontends/web/src/new_front/pages/Task/TaskPage.tsx b/frontends/web/src/new_front/pages/Task/TaskPage.tsx index 08c0b3ac7..30c39c4bc 100644 --- a/frontends/web/src/new_front/pages/Task/TaskPage.tsx +++ b/frontends/web/src/new_front/pages/Task/TaskPage.tsx @@ -40,8 +40,8 @@ const TaskPage = () => { const [taskData, maxScore, amountOfModels, adminOrOwner, taskInstructions] = await Promise.all([ await get(`/task/get_task_with_round_info_by_task_id/${taskId}`), - await get(`/score/get_maximun_principal_score_per_task/${taskId}`), - await get(`/model/get_amount_of_models_per_task/${taskId}`), + await get(`/score/get_maximun_principal_score_by_task/${taskId}`), + await get(`/model/get_amount_of_models_by_task/${taskId}`), await post("/auth/is_admin_or_owner", { task_id: taskId, user_id: user.id, @@ -72,7 +72,9 @@ const TaskPage = () => { } }, [task]); - console.log("task", task); + useEffect(() => { + localStorage.removeItem("originalPath"); + }, []); return (
@@ -130,13 +132,14 @@ const TaskPage = () => { setOpenTab={setOpenTab} /> )} - - + {Object.entries(taskInstructions).length !== 0 && ( + + )} {task.documentation_url && ( { { /> )}
-
- -
+ {Object.entries(taskInstructions).length !== 0 && ( +
+ +
+ )}
diff --git a/frontends/web/src/new_front/pages/Task/Test.tsx b/frontends/web/src/new_front/pages/Task/Test.tsx index 57d972acb..69f65d78a 100644 --- a/frontends/web/src/new_front/pages/Task/Test.tsx +++ b/frontends/web/src/new_front/pages/Task/Test.tsx @@ -1,11 +1,43 @@ -import React from "react"; -import SubmitPrediction from "../Submissions/SubmitPrediction"; +import React, { useState } from "react"; +import SignContract from "new_front/components/Modals/SignContract"; +import Modal from "react-bootstrap/Modal"; const Test = () => { + const [show, setShow] = useState(true); + const handleClose = () => setShow(false); + return ( - <> - - +
+ + + + +
); }; diff --git a/frontends/web/src/new_front/types/model/modelInfo.ts b/frontends/web/src/new_front/types/model/modelInfo.ts new file mode 100644 index 000000000..10fc97181 --- /dev/null +++ b/frontends/web/src/new_front/types/model/modelInfo.ts @@ -0,0 +1,28 @@ +export type ModelsInfo = { + id: number; + name: string; + task: string; + score: number; + upload_datetime: string; + is_published: number; + community: string; +}; + +export type AllModelsInfo = { + id: number; + name: string; + desc: string; + longdesc: string; + params: number; + languages: string; + license: string; + source_url: string; + light_model: number; + deployment_status: string; + is_in_the_loop: number; + is_published: number; + upload_datetime: string; + community: string; + task: string; + score: number; +}; diff --git a/frontends/web/src/new_front/types/user/userInfo.ts b/frontends/web/src/new_front/types/user/userInfo.ts new file mode 100644 index 000000000..17add6a36 --- /dev/null +++ b/frontends/web/src/new_front/types/user/userInfo.ts @@ -0,0 +1,35 @@ +export type UserInfoProps = { + id: number; + forgot_password_token: null | string; + metadata_json: string; + streak_days_last_model_wrong: string; + admin: number; + forgot_password_token_expiry_date: null | string; + examples_submitted: number; + api_token: string; + username: string; + total_retracted: number; + examples_verified: number; + avatar_url: null | string; + email: string; + examples_verified_correct: null | string; + models_submitted: number; + password: string; + total_verified_fooled: number; + unseen_notifications: number; + realname: null | string; + total_verified_not_correct_fooled: number; + streak_examples: number; + affiliation: null | string; + total_fooled: number; + streak_days: number; + settings_json: null | string; + badges: any[][]; +}; + +export type UserStatsProps = { + total_examples: number; + total_validations: number; + total_models: number; + model_fooling_rate: number; +}; diff --git a/frontends/web/src/new_front/utils/constants.ts b/frontends/web/src/new_front/utils/constants.ts index 6df8d1ccc..8e4f60bd5 100644 --- a/frontends/web/src/new_front/utils/constants.ts +++ b/frontends/web/src/new_front/utils/constants.ts @@ -36,6 +36,25 @@ export const responsiveCarouselCompanies = { }, }; +export const carouselLanding = { + superLargeDesktop: { + breakpoint: { max: 4000, min: 3000 }, + items: 1, + }, + desktop: { + breakpoint: { max: 3000, min: 1024 }, + items: 1, + }, + tablet: { + breakpoint: { max: 1024, min: 464 }, + items: 1, + }, + mobile: { + breakpoint: { max: 464, min: 0 }, + items: 1, + }, +}; + export const companies = [ { name: "Stanford University", diff --git a/frontends/web/src/new_front/utils/helpers/functions/FetchSSE.tsx b/frontends/web/src/new_front/utils/helpers/functions/FetchSSE.tsx new file mode 100644 index 000000000..190aa4a14 --- /dev/null +++ b/frontends/web/src/new_front/utils/helpers/functions/FetchSSE.tsx @@ -0,0 +1,156 @@ +import { fetchEventSource } from "@microsoft/fetch-event-source"; +import Swal from "sweetalert2"; + +type FetchType = { + post: (props: FetchProps) => Promise; + clear: () => void; +}; + +type FetchProps = { + url: string; + body: any; + setSaveData: (value: any) => void; + setExternalLoading?: (value: boolean) => void; + firstMessage?: boolean; + setFirstMessage?: (value: boolean) => void; + setAllowsGeneration?: (value: boolean) => void; +}; + +function useFetchSSE(baseUrl: string): FetchType { + const CACHE_PREFIX = "cache_"; + + const UseFetch = async ({ + url, + body, + setSaveData, + setExternalLoading, + firstMessage, + setFirstMessage, + setAllowsGeneration, + }: FetchProps) => { + const fullUrl = new URL(url, baseUrl); + setExternalLoading && setExternalLoading(true); + await fetchEventSource(fullUrl.toString(), { + body: JSON.stringify(body), + method: "POST", + headers: { "Content-Type": "application/json" }, + async onopen(response) { + await checkErrorResponse(response); + setSaveData && setSaveData([]); + setAllowsGeneration && setAllowsGeneration(false); + }, + onmessage: (ev) => { + if (!firstMessage) { + setExternalLoading && setExternalLoading(false); + setFirstMessage && setFirstMessage(true); + } + if (ev && Object.keys(ev.data).length !== 0) { + persist(body, ev.data as TData); + setSaveData((prev: any) => [...prev, ...JSON.parse(ev.data)] as any); + } + }, + onclose: () => { + setExternalLoading && setExternalLoading(false); + setFirstMessage && setFirstMessage(false); + setAllowsGeneration && setAllowsGeneration(true); + }, + onerror(err) { + setExternalLoading && setExternalLoading(false); + setFirstMessage && setFirstMessage(false); + setAllowsGeneration && setAllowsGeneration(true); + Swal.fire({ + icon: "error", + title: "Oops...", + text: "Something went wrong!", + }); + throw err; + }, + }); + }; + + const post = async ({ + url, + body, + setSaveData, + setExternalLoading, + firstMessage, + setFirstMessage, + }: FetchProps) => { + const cachedResponse = checkCachedRequest( + body.artifacts.prompt.replace(/"|'/g, ""), + ); + if (cachedResponse) { + setSaveData(cachedResponse); + } else { + await UseFetch({ + url, + body, + setSaveData, + setExternalLoading, + firstMessage, + setFirstMessage, + }); + } + }; + + const checkErrorResponse = async (resp: Response) => { + switch (resp.status) { + case 400: + case 401: + case 500: + case 404: + console.log("Error"); + Swal.fire({ + icon: "error", + title: "Oops...", + text: "Something went wrong!", + }); + + break; + default: + break; + } + }; + + const checkCachedRequest = (key: string) => { + const data = sessionStorage.getItem(CACHE_PREFIX + key); + if (data) { + return JSON.parse(data); + } + return null; + }; + + const generateKey = (key: string) => { + return CACHE_PREFIX + key; + }; + + const persist = (body: any, res: TData) => { + const key = body.artifacts.prompt.replace(/"|'/g, ""); + const data = sessionStorage.getItem(CACHE_PREFIX + key); + const fullResponse = []; + if (data) { + const localData = JSON.parse(data); + for (const d of localData) { + fullResponse.push(d); + } + } + fullResponse.push(...JSON.parse(res as any)); + sessionStorage.setItem(generateKey(key), JSON.stringify(fullResponse)); + }; + + const clear = () => { + const keys = Object.keys(sessionStorage); + for (const key of keys) { + if (key.includes(CACHE_PREFIX)) { + sessionStorage.removeItem(key); + } + } + }; + + return { + post, + clear, + }; +} + +export default useFetchSSE; diff --git a/frontends/web/tsconfig.json b/frontends/web/tsconfig.json index d6bd25265..088a1aac3 100644 --- a/frontends/web/tsconfig.json +++ b/frontends/web/tsconfig.json @@ -1,7 +1,7 @@ { "compilerOptions": { "useUnknownInCatchVariables": false, - "target": "es5", + "target": "es2015", "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true, diff --git a/annotators/.gitignore b/legacy/annotators/.gitignore similarity index 100% rename from annotators/.gitignore rename to legacy/annotators/.gitignore diff --git a/annotators/clean_servers.py b/legacy/annotators/clean_servers.py similarity index 81% rename from annotators/clean_servers.py rename to legacy/annotators/clean_servers.py index 00ade555f..4b8b671c1 100644 --- a/annotators/clean_servers.py +++ b/legacy/annotators/clean_servers.py @@ -1,3 +1,7 @@ +# Copyright (c) MLCommons 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. + # Copyright (c) Facebook, Inc. 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. diff --git a/annotators/conf/base.yaml b/legacy/annotators/conf/base.yaml similarity index 100% rename from annotators/conf/base.yaml rename to legacy/annotators/conf/base.yaml diff --git a/annotators/conf/nli_r1.yaml b/legacy/annotators/conf/nli_r1.yaml similarity index 100% rename from annotators/conf/nli_r1.yaml rename to legacy/annotators/conf/nli_r1.yaml diff --git a/annotators/conf/nli_r4_mturk.yaml b/legacy/annotators/conf/nli_r4_mturk.yaml similarity index 100% rename from annotators/conf/nli_r4_mturk.yaml rename to legacy/annotators/conf/nli_r4_mturk.yaml diff --git a/annotators/conf/vqa_r1.yaml b/legacy/annotators/conf/vqa_r1.yaml similarity index 100% rename from annotators/conf/vqa_r1.yaml rename to legacy/annotators/conf/vqa_r1.yaml diff --git a/annotators/conf/vqa_val_r1.yaml b/legacy/annotators/conf/vqa_val_r1.yaml similarity index 100% rename from annotators/conf/vqa_val_r1.yaml rename to legacy/annotators/conf/vqa_val_r1.yaml diff --git a/annotators/examine_results.py b/legacy/annotators/examine_results.py similarity index 96% rename from annotators/examine_results.py rename to legacy/annotators/examine_results.py index c20c4e7ec..72b10d0a8 100644 --- a/annotators/examine_results.py +++ b/legacy/annotators/examine_results.py @@ -1,5 +1,9 @@ #!/usr/bin/env python3 +# Copyright (c) MLCommons 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. + # Copyright (c) Facebook, Inc. 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. diff --git a/annotators/pay_workers.py b/legacy/annotators/pay_workers.py similarity index 96% rename from annotators/pay_workers.py rename to legacy/annotators/pay_workers.py index 12f0ead32..4d8b8da45 100644 --- a/annotators/pay_workers.py +++ b/legacy/annotators/pay_workers.py @@ -1,4 +1,8 @@ #!/usr/bin/env python3 +# Copyright (c) MLCommons 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. + # Copyright (c) Facebook, Inc. 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. diff --git a/annotators/process_dkqa.py b/legacy/annotators/process_dkqa.py similarity index 88% rename from annotators/process_dkqa.py rename to legacy/annotators/process_dkqa.py index eef214bac..6a113de60 100644 --- a/annotators/process_dkqa.py +++ b/legacy/annotators/process_dkqa.py @@ -1,5 +1,9 @@ #!/usr/bin/env python3 +# Copyright (c) MLCommons 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. + # Copyright (c) Facebook, Inc. 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. diff --git a/annotators/run_mturk.py b/legacy/annotators/run_mturk.py similarity index 96% rename from annotators/run_mturk.py rename to legacy/annotators/run_mturk.py index ef2954c0f..000758a15 100644 --- a/annotators/run_mturk.py +++ b/legacy/annotators/run_mturk.py @@ -1,5 +1,9 @@ #!/usr/bin/env python3 +# Copyright (c) MLCommons 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. + # Copyright (c) Facebook, Inc. 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. diff --git a/annotators/set_mturk_qualification.py b/legacy/annotators/set_mturk_qualification.py similarity index 94% rename from annotators/set_mturk_qualification.py rename to legacy/annotators/set_mturk_qualification.py index c3c75a285..09874c8fb 100644 --- a/annotators/set_mturk_qualification.py +++ b/legacy/annotators/set_mturk_qualification.py @@ -1,5 +1,9 @@ #!/usr/bin/env python3 +# Copyright (c) MLCommons 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. + # Copyright (c) Facebook, Inc. 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. diff --git a/annotators/util.py b/legacy/annotators/util.py similarity index 94% rename from annotators/util.py rename to legacy/annotators/util.py index 284e1b641..15e68bd22 100644 --- a/annotators/util.py +++ b/legacy/annotators/util.py @@ -1,3 +1,7 @@ +# Copyright (c) MLCommons 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. + # Copyright (c) Facebook, Inc. 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. diff --git a/mlcube/speech_data_selection/Dockerfile b/legacy/mlcube/speech_data_selection/Dockerfile similarity index 100% rename from mlcube/speech_data_selection/Dockerfile rename to legacy/mlcube/speech_data_selection/Dockerfile diff --git a/mlcube/speech_data_selection/Dockerfile_mlcube b/legacy/mlcube/speech_data_selection/Dockerfile_mlcube similarity index 100% rename from mlcube/speech_data_selection/Dockerfile_mlcube rename to legacy/mlcube/speech_data_selection/Dockerfile_mlcube diff --git a/mlcube/speech_data_selection/README.md b/legacy/mlcube/speech_data_selection/README.md similarity index 100% rename from mlcube/speech_data_selection/README.md rename to legacy/mlcube/speech_data_selection/README.md diff --git a/mlcube/speech_data_selection/config_files/dataperf_speech_config.yaml b/legacy/mlcube/speech_data_selection/config_files/dataperf_speech_config.yaml similarity index 100% rename from mlcube/speech_data_selection/config_files/dataperf_speech_config.yaml rename to legacy/mlcube/speech_data_selection/config_files/dataperf_speech_config.yaml diff --git a/mlcube/speech_data_selection/create_experiment.py b/legacy/mlcube/speech_data_selection/create_experiment.py similarity index 100% rename from mlcube/speech_data_selection/create_experiment.py rename to legacy/mlcube/speech_data_selection/create_experiment.py diff --git a/mlcube/speech_data_selection/eval.py b/legacy/mlcube/speech_data_selection/eval.py similarity index 100% rename from mlcube/speech_data_selection/eval.py rename to legacy/mlcube/speech_data_selection/eval.py diff --git a/mlcube/speech_data_selection/mlcube.py b/legacy/mlcube/speech_data_selection/mlcube.py similarity index 100% rename from mlcube/speech_data_selection/mlcube.py rename to legacy/mlcube/speech_data_selection/mlcube.py diff --git a/mlcube/speech_data_selection/mlcube.yaml b/legacy/mlcube/speech_data_selection/mlcube.yaml similarity index 100% rename from mlcube/speech_data_selection/mlcube.yaml rename to legacy/mlcube/speech_data_selection/mlcube.yaml diff --git a/mlcube/speech_data_selection/requirements.txt b/legacy/mlcube/speech_data_selection/requirements.txt similarity index 100% rename from mlcube/speech_data_selection/requirements.txt rename to legacy/mlcube/speech_data_selection/requirements.txt diff --git a/mlcube/speech_data_selection/selection/__init__.py b/legacy/mlcube/speech_data_selection/selection/__init__.py similarity index 100% rename from mlcube/speech_data_selection/selection/__init__.py rename to legacy/mlcube/speech_data_selection/selection/__init__.py diff --git a/mlcube/speech_data_selection/selection/load_samples.py b/legacy/mlcube/speech_data_selection/selection/load_samples.py similarity index 100% rename from mlcube/speech_data_selection/selection/load_samples.py rename to legacy/mlcube/speech_data_selection/selection/load_samples.py diff --git a/mlcube/speech_data_selection/selection/main.py b/legacy/mlcube/speech_data_selection/selection/main.py similarity index 100% rename from mlcube/speech_data_selection/selection/main.py rename to legacy/mlcube/speech_data_selection/selection/main.py diff --git a/mlcube/speech_data_selection/selection/selection.py b/legacy/mlcube/speech_data_selection/selection/selection.py similarity index 100% rename from mlcube/speech_data_selection/selection/selection.py rename to legacy/mlcube/speech_data_selection/selection/selection.py diff --git a/mlcube/speech_data_selection/utils/download_data.py b/legacy/mlcube/speech_data_selection/utils/download_data.py similarity index 100% rename from mlcube/speech_data_selection/utils/download_data.py rename to legacy/mlcube/speech_data_selection/utils/download_data.py diff --git a/mlcube/speech_data_selection/utils/run_evaluate.sh b/legacy/mlcube/speech_data_selection/utils/run_evaluate.sh similarity index 100% rename from mlcube/speech_data_selection/utils/run_evaluate.sh rename to legacy/mlcube/speech_data_selection/utils/run_evaluate.sh diff --git a/mlcube/speech_data_selection/workspace/.gitignore b/legacy/mlcube/speech_data_selection/workspace/.gitignore similarity index 100% rename from mlcube/speech_data_selection/workspace/.gitignore rename to legacy/mlcube/speech_data_selection/workspace/.gitignore diff --git a/mlcube/speech_data_selection/workspace/dataperf_speech_config.yaml b/legacy/mlcube/speech_data_selection/workspace/dataperf_speech_config.yaml similarity index 100% rename from mlcube/speech_data_selection/workspace/dataperf_speech_config.yaml rename to legacy/mlcube/speech_data_selection/workspace/dataperf_speech_config.yaml diff --git a/mlcube/speech_data_selection/workspace/parameters.yaml b/legacy/mlcube/speech_data_selection/workspace/parameters.yaml similarity index 100% rename from mlcube/speech_data_selection/workspace/parameters.yaml rename to legacy/mlcube/speech_data_selection/workspace/parameters.yaml diff --git a/mlcube/speech_data_selection/workspace/select_output/train.yaml b/legacy/mlcube/speech_data_selection/workspace/select_output/train.yaml similarity index 100% rename from mlcube/speech_data_selection/workspace/select_output/train.yaml rename to legacy/mlcube/speech_data_selection/workspace/select_output/train.yaml diff --git a/mlcube/vision_data_selection/Dockerfile b/legacy/mlcube/vision_data_selection/Dockerfile similarity index 100% rename from mlcube/vision_data_selection/Dockerfile rename to legacy/mlcube/vision_data_selection/Dockerfile diff --git a/mlcube/vision_data_selection/Dockerfile_mlcube b/legacy/mlcube/vision_data_selection/Dockerfile_mlcube similarity index 100% rename from mlcube/vision_data_selection/Dockerfile_mlcube rename to legacy/mlcube/vision_data_selection/Dockerfile_mlcube diff --git a/mlcube/vision_data_selection/README.md b/legacy/mlcube/vision_data_selection/README.md similarity index 100% rename from mlcube/vision_data_selection/README.md rename to legacy/mlcube/vision_data_selection/README.md diff --git a/mlcube/vision_data_selection/constants.py b/legacy/mlcube/vision_data_selection/constants.py similarity index 100% rename from mlcube/vision_data_selection/constants.py rename to legacy/mlcube/vision_data_selection/constants.py diff --git a/mlcube/vision_data_selection/data/embeddings/.gitignore b/legacy/mlcube/vision_data_selection/data/embeddings/.gitignore similarity index 100% rename from mlcube/vision_data_selection/data/embeddings/.gitignore rename to legacy/mlcube/vision_data_selection/data/embeddings/.gitignore diff --git a/mlcube/vision_data_selection/data/results/.gitignore b/legacy/mlcube/vision_data_selection/data/results/.gitignore similarity index 100% rename from mlcube/vision_data_selection/data/results/.gitignore rename to legacy/mlcube/vision_data_selection/data/results/.gitignore diff --git a/mlcube/vision_data_selection/data/test_sets/.gitignore b/legacy/mlcube/vision_data_selection/data/test_sets/.gitignore similarity index 100% rename from mlcube/vision_data_selection/data/test_sets/.gitignore rename to legacy/mlcube/vision_data_selection/data/test_sets/.gitignore diff --git a/mlcube/vision_data_selection/data/train_sets/.gitignore b/legacy/mlcube/vision_data_selection/data/train_sets/.gitignore similarity index 100% rename from mlcube/vision_data_selection/data/train_sets/.gitignore rename to legacy/mlcube/vision_data_selection/data/train_sets/.gitignore diff --git a/mlcube/vision_data_selection/docker-compose.yaml b/legacy/mlcube/vision_data_selection/docker-compose.yaml similarity index 100% rename from mlcube/vision_data_selection/docker-compose.yaml rename to legacy/mlcube/vision_data_selection/docker-compose.yaml diff --git a/mlcube/vision_data_selection/download_data.py b/legacy/mlcube/vision_data_selection/download_data.py similarity index 100% rename from mlcube/vision_data_selection/download_data.py rename to legacy/mlcube/vision_data_selection/download_data.py diff --git a/mlcube/vision_data_selection/eval.py b/legacy/mlcube/vision_data_selection/eval.py similarity index 100% rename from mlcube/vision_data_selection/eval.py rename to legacy/mlcube/vision_data_selection/eval.py diff --git a/mlcube/vision_data_selection/main.py b/legacy/mlcube/vision_data_selection/main.py similarity index 100% rename from mlcube/vision_data_selection/main.py rename to legacy/mlcube/vision_data_selection/main.py diff --git a/mlcube/vision_data_selection/mlcube.py b/legacy/mlcube/vision_data_selection/mlcube.py similarity index 100% rename from mlcube/vision_data_selection/mlcube.py rename to legacy/mlcube/vision_data_selection/mlcube.py diff --git a/mlcube/vision_data_selection/mlcube.yaml b/legacy/mlcube/vision_data_selection/mlcube.yaml similarity index 100% rename from mlcube/vision_data_selection/mlcube.yaml rename to legacy/mlcube/vision_data_selection/mlcube.yaml diff --git a/mlcube/vision_data_selection/requirements.txt b/legacy/mlcube/vision_data_selection/requirements.txt similarity index 100% rename from mlcube/vision_data_selection/requirements.txt rename to legacy/mlcube/vision_data_selection/requirements.txt diff --git a/mlcube/vision_data_selection/run_evaluate.sh b/legacy/mlcube/vision_data_selection/run_evaluate.sh similarity index 100% rename from mlcube/vision_data_selection/run_evaluate.sh rename to legacy/mlcube/vision_data_selection/run_evaluate.sh diff --git a/mlcube/vision_data_selection/selection.py b/legacy/mlcube/vision_data_selection/selection.py similarity index 100% rename from mlcube/vision_data_selection/selection.py rename to legacy/mlcube/vision_data_selection/selection.py diff --git a/mlcube/vision_data_selection/task_setup.yaml b/legacy/mlcube/vision_data_selection/task_setup.yaml similarity index 100% rename from mlcube/vision_data_selection/task_setup.yaml rename to legacy/mlcube/vision_data_selection/task_setup.yaml diff --git a/mlcube/vision_data_selection/utils.py b/legacy/mlcube/vision_data_selection/utils.py similarity index 100% rename from mlcube/vision_data_selection/utils.py rename to legacy/mlcube/vision_data_selection/utils.py diff --git a/mlcube/vision_data_selection/workspace/data/.gitignore b/legacy/mlcube/vision_data_selection/workspace/data/.gitignore similarity index 100% rename from mlcube/vision_data_selection/workspace/data/.gitignore rename to legacy/mlcube/vision_data_selection/workspace/data/.gitignore diff --git a/mlcube/vision_data_selection/workspace/parameters.yaml b/legacy/mlcube/vision_data_selection/workspace/parameters.yaml similarity index 100% rename from mlcube/vision_data_selection/workspace/parameters.yaml rename to legacy/mlcube/vision_data_selection/workspace/parameters.yaml