diff --git a/.github/code_spell_ignore.txt b/.github/code_spell_ignore.txt index 7fe214bb..319927fd 100644 --- a/.github/code_spell_ignore.txt +++ b/.github/code_spell_ignore.txt @@ -4,3 +4,5 @@ ROUGE ModelIn modelin fpr +PromptIn +pressEnter diff --git a/evals/evaluation/rag_pilot/Dockerfile b/evals/evaluation/rag_pilot/Dockerfile new file mode 100755 index 00000000..3266a103 --- /dev/null +++ b/evals/evaluation/rag_pilot/Dockerfile @@ -0,0 +1,18 @@ +FROM python:3.11-slim + +SHELL ["/bin/bash", "-o", "pipefail", "-c"] + +RUN pip install --no-cache-dir --upgrade pip setuptools==70.0.0 + +RUN useradd -m -s /bin/bash user && \ + mkdir -p /home/user && \ + chown -R user /home/user/ + +COPY ./ /home/user/rag_pilot + +USER user + +WORKDIR /home/user/rag_pilot +RUN pip install --no-cache-dir --extra-index-url https://download.pytorch.org/whl/cpu -r requirements.txt + +ENTRYPOINT ["python3", "-m", "server"] diff --git a/evals/evaluation/rag_pilot/README.md b/evals/evaluation/rag_pilot/README.md index 044db1c5..3a9dc1ce 100644 --- a/evals/evaluation/rag_pilot/README.md +++ b/evals/evaluation/rag_pilot/README.md @@ -18,25 +18,38 @@ RAG Pilot provides a set of tuners to optimize various parameters in a retrieval These tuners help in optimizing document parsing, chunking strategies, reranking efficiency, and embedding selection for improved RAG performance. -## ๐ŸŒ Online RAG Tuning +## ๐ŸŒ Quickstart Guide ### โš™๏ธ Dependencies and Environment Setup -#### ๐Ÿ› ๏ธ Setup EdgeCraftRAG +#### Setup EdgeCraftRAG Setup EdgeCraftRAG pipeline based on this [link](https://github.com/opea-project/GenAIExamples/tree/main/EdgeCraftRAG). Load documents in EdgeCraftRAG before running RAG Pilot. -#### ๐Ÿงช Create Running Environment +#### Setup RAG Pilot ```bash -# Create a virtual environment -python3 -m venv rag_pilot -source rag_pilot/bin/activate +cd rag_pilot -# Install dependencies -pip install -r requirements.txt +# (Optional) Build RAG Pilot and UI docker images +docker build --build-arg HTTP_PROXY=$HTTP_PROXY --build-arg HTTP_PROXYS=$HTTP_PROXYS --build-arg NO_PROXY=$NO_PROXY -t opea/ragpilot:latest -f ./Dockerfile . +docker build --build-arg HTTP_PROXY=$HTTP_PROXY --build-arg HTTP_PROXYS=$HTTP_PROXYS --build-arg NO_PROXY=$NO_PROXY -t opea/ragpilot-ui:latest -f ./ui/Dockerfile.ui . + +# Setup ENV +export ECRAG_SERVICE_HOST_IP=${HOST_IP} # HOST IP of EC-RAG Service, usually current host ip + +# If EC-RAG Service port is not default +#export ECRAG_SERVICE_PORT=16010 + +# If you want to change exposed RAG Pilot UI port +#export RAGPILOT_UI_SERVICE_PORT=8090 + +# If you want to change exposed RAG Pilot service port +#export RAGPILOT_SERVICE_PORT= + +docker compose -f docker_compose/intel/gpu/arc/compose.yaml up -d ``` ### ๐Ÿšฆ Launch RAG Pilot in Online Mode @@ -82,11 +95,11 @@ Each tuning run in **RAG Pilot** generates a set of structured output files for ##### ๐Ÿ“ Directory Layout - `rag_pilot_/`: Main folder for a tuning session. + - `summary.csv` โ€“ Overall performance metrics of all executed pipelines. - `curr_pipeline.json` โ€“ Best pipeline configuration. - `curr_rag_results.json` โ€“ Results of the best pipeline. - `rag_summary.csv` โ€“ Query-wise summary. - `rag_contexts.csv` โ€“ Detailed context analysis. - - `summary.csv` โ€“ Overall performance metrics. - `entry_/`: Subfolders for each tried pipeline with the same file structure: - `pipeline.json` - `rag_results.json` @@ -97,11 +110,11 @@ Each tuning run in **RAG Pilot** generates a set of structured output files for | File Name | Description | |----------------------|-----------------------------------------------------------------------------| +| `summary.csv` | Aggregated summary across all pipelines | | `pipeline.json` | RAG pipeline configuration used in a specific trial | | `rag_results.json` | List of results for each query, including metadata and context sets | | `rag_summary.csv` | Summary of each query's outcome, including response and context hit counts | | `rag_contexts.csv` | Breakdown of retrieved/reranked contexts and mapping to ground truth | -| `summary.csv` | Aggregated performance summary across all queries | **Context Mapping Notes:** diff --git a/evals/evaluation/rag_pilot/VERSION b/evals/evaluation/rag_pilot/VERSION new file mode 100644 index 00000000..e0ecd517 --- /dev/null +++ b/evals/evaluation/rag_pilot/VERSION @@ -0,0 +1 @@ +25.05-dev diff --git a/evals/evaluation/rag_pilot/api/__init__.py b/evals/evaluation/rag_pilot/api/__init__.py new file mode 100644 index 00000000..4057dc01 --- /dev/null +++ b/evals/evaluation/rag_pilot/api/__init__.py @@ -0,0 +1,2 @@ +# Copyright (C) 2025 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 diff --git a/evals/evaluation/rag_pilot/api/v1/__init__.py b/evals/evaluation/rag_pilot/api/v1/__init__.py new file mode 100644 index 00000000..4057dc01 --- /dev/null +++ b/evals/evaluation/rag_pilot/api/v1/__init__.py @@ -0,0 +1,2 @@ +# Copyright (C) 2025 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 diff --git a/evals/evaluation/rag_pilot/api/v1/pilot.py b/evals/evaluation/rag_pilot/api/v1/pilot.py new file mode 100644 index 00000000..34a17afc --- /dev/null +++ b/evals/evaluation/rag_pilot/api/v1/pilot.py @@ -0,0 +1,288 @@ +# Copyright (C) 2025 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +import json +import uuid +from io import BytesIO, StringIO +from typing import List + +from api_schema import GroundTruth, RAGStage, ResultOut, RunningStatus +from components.connect_utils import create_pipeline, update_active_pipeline, update_pipeline, upload_files +from components.pilot.base import RAGPipeline, convert_dict_to_pipeline +from components.pilot.ecrag.api_schema import DataIn, PipelineCreateIn +from components.pilot.pilot import pilot, update_rag_pipeline +from components.tuner.tunermgr import tunerMgr +from components.utils import load_rag_results_from_csv, load_rag_results_from_gt +from fastapi import Body, FastAPI, File, HTTPException, UploadFile +from fastapi.responses import JSONResponse, StreamingResponse + +pilot_app = FastAPI() + + +@pilot_app.post(path="/v1/pilot/pipeline/active") +async def add_active_pipeline(request: PipelineCreateIn): + ret = create_pipeline(request) + if hasattr(ret, "status_code") and ret.status_code != 200: + raise HTTPException(status_code=ret.status_code, detail=f"Failed to create pipeline: {ret.text}") + + if hasattr(ret, "text"): + try: + ret_dict = json.loads(ret.text) + except json.JSONDecodeError: + raise HTTPException(status_code=500, detail="Invalid JSON in pipeline creation response.") + elif isinstance(ret, dict): + ret_dict = ret + else: + raise HTTPException(status_code=500, detail="Unexpected return type from create_pipeline.") + + pipeline_config = convert_dict_to_pipeline(ret_dict) + pl = RAGPipeline(pipeline_config) + pilot.set_curr_pl(pl) + return "Added" + + +@pilot_app.post(path="/v1/pilot/pipeline/active/import") +async def import_active_pipeline(file: UploadFile = File(...)): + try: + content = await file.read() + request = json.loads(content) + pipeline_req = PipelineCreateIn(**request) + except json.JSONDecodeError: + raise HTTPException(status_code=400, detail="Uploaded file is not valid JSON.") + except Exception as e: + raise HTTPException(status_code=400, detail=f"Invalid pipeline request format: {e}") + + ret = create_pipeline(pipeline_req) + + if hasattr(ret, "status_code") and ret.status_code != 200: + raise HTTPException( + status_code=ret.status_code, detail=f"Failed to create pipeline: {getattr(ret, 'text', '')}" + ) + if hasattr(ret, "text"): + try: + ret_dict = json.loads(ret.text) + except json.JSONDecodeError: + raise HTTPException(status_code=500, detail="Invalid JSON in pipeline creation response.") + elif isinstance(ret, dict): + ret_dict = ret + else: + raise HTTPException(status_code=500, detail="Unexpected return type from create_pipeline.") + + pl = RAGPipeline(convert_dict_to_pipeline(ret_dict)) + pilot.set_curr_pl(pl) + return "Added" + + +@pilot_app.get(path="/v1/pilot/pipeline/active") +async def get_active_pipeline(): + return pilot.get_curr_pl() + + +@pilot_app.get(path="/v1/pilot/pipeline/active/prompt") +async def get_active_pipeline_prompt(): + return pilot.get_curr_pl().get_prompt() if pilot.get_curr_pl() else None + + +@pilot_app.get(path="/v1/pilot/pipeline/active/export") +async def export_active_pipeline(): + try: + pl_dict = pilot.get_curr_pl().export_pipeline().dict() + json_bytes = json.dumps(pl_dict, indent=2).encode("utf-8") + return StreamingResponse( + BytesIO(json_bytes), + media_type="application/json", + headers={"Content-Disposition": "attachment; filename=active_pipeline.json"}, + ) + except Exception as e: + raise HTTPException(status_code=500, detail=f"Failed to export pipeline: {e}") + + +@pilot_app.get(path="/v1/pilot/pipeline/active/id") +async def get_active_pipeline_id(): + return pilot.get_curr_pl_id() + + +@pilot_app.patch(path="/v1/pilot/pipeline/active") +async def update_active_pl(request: PipelineCreateIn): + ret = update_active_pipeline(request) + pl = RAGPipeline(convert_dict_to_pipeline(ret)) + pilot.set_curr_pl(pl) + return "Updated" + + +@pilot_app.post(path="/v1/pilot/pipeline/active/run") +async def run_active_pipeline(): + if pilot.run_pipeline(): + return "Done" + else: + return "ERROR: Current pipeline cannot execute" + + +@pilot_app.patch(path="/v1/pilot/pipeline/active/top_n/{top_n}") +async def update_active_pl_top_n(top_n: int): + pl_config = pilot.get_curr_pl().export_pipeline() + + reranker_found = False + for pp in pl_config.postprocessor: + if pp.processor_type == "reranker": + pp.top_n = top_n + reranker_found = True + + if not reranker_found: + return {"error": "Reranker not found"}, 404 + + ret = update_active_pipeline(pl_config) + pl = RAGPipeline(convert_dict_to_pipeline(ret)) + pl.regenerate_id() + pilot.set_curr_pl(pl) + + return {"message": "Updated", "new_top_n": top_n} + + +@pilot_app.get(path="/v1/pilot/pipeline/{id}") +async def get_pipeline_by_id(id: uuid.UUID): + return pilot.get_pl(id) + + +@pilot_app.get(path="/v1/pilot/pipeline/{id}/prompt") +async def get_pipeline_prompt_by_id(id: uuid.UUID): + return pilot.get_pl(id).get_prompt() if pilot.get_pl(id) else None + + +@pilot_app.get(path="/v1/pilot/pipeline/{id}/export") +async def export_pipeline_by_id(id: uuid.UUID): + try: + pl_dict = pilot.get_curr_pl().export_pipeline().dict() + json_bytes = json.dumps(pl_dict, indent=2).encode("utf-8") + return StreamingResponse( + BytesIO(json_bytes), + media_type="application/json", + headers={"Content-Disposition": "attachment; filename=active_pipeline.json"}, + ) + except Exception as e: + raise HTTPException(status_code=500, detail=f"Failed to export pipeline: {e}") + + +@pilot_app.post(path="/v1/pilot/pipeline/{id}/active") +async def set_active_pipeline_by_id(id: uuid.UUID): + if pilot.set_curr_pl_by_id(id): + return "Done" + else: + return f"Error: Pipeline {id} cannot be set" + + +@pilot_app.post(path="/v1/pilot/pipeline/{id}/run") +async def run_pipeline_by_id(id: uuid.UUID): + if pilot.set_curr_pl_by_id(id): + if pilot.run_pipeline(): + return "Done" + else: + return f"Error: Pipeline {id} cannot execute" + else: + return f"Error: Pipeline {id} does not exist" + + +@pilot_app.post(path="/v1/pilot/files") +async def add_files(request: DataIn): + ret = upload_files(request) + + if ret.status_code != 200: + raise HTTPException(status_code=ret.status_code, detail=f"Failed to upload files: {ret.text}") + + try: + return ret.json() + except ValueError: + return {"detail": "File uploaded, but response was not valid JSON.", "raw": ret.text} + + +def load_rag_results_from_uploaded_file(uploaded_file: UploadFile, filetype: str): + content = uploaded_file.file.read().decode("utf-8") + if filetype == "csv": + csv_buffer = StringIO(content) + return load_rag_results_from_csv(csv_buffer) + if filetype == "json": + json_gts = json.loads(content) + gts = [GroundTruth(**gt) for gt in json_gts] + return load_rag_results_from_gt(gts) + + +@pilot_app.get(path="/v1/pilot/ground_truth") +async def get_rag_ground_truth(): + return "Not Implemented" + + +@pilot_app.post(path="/v1/pilot/ground_truth") +async def update_rag_ground_truth(gts: List[GroundTruth]): + try: + rag_results = load_rag_results_from_gt(gts) + + if not rag_results.results: + raise ValueError("No results found.") + + if pilot.update_rag_results_sample(rag_results): + pilot.clear_rag_result_dict() + for stage in RAGStage: + tunerMgr.reset_tuners_by_stage(stage) + return "RAG ground truth updated and database cleared" + else: + return "Error" + + except Exception as e: + raise HTTPException(status_code=500, detail=f"Internal server error: {e}") + + +@pilot_app.post(path="/v1/pilot/ground_truth/file") +async def update_rag_ground_truth_file(file: UploadFile = File(...)): + filetype = "" + if file.filename.endswith(".csv"): + filetype = "csv" + elif file.filename.endswith(".json"): + filetype = "json" + else: + raise HTTPException(status_code=400, detail="Only CSV and JSON files are supported.") + + try: + await file.seek(0) + rag_results = load_rag_results_from_uploaded_file(file, filetype) + + if not rag_results.results: + raise ValueError("No results found in the uploaded file.") + + if pilot.update_rag_results_sample(rag_results): + pilot.clear_rag_result_dict() + for stage in RAGStage: + tunerMgr.reset_tuners_by_stage(stage) + return "RAG ground truth file updated and database cleared" + else: + return "Error" + + except ValueError as e: + raise HTTPException(status_code=400, detail=str(e)) + except Exception as e: + raise HTTPException(status_code=500, detail=f"Internal server error: {e}") + + +@pilot_app.get(path="/v1/pilot/pipeline/{id}/results") +async def get_pipeline_results(id: uuid.UUID): + return pilot.get_results(id) + + +@pilot_app.get(path="/v1/pilot/pipeline/{id}/results/metrics") +async def get_pipeline_metrics(id: uuid.UUID): + return pilot.get_results_metrics(id) + + +@pilot_app.patch(path="/v1/pilot/pipeline/{id}/results/metrics") +async def update_pipeline_metrics(id: uuid.UUID, request: list[ResultOut] = Body(...)): + update_results = [] + for result in request: + success = pilot.update_result_metrics(id, result.query_id, result.metadata) + update_results.append({"query_id": result.query_id, "updated": success}) + + return update_results + + +@pilot_app.post(path="/v1/pilot/save") +async def save_dicts(): + folder = pilot.save_dicts() + return f"All results saved in {folder}" diff --git a/evals/evaluation/rag_pilot/api/v1/tuner.py b/evals/evaluation/rag_pilot/api/v1/tuner.py new file mode 100644 index 00000000..38adb3d4 --- /dev/null +++ b/evals/evaluation/rag_pilot/api/v1/tuner.py @@ -0,0 +1,247 @@ +# Copyright (C) 2025 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +import asyncio +from typing import List, Optional + +from api_schema import RAGStage, RunningStatus, TunerOut +from components.pilot.base import Metrics +from components.pilot.pilot import pilot +from components.tuner.tunermgr import tunerMgr +from fastapi import FastAPI, Path + +tuner_app = FastAPI() + + +def get_best_pl_id(pl_id_list: List[int], stage=None): + best_pl_id = None + best_metric = float("-inf") + + if stage is RAGStage.RETRIEVAL: + metric = Metrics.RETRIEVAL_RECALL + elif stage is RAGStage.POSTPROCESSING: + metric = Metrics.POSTPROCESSING_RECALL + else: + return None + + metric_dict = {} + for pl_id in pl_id_list: + rate = pilot.rag_results_dict[pl_id].get_metric(metric) if pl_id in pilot.rag_results_dict else float("-inf") + metric_dict[pl_id] = rate + if rate > best_metric: + best_metric = rate + best_pl_id = pl_id + + return best_pl_id + + +@tuner_app.get(path="/v1/tuners/stage/{stage}", response_model=List[TunerOut]) +async def get_tuners_by_stage(stage: RAGStage = Path(...)): + active_pl = pilot.get_curr_pl() + tunerMgr.update_adaptor(active_pl) + tuner_names = tunerMgr.get_tuners_by_stage(stage) + tuners_out = [] + + for name in tuner_names: + tuners_out.append(tunerMgr.get_tuner_out(name, stage)) + + return tuners_out + + +@tuner_app.get(path="/v1/tuners/stage/{stage}/status") +async def get_stage_status(stage: RAGStage = Path(...)): + return {stage: tunerMgr.get_stage_status(stage).value} + + +pipeline_run_lock = asyncio.Lock() + + +async def run_tuners_in_background(stage: Optional[RAGStage], tuner_names: List[str]): + for tuner_name in tuner_names: + status = tunerMgr.get_tuner_status(tuner_name) + if status is not RunningStatus.NOT_STARTED: + print(f"[Tuner {tuner_name}] Skipped, current status {status}.") + continue + + async with pipeline_run_lock: + try: + tunerMgr.set_tuner_status(tuner_name, RunningStatus.IN_PROGRESS) + print(f"[Tuner {tuner_name}] Starting...") + + pl = pilot.get_curr_pl() + tunerMgr.update_adaptor(pl) + + pl_list, params_candidates = tunerMgr.run_tuner(tuner_name, pl) + if tunerMgr.get_tuner_status(tuner_name) is RunningStatus.INACTIVE: + print(f"[Tuner {tuner_name}] is inactive. Skipped") + + for new_pl in pl_list: + pilot.add_rag_pipeline(new_pl) + + for pl, params in zip(pl_list, params_candidates): + print(f"[Tuner {tuner_name}]: Running {pl.get_id()}") + for attr, tunerUpdate in params.items(): + print( + f"[Tuner {tuner_name}][{pl.get_id()}]: Setting {tunerUpdate.node_type}.{tunerUpdate.module_type}.{attr} to {tunerUpdate.val}" + ) + if stage == RAGStage.RETRIEVAL or stage == RAGStage.POSTPROCESSING: + await asyncio.to_thread(pilot.run_pipeline_blocked, pl, True) + else: + await asyncio.to_thread(pilot.run_pipeline_blocked, pl) + + actual_stage = stage or tunerMgr.get_tuner_stage(tuner_name) + best_pl = await asyncio.to_thread(pilot.change_best_recall_pl, actual_stage) + best_pl_id = best_pl.get_id() if best_pl else None + tunerMgr.complete_tuner(tuner_name, best_pl_id) + print(f"[Tuner {tuner_name}] Completed. Best pipeline ID: {best_pl_id or 'None'}") + + except Exception as e: + print(f"[Tuner {tuner_name}] Error while running pipelines: {e}") + + +@tuner_app.post(path="/v1/tuners/stage/{stage}/run") +async def run_stage_tuner(stage: RAGStage = Path(...)): + tuner_names = tunerMgr.get_tuners_by_stage(stage) + tuner_outs = [tunerMgr.get_tuner_out(tuner_name, stage) for tuner_name in tuner_names] + + asyncio.create_task(run_tuners_in_background(stage, tuner_names)) + return tuner_outs + + +@tuner_app.post(path="/v1/tuners/stage/{stage}/reset") +async def reset_stage_tuner(stage: RAGStage = Path(...)): + tunerMgr.reset_tuners_by_stage(stage) + return "Done" + + +@tuner_app.get(path="/v1/tuners/stage/{stage}/results") +async def get_stage_results(stage: RAGStage = Path(...)): + tuner_names = tunerMgr.get_tuners_by_stage(stage) + results_dict = {} + for tuner_name in tuner_names: + record = tunerMgr.get_tuner_record(tuner_name) + if record is not None: + all_pipeline_ids = list(record.all_pipeline_ids) + for pl_id in all_pipeline_ids: + results_dict[pl_id] = pilot.get_results(pl_id) + + return results_dict + + +@tuner_app.get(path="/v1/tuners/stage/{stage}/results/metrics") +async def get_stage_results_metrics(stage: RAGStage = Path(...)): + tuner_names = tunerMgr.get_tuners_by_stage(stage) + metrics_dict = {} + for tuner_name in tuner_names: + record = tunerMgr.get_tuner_record(tuner_name) + if record is not None: + all_pipeline_ids = list(record.all_pipeline_ids) + for pl_id in all_pipeline_ids: + metrics_dict[pl_id] = pilot.get_results_metrics(pl_id) + + return metrics_dict + + +@tuner_app.get(path="/v1/tuners/stage/{stage}/pipelines") +async def get_stage_pipelines(stage: RAGStage = Path(...)): + tuner_names = tunerMgr.get_tuners_by_stage(stage) + pipeline_list = [] + for tuner_name in tuner_names: + record = tunerMgr.get_tuner_record(tuner_name) + if record is not None and record.best_pipeline_id is None: + pl_id_list = list(record.all_pipeline_ids) + if record.base_pipeline_id not in pl_id_list: + pl_id_list.append(record.base_pipeline_id) + best_pl_id = get_best_pl_id(record.all_pipeline_ids, stage) + record.best_pipeline_id = best_pl_id + pipeline_list.append(tunerMgr.get_tuner_update_outs_by_name(tuner_name)) + return pipeline_list + + +@tuner_app.get(path="/v1/tuners/{tuner_name}/pipelines/best") +async def get_pipeline_best(tuner_name): + record = tunerMgr.get_tuner_record(tuner_name) + if record is not None and record.best_pipeline_id is None: + stage = tunerMgr.get_tuner_stage(tuner_name) + pl_id_list = list(record.all_pipeline_ids) + if record.base_pipeline_id not in pl_id_list: + pl_id_list.append(record.base_pipeline_id) + best_pl_id = get_best_pl_id(pl_id_list, stage) + record.best_pipeline_id = best_pl_id + + return tunerMgr.get_pipeline_best(tuner_name) + + +@tuner_app.get(path="/v1/tuners/{tuner_name}/pipelines/base") +async def get_pipeline_base(tuner_name): + return tunerMgr.get_pipeline_base(tuner_name) + + +@tuner_app.post(path="/v1/tuners/{tuner_name}/run") +async def run_tuner(tuner_name: str): + stage = tunerMgr.get_tuner_stage(tuner_name) + asyncio.create_task(run_tuners_in_background(stage, [tuner_name])) + tunerOut = tunerMgr.get_tuner_out(tuner_name) + return tunerOut + + +@tuner_app.post(path="/v1/tuners/{tuner_name}/reset") +async def reset_tuner(tuner_name): + tunerMgr.set_tuner_status(tuner_name, RunningStatus.NOT_STARTED) + return "Done" + + +@tuner_app.get(path="/v1/tuners/{tuner_name}") +async def get_tuner(tuner_name): + record = tunerMgr.get_tuner_record(tuner_name) + if record is not None and record.best_pipeline_id is None: + stage = tunerMgr.get_tuner_stage(tuner_name) + pl_id_list = list(record.all_pipeline_ids) + if record.base_pipeline_id not in pl_id_list: + pl_id_list.append(record.base_pipeline_id) + best_pl_id = get_best_pl_id(record.all_pipeline_ids, stage) + record.best_pipeline_id = best_pl_id + return tunerMgr.get_tuner_update_outs_by_name(tuner_name) + + +@tuner_app.get(path="/v1/tuners/{tuner_name}/status") +async def get_stage_status_by_tuner_name(tuner_name): + status = tunerMgr.get_tuner_status(tuner_name) + return status.value if status else f"Invalid tuner {tuner_name}" + + +@tuner_app.get(path="/v1/tuners/{tuner_name}/pipelines") +async def get_tuner_pipelines(tuner_name): + record = tunerMgr.get_tuner_record(tuner_name) + if record is not None and record.best_pipeline_id is None: + stage = tunerMgr.get_tuner_stage(tuner_name) + pl_id_list = list(record.all_pipeline_ids) + if record.base_pipeline_id not in pl_id_list: + pl_id_list.append(record.base_pipeline_id) + best_pl_id = get_best_pl_id(record.all_pipeline_ids, stage) + record.best_pipeline_id = best_pl_id + return tunerMgr.get_tuner_update_outs_by_name(tuner_name) + + +@tuner_app.get(path="/v1/tuners/{tuner_name}/results") +async def get_tuner_results(tuner_name): + record = tunerMgr.get_tuner_record(tuner_name) + results_dict = {} + if record is not None: + all_pipeline_ids = list(record.all_pipeline_ids) + for pl_id in all_pipeline_ids: + results_dict[pl_id] = pilot.get_results(pl_id) + + return results_dict + + +@tuner_app.get(path="/v1/tuners/{tuner_name}/results/metrics") +async def get_tuner_results_metrics(tuner_name): + record = tunerMgr.get_tuner_record(tuner_name) + metrics_dict = {} + if record is not None: + all_pipeline_ids = list(record.all_pipeline_ids) + for pl_id in all_pipeline_ids: + metrics_dict[pl_id] = pilot.get_results_metrics(pl_id) + + return metrics_dict diff --git a/evals/evaluation/rag_pilot/api_schema.py b/evals/evaluation/rag_pilot/api_schema.py new file mode 100644 index 00000000..26a86a06 --- /dev/null +++ b/evals/evaluation/rag_pilot/api_schema.py @@ -0,0 +1,70 @@ +# Copyright (C) 2025 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +import uuid +from enum import Enum +from typing import Any, Dict, List, Optional, Union + +from pydantic import BaseModel + + +class RunningStatus(str, Enum): + INACTIVE = "inactive" + NOT_STARTED = "not_started" + IN_PROGRESS = "in_progress" + COMPLETED = "completed" + + +class RAGStage(str, Enum): + RETRIEVAL = "retrieval" + POSTPROCESSING = "postprocessing" + GENERATION = "generation" + + +class TunerOut(BaseModel): + stage: str + name: str + targets: str + status: str + + +class TunerUpdateOut(BaseModel): + tuner_name: Optional[str] = None + base_pipeline_id: Optional[uuid.UUID] = None + pipeline_id: uuid.UUID + targets: Dict[str, Union[str, int]] + + +class ContextItem(BaseModel): + context_idx: Optional[int] = None + file_name: Optional[str] = None + text: Optional[str] = "" + metadata: Optional[Dict[str, Union[int, float]]] = {} + + +class ResultOut(BaseModel): + query_id: int + metadata: Optional[Dict[str, Union[int, float]]] = {} + query: Optional[str] = None + ground_truth: Optional[str] = None + response: Optional[str] = None + gt_contexts: Optional[List[ContextItem]] = None + retrieval_contexts: Optional[List[ContextItem]] = None + postprocessing_contexts: Optional[List[ContextItem]] = None + + +class ResultsOut(BaseModel): + metadata: Optional[Dict[str, Union[int, float]]] = {} + results: Optional[List[ResultOut]] = None + + +class GroundTruthContext(BaseModel): + filename: str + text: str + + +class GroundTruth(BaseModel): + query_id: int + query: str + contexts: List[GroundTruthContext] + answer: Optional[str] = None diff --git a/evals/evaluation/rag_pilot/components/connect_utils.py b/evals/evaluation/rag_pilot/components/connect_utils.py new file mode 100644 index 00000000..14530ec3 --- /dev/null +++ b/evals/evaluation/rag_pilot/components/connect_utils.py @@ -0,0 +1,144 @@ +# Copyright (C) 2025 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +import json +import os + +import requests +from components.pilot.base import convert_dict_to_pipeline +from components.pilot.ecrag.api_schema import PipelineCreateIn, RagOut + +ECRAG_SERVICE_HOST_IP = os.getenv("ECRAG_SERVICE_HOST_IP", "127.0.0.1") +ECRAG_SERVICE_PORT = int(os.getenv("ECRAG_SERVICE_PORT", 16010)) +server_addr = f"http://{ECRAG_SERVICE_HOST_IP}:{ECRAG_SERVICE_PORT}" + + +def get_active_pipeline() -> PipelineCreateIn: + path = "/v1/settings/pipelines" + res = requests.get(f"{server_addr}{path}", proxies={"http": None}) + if res.status_code == 200: + for pl in res.json(): + if pl["status"]["active"]: + return convert_dict_to_pipeline(pl) + return None + + +def load_prompt(prompt_text): + path = "/v1/chatqna/prompt" + request_data = {"prompt": prompt_text} + res = requests.post(f"{server_addr}{path}", json=request_data, proxies={"http": None}) + + if res.status_code == 200: + print("Successfully set prompt") + return True + else: + error_detail = res.text if hasattr(res, "text") else "Unknown error" + print(f"Failed to set prompt: {error_detail}") + return False + + +def create_pipeline(pipeline_conf): + path = "/v1/settings/pipelines" + return requests.post(f"{server_addr}{path}", json=pipeline_conf.dict(), proxies={"http": None}) + + +def update_pipeline(pipeline_conf): + path = "/v1/settings/pipelines" + return requests.patch( + f"{server_addr}{path}/{pipeline_conf.name}", json=pipeline_conf.dict(), proxies={"http": None} + ) + + +def update_active_pipeline(pipeline): + pipeline.active = False + res = update_pipeline(pipeline) + if res.status_code == 200: + pipeline.active = True + res = update_pipeline(pipeline) + if res.status_code == 200: + return res.json() + else: + return None + + +def upload_files(file_conf): + path = "/v1/data" + return requests.post(f"{server_addr}{path}", json=file_conf.dict(), proxies={"http": None}) + + +def get_ragqna(query): + new_req = {"messages": query, "stream": True} + path = "/v1/ragqna" + res = requests.post(f"{server_addr}{path}", json=new_req, proxies={"http": None}) + if res.status_code == 200: + return RagOut(**res.json()) + else: + return None + + +def get_retrieval(query): + new_req = {"messages": query} + path = "/v1/retrieval" + res = requests.post(f"{server_addr}{path}", json=new_req, proxies={"http": None}) + if res.status_code == 200: + return RagOut(**res.json()) + else: + return None + + +def reindex_data(): + path = "/v1/data" + res = requests.post(f"{server_addr}{path}/reindex", proxies={"http": None}) + return res.status_code == 200 + + +def get_ecrag_module_map(ecrag_pl): + ecrag_modules = { + # root + "root": (ecrag_pl, ""), + # node_parser + "node_parser": (ecrag_pl, "node_parser"), + "simple": (ecrag_pl, "node_parser"), + "hierarchical": (ecrag_pl, "node_parser"), + "sentencewindow": (ecrag_pl, "node_parser"), + # indexer + "indexer": (ecrag_pl, "indexer"), + "vector": (ecrag_pl, "indexer"), + "faiss_vector": (ecrag_pl, "indexer"), + # retriever + "retriever": (ecrag_pl, "retriever"), + "vectorsimilarity": (ecrag_pl, "retriever"), + "auto_merge": (ecrag_pl, "retriever"), + "bm25": (ecrag_pl, "retriever"), + # postprocessor + "postprocessor": (ecrag_pl, "postprocessor[0]"), + "reranker": (ecrag_pl, "postprocessor[0]"), + "metadata_replace": (ecrag_pl, "postprocessor[0]"), + # generator + "generator": (ecrag_pl, "generator"), + } + return ecrag_modules + + +COMP_TYPE_MAP = { + "node_parser": "parser_type", + "indexer": "indexer_type", + "retriever": "retriever_type", + "postprocessor": "processor_type", + "generator": "inference_type", +} + + +def load_pipeline_from_json(file_path): + try: + with open(file_path, "r", encoding="utf-8") as file: + data = json.load(file) + return convert_dict_to_pipeline(data) + except FileNotFoundError: + print(f"The file '{file_path}' was not found.") + except json.JSONDecodeError: + print(f"Error decoding JSON in the file '{file_path}'.") + except Exception as e: + print(f"An unexpected error occurred: {e}") + + return None diff --git a/evals/evaluation/rag_pilot/components/llm_eval/doc.py b/evals/evaluation/rag_pilot/components/llm_eval/doc.py new file mode 100644 index 00000000..64fba3fd --- /dev/null +++ b/evals/evaluation/rag_pilot/components/llm_eval/doc.py @@ -0,0 +1,49 @@ +# Copyright (C) 2025 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +import json +from dataclasses import dataclass, field +from typing import Dict, List, Optional + +from dataclasses_json import dataclass_json + +from . import metrics + + +@dataclass_json +@dataclass +class RetrievedDoc: + doc_id: Optional[str] = None + text: str = "" + + +@dataclass_json +@dataclass +class RAGResult: + query_id: str + query: str + gt_answer: str + response: str + retrieved_contexts: List[RetrievedDoc] = None # Retrieved documents + metrics: Dict[str, float] = field(default_factory=dict) + + +@dataclass_json +@dataclass +class RAGResults: + results: List[RAGResult] = field(default_factory=list) + metrics: Dict[str, Dict[str, float]] = field( + default_factory=lambda: { + metrics.overall_metrics: {}, + metrics.retriever_metrics: {}, + metrics.generator_metrics: {}, + } + ) + + def __repr__(self) -> str: + metrics = " " + "\n ".join(json.dumps(self.metrics, indent=2).split("\n")) + return f"RAGResults(\n {len(self.results):,} RAG results,\n" f" Metrics:\n{metrics}\n)" + + def update(self, rag_result: List[RAGResult]): + self.results.append(rag_result) + self.metrics = {metrics.overall_metrics: {}, metrics.retriever_metrics: {}, metrics.generator_metrics: {}} diff --git a/evals/evaluation/rag_pilot/components/llm_eval/evaluator.py b/evals/evaluation/rag_pilot/components/llm_eval/evaluator.py new file mode 100644 index 00000000..adf78536 --- /dev/null +++ b/evals/evaluation/rag_pilot/components/llm_eval/evaluator.py @@ -0,0 +1,76 @@ +# Copyright (C) 2025 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +from typing import Any, List, Optional + +from comps import opea_microservices, register_microservice +from pydantic import BaseModel + +from .doc import RAGResults +from .metrics import * +from .metrics_parser import DeepevalMetricsParser, EvaluatorType, RagasMetricsParser + +default_llm_name = "Qwen/Qwen2-7B-Instruct" + + +class EvaluatorCreateIn(BaseModel): + + llm_name: Optional[str] = default_llm_name + evaluator_type: Optional[str] = EvaluatorType.RAGAS + metrics: Optional[str] = "all_metrics" + + +class MetricsIn(BaseModel): + + metrics: str + + +class Evaluator: + def __init__(self): + self.metrics_parser = None + + +@register_microservice( + name="opea_service@ec_rag", endpoint="/v1/settings/evaluator", host="0.0.0.0", port=16020, methods=["POST"] +) +async def create_metrics(request: EvaluatorCreateIn): + match request.evaluator_type: + case EvaluatorType.RAGAS: + metrics_parser = RagasMetricsParser(request.llm_name) + case EvaluatorType.DEEPEVAL: + metrics_parser = DeepevalMetricsParser(request.llm_name) + case _: + pass + if metrics_parser is not None: + metrics_parser.create_metrics(request.metrics) + evaluator.metrics_parser = metrics_parser + return f"Metrics {request.metrics} on {request.evaluator_type} are created" + else: + return f"Fail to create evaluator {request.evaluator_type} with metrics {request.metrics}" + + +@register_microservice( + name="opea_service@ec_rag", endpoint="/v1/settings/metrics", host="0.0.0.0", port=16020, methods=["POST"] +) +async def update_metrics(request: MetricsIn): + if evaluator.metrics_parser is not None: + evaluator.metrics_parser.create_metrics(request.metrics) + return f"Metrics {request.metrics} is updated" + else: + return "Metrics parser is not initiated" + + +@register_microservice( + name="opea_service@ec_rag", endpoint="/v1/data/ragresults", host="0.0.0.0", port=16020, methods=["POST"] +) +async def evaluate(request: RAGResults): + if evaluator.metrics_parser is not None: + evaluator.metrics_parser.evaluate(request) + return repr(request) + else: + return "Metrics parser is not initiated" + + +if __name__ == "__main__": + evaluator = Evaluator() + opea_microservices["opea_service@ec_rag"].start() diff --git a/evals/evaluation/rag_pilot/components/llm_eval/examples/checking_inputs.json b/evals/evaluation/rag_pilot/components/llm_eval/examples/checking_inputs.json new file mode 100644 index 00000000..20f0f664 --- /dev/null +++ b/evals/evaluation/rag_pilot/components/llm_eval/examples/checking_inputs.json @@ -0,0 +1,28 @@ +{ + "results": [ + { + "query_id": "0", + "query": "What's the longest river in the world?", + "gt_answer": "The Nile is a major north-flowing river in northeastern Africa. It flows into the Mediterranean Sea. The Nile is the longest river in Africa and has historically been considered the longest river in the world, though this has been contested by research suggesting that the Amazon River is slightly longer. Of the world's major rivers, the Nile is one of the smallest, as measured by annual flow in cubic metres of water. About 6,650 km (4,130 mi) long, its drainage basin covers eleven countries: the Democratic Republic of the Congo, Tanzania, Burundi, Rwanda, Uganda, Kenya, Ethiopia, Eritrea, South Sudan, Sudan, and Egypt.", + "response": "The longest river in the world is the Nile, stretching approximately 6,650 kilometers (4,130 miles) through northeastern Africa, flowing through countries such as Uganda, Sudan, and Egypt before emptying into the Mediterranean Sea. There is some debate about this title, as recent studies suggest the Amazon River could be longer if its longest tributaries are included, potentially extending its length to about 7,000 kilometers (4,350 miles).", + "retrieved_context": [ + { + "doc_id": "000", + "text": "Scientists debate whether the Amazon or the Nile is the longest river in the world. Traditionally, the Nile is considered longer, but recent information suggests that the Amazon may be longer." + }, + { + "doc_id": "001", + "text": "The Nile River was central to the Ancient Egyptians' rise to wealth and power. Since rainfall is almost non-existent in Egypt, the Nile River and its yearly floodwaters offered the people a fertile oasis for rich agriculture." + }, + { + "doc_id": "002", + "text": "The world's longest rivers are defined as the longest natural streams whose water flows within a channel, or streambed, with defined banks." + }, + { + "doc_id": "003", + "text": "The Amazon River could be considered longer if its longest tributaries are included, potentially extending its length to about 7,000 kilometers" + } + ] + } + ] +} diff --git a/evals/evaluation/rag_pilot/components/llm_eval/examples/test_evaluator.json b/evals/evaluation/rag_pilot/components/llm_eval/examples/test_evaluator.json new file mode 100644 index 00000000..9f1eef0a --- /dev/null +++ b/evals/evaluation/rag_pilot/components/llm_eval/examples/test_evaluator.json @@ -0,0 +1,5 @@ +{ + "llm_name": "Qwen/Qwen2-7B-Instruct", + "evaluator_type": "deepeval", + "metrics": "all_metrics" +} diff --git a/evals/evaluation/rag_pilot/components/llm_eval/examples/test_metrics.json b/evals/evaluation/rag_pilot/components/llm_eval/examples/test_metrics.json new file mode 100644 index 00000000..cd4d825d --- /dev/null +++ b/evals/evaluation/rag_pilot/components/llm_eval/examples/test_metrics.json @@ -0,0 +1,3 @@ +{ + "metrics": "retriever_metrics" +} diff --git a/evals/evaluation/rag_pilot/components/llm_eval/metrics.py b/evals/evaluation/rag_pilot/components/llm_eval/metrics.py new file mode 100644 index 00000000..1af5a2cc --- /dev/null +++ b/evals/evaluation/rag_pilot/components/llm_eval/metrics.py @@ -0,0 +1,41 @@ +# Copyright (C) 2025 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +overall_metrics = "overall_metrics" +precision = "precision" +recall = "recall" +f1 = "f1" + +retriever_metrics = "retriever_metrics" +context_recall = "context_recall" +context_precision = "context_precision" +context_relevancy = "context_relevancy" +context_entity_recall = "context_entity_recall" + +generator_metrics = "generator_metrics" +answer_correctness = "answer_correctness" +answer_relevancy = "answer_relevancy" +answer_similarity = "answer_similarity" +faithfulness = "faithfulness" + +all_metrics = "all_metrics" + + +METRIC_GROUP_MAP = { + overall_metrics: [precision, recall, f1], + retriever_metrics: [context_recall, context_precision, context_entity_recall, context_relevancy], + generator_metrics: [answer_correctness, answer_relevancy, answer_similarity, faithfulness], + all_metrics: [ + precision, + recall, + f1, + context_recall, + context_precision, + context_entity_recall, + context_relevancy, + answer_correctness, + answer_relevancy, + answer_similarity, + faithfulness, + ], +} diff --git a/evals/evaluation/rag_pilot/components/llm_eval/metrics_parser.py b/evals/evaluation/rag_pilot/components/llm_eval/metrics_parser.py new file mode 100644 index 00000000..2433ff8d --- /dev/null +++ b/evals/evaluation/rag_pilot/components/llm_eval/metrics_parser.py @@ -0,0 +1,234 @@ +# Copyright (C) 2025 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +import threading +import warnings +from abc import ABC, abstractmethod +from enum import Enum +from typing import Any, List, Optional + +import numpy as np +import torch +from datasets import Dataset + +from .doc import RAGResult, RAGResults +from .metrics import * +from .utils_eval import clean_memory, load_hf_pipeline + + +class EvaluatorType(str, Enum): + + RAGAS = "ragas" + DEEPEVAL = "deepeval" + + +class MetricsParser(ABC): + + def __init__(self): + self.metrics = [] + + @abstractmethod + def load_model(self): + pass + + @abstractmethod + def create_metrics(self, metrics: List[str]): + pass + + @abstractmethod + def evaluate(self, results: RAGResults, metrics=all_metrics, save_path=None): + pass + + def aggregate_results_metrics(self, results: RAGResults): + for group, group_metrics in METRIC_GROUP_MAP.items(): + if group == all_metrics: + continue + for metric in group_metrics: + if metric in self.metrics: + metric_values = [result.metrics.get(metric, np.nan) for result in results.results] + if not np.isnan(metric_values).all(): + results.metrics[group][metric] = round(np.nanmean(metric_values) * 100, 1) + else: + results.metrics[group][metric] = np.nan + + def save_results(self, results, save_path): + if save_path is not None: + with open(save_path, "w") as f: + f.write(results.to_json(indent=2)) + + +default_embedding_model_name = "BAAI/bge-small-zh-v1.5" + + +class RagasMetricsParser(MetricsParser): + + def __init__(self, llm_name, embedding_model_name=default_embedding_model_name): + super().__init__() + + self.llm_name = llm_name + self.embedding_model_name = embedding_model_name + self.llm = None + self.embedding = None + self.run_config = None + + self.load_model() + + def load_model(self): + from langchain_community.embeddings import HuggingFaceEmbeddings + from langchain_huggingface.llms import HuggingFacePipeline + from ragas import RunConfig + from ragas.embeddings.base import LangchainEmbeddingsWrapper + + pipe = load_hf_pipeline(self.llm_name) + self.llm = HuggingFacePipeline(pipeline=pipe) + self.embedding = LangchainEmbeddingsWrapper( + HuggingFaceEmbeddings( + model_name=self.embedding_model_name, + model_kwargs={"device": "cuda" if torch.cuda.is_available() else "cpu"}, + encode_kwargs={"normalize_embeddings": True}, # Normalize for cosine similarity + ) + ) + self.run_config = RunConfig(timeout=12000) + + def create_metrics(self, eval_metrics: List[str]): + from .utils_ragas import RAGAS_METRIC_FUNC_MAP + + if isinstance(eval_metrics, str): + eval_metrics = [eval_metrics] + + ret_metrics = set() + for metric in eval_metrics: + if metric not in RAGAS_METRIC_FUNC_MAP: + if metric not in METRIC_GROUP_MAP: + warnings.warn(f"Invalid metric: {metric}.") + else: + ret_metrics.update(METRIC_GROUP_MAP[metric]) + else: + ret_metrics.add(metric) + + metrics_func = [] + for metric in ret_metrics: + if metric in RAGAS_METRIC_FUNC_MAP: + metrics_func.append(RAGAS_METRIC_FUNC_MAP[metric]) + + self.metrics_func = metrics_func + self.metrics = ret_metrics + + def results2datasets(self, results: RAGResults): + data_collections = { + "question": [result.query for result in results.results], + "answer": [result.response for result in results.results], + "ground_truth": [result.gt_answer if result.gt_answer else "" for result in results.results], + "contexts": [ + [doc.text for doc in result.retrieved_contexts] if result.retrieved_contexts else [""] + for result in results.results + ], + } + + return Dataset.from_dict(data_collections) + + def evaluate(self, results: RAGResults, save_path=None): + from ragas import evaluate + + from .utils_ragas import RAGAS_METRIC_FUNC_MAP + + dataset = self.results2datasets(results) + scores = evaluate( + dataset=dataset, + metrics=self.metrics_func, + llm=self.llm, + embeddings=self.embedding, + raise_exceptions=False, + run_config=self.run_config, + ) + df = scores.to_pandas() + for metric in self.metrics: + if metric in RAGAS_METRIC_FUNC_MAP: + for result, metric_value in zip(results.results, df[metric]): + if not (np.isnan(metric_value) and metric in result.metrics): + result.metrics[metric] = metric_value + print(f"result {result.query_id} metrics[{metric}]={metric_value}") + + self.aggregate_results_metrics(results) + self.save_results(results, save_path) + + return results.metrics + + +class DeepevalMetricsParser(MetricsParser): + + def __init__(self, llm_name): + super().__init__() + + self.llm_name = llm_name + self.llm = None + + self.load_model() + + def load_model(self): + from .utils_deepeval import DeepEvalCustomEvalLLM + + self.llm = DeepEvalCustomEvalLLM(self.llm_name) + + def create_metrics(self, eval_metrics: List[str]): + from .utils_deepeval import DEEPEVAL_METRIC_FUNC_MAP + + if isinstance(eval_metrics, str): + eval_metrics = [eval_metrics] + + llm = self.llm + ret_metrics = set() + for metric in eval_metrics: + if metric not in DEEPEVAL_METRIC_FUNC_MAP: + if metric not in METRIC_GROUP_MAP: + warnings.warn(f"Invalid metric: {metric}.") + else: + ret_metrics.update(METRIC_GROUP_MAP[metric]) + else: + ret_metrics.add(metric) + + metrics_func = {} + for metric in ret_metrics: + if metric in DEEPEVAL_METRIC_FUNC_MAP: + # metric_instance = DEEPEVAL_METRIC_FUNC_MAP[metric](model=llm) + metric_instance = DEEPEVAL_METRIC_FUNC_MAP[metric](model=llm, include_reason=False) # TODO Test + metrics_func[metric] = metric_instance + + self.metrics_func = metrics_func + self.metrics = ret_metrics + + def result2dataset(self, result: RAGResult): + from deepeval.test_case import LLMTestCase + + test_case = LLMTestCase( + input=result.query, + actual_output=result.response, + expected_output=result.gt_answer if result.gt_answer else "", + retrieval_context=[doc.text for doc in result.retrieved_contexts] if result.retrieved_contexts else [""], + # context=["The chicken wanted to cross the road."] list of strings, GT for context + ) + + return test_case + + def evaluate(self, results: RAGResults, save_path=None): + for result in results.results: + test_case = self.result2dataset(result) + print(f"Evaluating test case {result.query_id}") + for metric, metric_func in self.metrics_func.items(): + if metric not in result.metrics: + clean_memory() + + def evaluate_metric(): + metric_func.measure(test_case) + result.metrics[metric] = metric_func.score + print(f"result {result.query_id} metrics[{metric}]={metric_func.score}") + self.save_results(results, save_path) + + evaluation_thread = threading.Thread(target=evaluate_metric) + evaluation_thread.start() + evaluation_thread.join() + + self.aggregate_results_metrics(results) + self.save_results(results, save_path) + + return results.metrics diff --git a/evals/evaluation/rag_pilot/components/llm_eval/utils_deepeval.py b/evals/evaluation/rag_pilot/components/llm_eval/utils_deepeval.py new file mode 100644 index 00000000..bed69212 --- /dev/null +++ b/evals/evaluation/rag_pilot/components/llm_eval/utils_deepeval.py @@ -0,0 +1,80 @@ +# Copyright (C) 2025 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +import json + +import transformers +from deepeval.metrics import ( + AnswerRelevancyMetric, + ContextualPrecisionMetric, + ContextualRecallMetric, + ContextualRelevancyMetric, + FaithfulnessMetric, +) +from deepeval.models import DeepEvalBaseLLM +from lmformatenforcer import JsonSchemaParser +from lmformatenforcer.integrations.transformers import ( + build_transformers_prefix_allowed_tokens_fn, +) +from pydantic import BaseModel + +from .metrics import * +from .utils_eval import load_huggingface_llm + +DEEPEVAL_METRIC_FUNC_MAP = { + context_recall: ContextualRecallMetric, + context_precision: ContextualPrecisionMetric, + context_relevancy: ContextualRelevancyMetric, + answer_relevancy: AnswerRelevancyMetric, + faithfulness: FaithfulnessMetric, +} + + +class DeepEvalCustomEvalLLM(DeepEvalBaseLLM): + def __init__(self, model_name): + self.model_name = model_name + self.model, self.tokenizer = load_huggingface_llm(model_name) + + def load_model(self): + return self.model + + def generate(self, prompt: str, schema: BaseModel) -> BaseModel: + model = self.load_model() + pipeline = transformers.pipeline( + "text-generation", + model=model, + tokenizer=self.tokenizer, + use_cache=True, + device_map="auto", + max_new_tokens=1024, + do_sample=True, + top_k=5, + num_return_sequences=1, + eos_token_id=self.tokenizer.eos_token_id, + pad_token_id=self.tokenizer.eos_token_id, + ) + + # Create parser required for JSON confinement using lmformatenforcer + parser = JsonSchemaParser(schema.schema()) + prefix_function = build_transformers_prefix_allowed_tokens_fn(pipeline.tokenizer, parser) + + # Output and load valid JSON + output_dict = pipeline(prompt, prefix_allowed_tokens_fn=prefix_function) + output = output_dict[0]["generated_text"][len(prompt) :] + try: + json_result = json.loads(output) + except json.JSONDecodeError as e: + print("JSONDecodeError:", e) + with open("debug_output.json", "w") as f: + f.write(output) + raise e + + # Return valid JSON object according to the schema DeepEval supplied + return schema(**json_result) + + # TODO an asynchronous version of generate + async def a_generate(self, prompt: str, schema: BaseModel) -> BaseModel: + return self.generate(prompt, schema) + + def get_model_name(self): + return self.model_name diff --git a/evals/evaluation/rag_pilot/components/llm_eval/utils_eval.py b/evals/evaluation/rag_pilot/components/llm_eval/utils_eval.py new file mode 100644 index 00000000..ffdf2c6a --- /dev/null +++ b/evals/evaluation/rag_pilot/components/llm_eval/utils_eval.py @@ -0,0 +1,56 @@ +# Copyright (C) 2025 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +import ctypes +import gc + +import torch +import transformers +from transformers import AutoModelForCausalLM, AutoTokenizer + +DEFAULT_SAMPLING_TEMPERATURE = 0.001 +DEFAULT_REPETITION_PENTALTY = 1.0 +DEFAULT_MAX_NEW_TOKENS = 256 +DEFAULT_LLM_DEVICE = "cuda" if torch.cuda.is_available() else "cpu" +DEFAULT_BM25_WEIGHT = 0.333333 + + +def _load_huggingface_llm(name): + tokenizer = AutoTokenizer.from_pretrained(name, trust_remote_code=True) + model = AutoModelForCausalLM.from_pretrained( + name, + # load_in_8bit=True, + device_map="auto", + trust_remote_code=True, + ) + model.eval() + # model.to(DEFAULT_LLM_DEVICE) + + tokenizer.pad_token = tokenizer.eos_token + model.config.pad_token_id = model.config.eos_token_id + return model, tokenizer + + +def load_huggingface_llm(name): + model, tokenizer = _load_huggingface_llm(name) + return model, tokenizer + + +def load_hf_pipeline(name, temperature=DEFAULT_SAMPLING_TEMPERATURE, max_new_tokens=DEFAULT_MAX_NEW_TOKENS): + hf_model, hf_tokenizer = _load_huggingface_llm(name) + hf_pipeline = transformers.pipeline( + task="text-generation", + model=hf_model, + tokenizer=hf_tokenizer, + do_sample=True, # does not work ... True if temperature > 0 else False, + temperature=temperature, + repetition_penalty=DEFAULT_REPETITION_PENTALTY, + return_full_text=False, + max_new_tokens=max_new_tokens, + ) + return hf_pipeline + + +def clean_memory(): + gc.collect() + ctypes.CDLL("libc.so.6").malloc_trim(0) diff --git a/evals/evaluation/rag_pilot/components/llm_eval/utils_ragas.py b/evals/evaluation/rag_pilot/components/llm_eval/utils_ragas.py new file mode 100644 index 00000000..4a342318 --- /dev/null +++ b/evals/evaluation/rag_pilot/components/llm_eval/utils_ragas.py @@ -0,0 +1,16 @@ +# Copyright (C) 2025 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +from ragas import metrics + +from .metrics import * + +RAGAS_METRIC_FUNC_MAP = { + context_recall: metrics.context_recall, + context_precision: metrics.context_precision, + context_entity_recall: metrics.context_entity_recall, + answer_correctness: metrics.answer_correctness, + answer_relevancy: metrics.answer_relevancy, + answer_similarity: metrics.answer_similarity, + faithfulness: metrics.faithfulness, +} diff --git a/evals/evaluation/rag_pilot/components/pilot/base.py b/evals/evaluation/rag_pilot/components/pilot/base.py index 4c882ac0..4fe58d63 100644 --- a/evals/evaluation/rag_pilot/components/pilot/base.py +++ b/evals/evaluation/rag_pilot/components/pilot/base.py @@ -6,10 +6,11 @@ import hashlib import json import re +import uuid from difflib import SequenceMatcher from enum import Enum from pathlib import Path -from typing import Callable, Dict, List, Optional, Tuple, Union +from typing import Dict, List, Optional, Union import numpy as np from components.pilot.ecrag.api_schema import ( @@ -21,7 +22,13 @@ PostProcessorIn, RetrieverIn, ) -from pydantic import BaseModel +from pydantic import BaseModel, Field, model_serializer + + +class Metrics(str, Enum): + RETRIEVAL_RECALL = "retrieval_recall_rate" + POSTPROCESSING_RECALL = "postprocessing_recall_rate" + ANSWER_RELEVANCY = "answer_relevancy" def convert_dict_to_pipeline(pl: dict) -> PipelineCreateIn: @@ -74,25 +81,26 @@ def initialize_component(cls, data, extra=None, key_map=None, nested_fields=None ) -def generate_json_id(config, length=8): +def generate_json_id(config, length=8) -> int: if "active" in config: del config["active"] if "name" in config: del config["name"] config_str = json.dumps(config, sort_keys=True) unique_id = hashlib.sha256(config_str.encode()).hexdigest() - return unique_id[:length] + return int(unique_id[:length], 16) -class RAGPipeline: +class RAGPipeline(BaseModel): pl: PipelineCreateIn - id: int - _backup: Dict + id: int = Field(default=0) + _backup: Dict = {} def __init__(self, pl): - self.pl = pl + super().__init__(pl=pl) self._replace_model_with_id() - self.id = generate_json_id(self.pl.dict()) + # self.id = generate_json_id(self.pl.dict()) + self.id = uuid.uuid4() def _replace_model_with_id(self): self._backup = {} @@ -153,17 +161,44 @@ def restore_model(model_id, model_type, is_generator=False): self._backup = None + def get_prompt(self) -> Optional[str]: + generator = self.pl.generator + if not generator: + return None + if generator.prompt_content: + return generator.prompt_content + # if generator.prompt_path: + # try: + # with open(generator.prompt_path, 'r', encoding='utf-8') as f: + # return f.read() + # except FileNotFoundError: + # raise FileNotFoundError(f"Prompt file not found at path: {generator.prompt_path}") + # except Exception as e: + # raise RuntimeError(f"Error reading prompt from {generator.prompt_path}: {e}") + return None + def export_pipeline(self): self._restore_model_instances() exported_pl = copy.deepcopy(self.pl) + if hasattr(exported_pl, "generator") and exported_pl.generator: + if hasattr(exported_pl.generator, "prompt_content"): + delattr(exported_pl.generator, "prompt_content") self._replace_model_with_id() return exported_pl + @model_serializer(mode="plain") + def ser_model(self): + return {"id": self.id, **self.pl.model_dump()} + def copy(self): return copy.deepcopy(self) + def get_id(self): + return self.id + def regenerate_id(self): - self.id = generate_json_id(self.pl.dict()) + # self.id = generate_json_id(self.pl.dict()) + self.id = uuid.uuid4() def activate_pl(self): self.pl.active = True @@ -185,12 +220,6 @@ class ContextType(str, Enum): POSTPROCESSING = "postprocessing" -class RAGStage(str, Enum): - RETRIEVAL = "retrieval" - POSTPROCESSING = "postprocessing" - GENERATION = "generation" - - class ContextItem(BaseModel): context_idx: Optional[int] = None file_name: Optional[str] = None @@ -242,6 +271,8 @@ class RAGResult(BaseModel): retrieval_contexts: Optional[List[ContextItem]] = None postprocessing_contexts: Optional[List[ContextItem]] = None + finished: bool = False + def __init__(self, **data): super().__init__(**data) @@ -252,6 +283,15 @@ def __post_init__(self): def copy(self): return copy.deepcopy(self) + def update_metrics(self, metrics: Dict[str, Union[float, int]]): + if not metrics: + return + if self.metadata is None: + self.metadata = {} + for key, value in metrics.items(): + if isinstance(value, (float, int)): + self.metadata[key] = value + def init_context_idx(self, context_type): context_list_name = f"{context_type.value}_contexts" context_list = getattr(self, context_list_name, None) @@ -327,12 +367,13 @@ def cal_metric(cls, query: str, ground_truth: str, response: str) -> Dict[str, f class RAGResults(BaseModel): - metadata: Optional[Dict[str, Union[float, int, list]]] = None + metadata: Optional[Dict[str, Union[float, int]]] = None results: List[RAGResult] = [] + finished: bool = False def add_result(self, result): self.results.append(result) - self.cal_recall() + self.cal_metadata() def cal_recall(self): recall_rates = {} @@ -344,20 +385,62 @@ def cal_recall(self): hit_count += result.metadata.get(context_type, 0) if result.metadata else 0 recall_rate = hit_count / gt_count if gt_count > 0 else np.nan - recall_rates[context_type] = recall_rate + if context_type is ContextType.RETRIEVAL: + recall_rates[Metrics.RETRIEVAL_RECALL.value] = recall_rate + elif context_type is ContextType.POSTPROCESSING: + recall_rates[Metrics.POSTPROCESSING_RECALL.value] = recall_rate + self.metadata = self.metadata or {} + self.metadata.update(recall_rates) + + def cal_metadata(self): + self.cal_recall() + + rate_sums = {} + rate_counts = {} + + for result in self.results: + if not result.metadata: + continue + for key, value in result.metadata.items(): + if isinstance(value, (int, float)) and key in {metric.value for metric in Metrics}: + if key not in rate_sums: + rate_sums[key] = 0.0 + rate_counts[key] = 0 + rate_sums[key] += value + rate_counts[key] += 1 self.metadata = self.metadata or {} - self.metadata["recall_rate"] = recall_rates + for key, total in rate_sums.items(): + avg = total / rate_counts[key] if rate_counts[key] > 0 else np.nan + self.metadata[f"{key}"] = avg + + def get_metrics(self): + return self.metadata or {} + + def get_metric(self, metric: Metrics, default=float("-inf")): + return self.metadata.get(metric.value, default) + + def update_result_metrics(self, query_id: int, metrics: Dict[str, Union[float, int]]): + updated = False + for result in self.results: + if result.query_id == query_id: + result.update_metrics(metrics) + updated = True + break + + if updated: + self.cal_metadata() + return updated def check_metadata(self): - recall_rates = self.metadata.get("recall_rate", {}) - for key, rate in recall_rates.items(): - print(f"{key}: {rate}") + if not self.metadata: + print("No metadata found.") + return + for key, value in self.metadata.items(): + print(f"{key}: {value}") def save_to_json(self, file_path: str): - cleaned_metadata = None - if self.metadata: - cleaned_metadata = {str(k): v for k, v in self.metadata.items()} + cleaned_metadata = {str(k): v for k, v in (self.metadata or {}).items()} rag_results_dict = { **self.dict(exclude={"metadata"}), "metadata": cleaned_metadata, @@ -365,7 +448,6 @@ def save_to_json(self, file_path: str): with open(file_path, "w", encoding="utf-8") as f: json.dump(rag_results_dict, f, ensure_ascii=False, indent=4) - # print(f"RAGResults saved to {file_path}") def save_to_csv(self, output_dir: str): output_dir = Path(output_dir) @@ -378,24 +460,21 @@ def save_to_csv(self, output_dir: str): metadata_keys = set() for result in self.results: for context_type in ContextType: - context_type_str = f"{context_type.value}_contexts" - context_list: List[ContextItem] = getattr(result, context_type_str) or [] + context_list = getattr(result, f"{context_type.value}_contexts") or [] for ctx in context_list: if ctx.metadata: metadata_keys.update(ctx.metadata.keys()) fieldnames.extend(metadata_keys) - writer = csv.DictWriter(f, fieldnames=fieldnames) writer.writeheader() for result in self.results: for context_type in ContextType: - context_type_str = f"{context_type.value}_contexts" - context_list: List[ContextItem] = getattr(result, context_type_str) or [] + context_list = getattr(result, f"{context_type.value}_contexts") or [] for ctx in context_list: row = { "query_id": result.query_id, - "context_type": context_type_str, + "context_type": f"{context_type.value}_contexts", "context_idx": ctx.context_idx, "file_name": ctx.file_name, "text": ctx.text, diff --git a/evals/evaluation/rag_pilot/components/pilot/ecrag/api_schema.py b/evals/evaluation/rag_pilot/components/pilot/ecrag/api_schema.py index 48c08548..66b12a43 100644 --- a/evals/evaluation/rag_pilot/components/pilot/ecrag/api_schema.py +++ b/evals/evaluation/rag_pilot/components/pilot/ecrag/api_schema.py @@ -40,6 +40,7 @@ class PostProcessorIn(BaseModel): class GeneratorIn(BaseModel): prompt_path: Optional[str] = None + prompt_content: Optional[str] = None model: Optional[ModelIn] = None inference_type: Optional[str] = "local" @@ -67,3 +68,13 @@ class RagOut(BaseModel): query: str contexts: Optional[dict[str, Any]] = None response: str + + +class PromptIn(BaseModel): + prompt: Optional[str] = None + + +class KnowledgeBaseCreateIn(BaseModel): + name: str + description: Optional[str] = None + active: Optional[bool] = None diff --git a/evals/evaluation/rag_pilot/components/pilot/ecrag/base.py b/evals/evaluation/rag_pilot/components/pilot/ecrag/base.py index a163c486..9eabf857 100644 --- a/evals/evaluation/rag_pilot/components/pilot/ecrag/base.py +++ b/evals/evaluation/rag_pilot/components/pilot/ecrag/base.py @@ -40,22 +40,20 @@ class FileType(str, Enum): class NodeParserType(str, Enum): - DEFAULT = "default" SIMPLE = "simple" HIERARCHY = "hierarchical" SENTENCEWINDOW = "sentencewindow" + UNSTRUCTURED = "unstructured" class IndexerType(str, Enum): - DEFAULT = "default" FAISS_VECTOR = "faiss_vector" DEFAULT_VECTOR = "vector" class RetrieverType(str, Enum): - DEFAULT = "default" VECTORSIMILARITY = "vectorsimilarity" AUTOMERGE = "auto_merge" BM25 = "bm25" diff --git a/evals/evaluation/rag_pilot/components/pilot/pilot.py b/evals/evaluation/rag_pilot/components/pilot/pilot.py index 25c1e209..2a954f33 100644 --- a/evals/evaluation/rag_pilot/components/pilot/pilot.py +++ b/evals/evaluation/rag_pilot/components/pilot/pilot.py @@ -3,39 +3,63 @@ import csv import os +import threading from datetime import datetime -from components.pilot.base import ContextItem, ContextType, RAGPipeline, RAGResults, RAGStage -from components.pilot.connector import get_ragqna, update_active_pipeline +from api_schema import RAGStage +from components.connect_utils import get_active_pipeline, get_ragqna, get_retrieval, load_prompt, update_active_pipeline +from components.pilot.base import ContextItem, ContextType, Metrics, RAGPipeline, RAGResults -def get_rag_results_with_rag_pipeline(rag_pipeline: RAGPipeline, rag_results_sample: RAGResults, hit_threshold): - # Update rag_pipeline +def update_rag_pipeline(rag_pipeline: RAGPipeline): ecrag_pipeline = rag_pipeline.export_pipeline() - update_active_pipeline(ecrag_pipeline) + ret = update_active_pipeline(ecrag_pipeline) + prompt = rag_pipeline.get_prompt() + if prompt: + load_prompt(prompt) + # TODO load_prompt() error check + return ret - # Create a new instance of RAGResults - new_rag_results = RAGResults() + +def get_rag_results(results_out: RAGResults, results_in: RAGResults, hit_threshold, is_retrieval=False): + if results_in is None: + return None # Update each rag_result in rag_results and add to new instance - for result in rag_results_sample.results: + for result in results_in.results: query = result.query - ragqna = get_ragqna(query) + ragqna = None + if is_retrieval: + ragqna = get_retrieval(query) + else: + ragqna = get_ragqna(query) + if ragqna is None: + continue # Create a new result object to avoid modifying the input new_result = result.copy() for key, nodes in ragqna.contexts.items(): for node in nodes: - context_item = ContextItem(file_name=node["node"]["metadata"]["file_name"], text=node["node"]["text"]) + node_node = node.get("node", {}) + metadata = node_node.get("metadata", {}) + possible_file_keys = ["file_name", "filename"] + file_name = next( + (metadata[key] for key in possible_file_keys if key in metadata), + None, + ) + text = node_node.get("text", "") + context_item = ContextItem(file_name=file_name, text=text) if key == "retriever": new_result.add_context(ContextType.RETRIEVAL, context_item) else: new_result.add_context(ContextType.POSTPROCESSING, context_item) + new_result.update_metadata_hits(hit_threshold) new_result.set_response(ragqna.response) - new_rag_results.add_result(new_result) + new_result.finished = True + results_out.add_result(new_result) - return new_rag_results + results_out.finished = True class Pilot: @@ -43,34 +67,135 @@ class Pilot: rag_results_dict: dict[int, RAGResults] = {} curr_pl_id: int = None - rag_results_sample: RAGResults + rag_results_sample: RAGResults = None hit_threshold: float base_folder: str + _run_lock = threading.Lock() + _run_done_event = threading.Event() - def __init__(self, rag_results_sample, hit_threshold=1): + def __init__(self, rag_results_sample=None, hit_threshold=1): self.rag_results_sample = rag_results_sample self.hit_threshold = hit_threshold timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") self.base_folder = os.path.join(os.getcwd(), f"rag_pilot_{timestamp}") + def update_rag_results_sample(self, rag_results_sample): + self.rag_results_sample = rag_results_sample + return True + def add_rag_pipeline(self, rag_pipeline): - id = rag_pipeline.id + id = rag_pipeline.get_id() self.rag_pipeline_dict[id] = rag_pipeline if not self.curr_pl_id: self.curr_pl_id = id - def add_rag_results(self, pl_id, rag_results): - self.rag_results_dict[pl_id] = rag_results - - def run_curr_pl(self): - curr_rag_pl = self.rag_pipeline_dict[self.curr_pl_id] - rag_results = get_rag_results_with_rag_pipeline(curr_rag_pl, self.rag_results_sample, self.hit_threshold) - self.add_rag_results(self.curr_pl_id, rag_results) + def set_curr_pl_by_id(self, pl_id): + if pl_id in self.rag_pipeline_dict: + curr_rag_pl = self.rag_pipeline_dict[pl_id] + if update_rag_pipeline(curr_rag_pl) is not None: + self.curr_pl_id = pl_id + return True + else: + return False + else: + return False + + def set_curr_pl(self, rag_pipeline): + id = rag_pipeline.get_id() + if id not in self.rag_pipeline_dict: + self.rag_pipeline_dict[id] = rag_pipeline + return self.set_curr_pl_by_id(id) + + def add_rag_results(self, pl_id): + if pl_id not in self.rag_results_dict: + # Create a new instance of RAGResults + self.rag_results_dict[pl_id] = RAGResults() + + return self.rag_results_dict[pl_id] + + def clear_rag_result_dict(self): + self.rag_results_dict = {} + + def _execute_pipeline(self, pipeline, is_retrieval=False): + if not self.rag_results_sample: + print("[ERROR] RAG result sample file is not initiated") + return False + + print("[Pilot] Trying to acquire run lock (non-blocking)...") + if not self._run_lock.acquire(blocking=False): + print("[Pilot] Pipeline is already running. Skipping execution.") + return False + + self._run_done_event.clear() + try: + print("[Pilot] Acquired run lock.") + if self.set_curr_pl(pipeline): + + rag_results = self.add_rag_results(self.curr_pl_id) + + get_rag_results(rag_results, self.rag_results_sample, self.hit_threshold, is_retrieval) + + return True + return False + finally: + print("[Pilot] Releasing run lock and setting done event.") + self._run_lock.release() + self._run_done_event.set() + + def run_pipeline(self, rag_pipeline=None, is_retrieval=False): + pipeline = rag_pipeline or self.get_curr_pl() + thread = threading.Thread( + target=self._execute_pipeline, + args=(pipeline, is_retrieval), + daemon=True, # ensures thread exits when the process exits + name=f"{pipeline.id}"[:15], + ) + thread.start() + if thread.ident is None: + return False + return "Pipeline {thread.ident} is running" + + def run_pipeline_blocked(self, rag_pipeline=None, is_retrieval=False): + if not self.rag_results_sample: + print("[Pilot] Skipping pipeline run โ€” rag_results_sample not set.") + return False + + thread_id = threading.get_ident() + thread_name = threading.current_thread().name + pipeline = rag_pipeline or self.get_curr_pl() + + print(f"[Pilot][{thread_name}:{thread_id}] Waiting for current pipeline run to complete (if any)...") + while not self._execute_pipeline(pipeline, is_retrieval): + self._run_done_event.wait(timeout=0.5) + print(f"[Pilot][{thread_name}:{thread_id}] Pipeline run completed.") + return True def get_curr_pl(self): - return self.rag_pipeline_dict[self.curr_pl_id] + if self.curr_pl_id: + return self.rag_pipeline_dict[self.curr_pl_id] + else: + pl_raw = get_active_pipeline() + if pl_raw: + active_pl = RAGPipeline(pl_raw) + active_pl.regenerate_id() + pilot.add_rag_pipeline(active_pl) + return self.rag_pipeline_dict[self.curr_pl_id] + else: + return None + + def get_curr_pl_id(self): + if self.curr_pl_id: + return self.curr_pl_id + else: + if self.get_curr_pl(): + return self.curr_pl_id + else: + return None + + def get_pl(self, id): + return self.rag_pipeline_dict[id] if id in self.rag_pipeline_dict else None def get_results(self, id): return self.rag_results_dict[id] if id in self.rag_results_dict else None @@ -78,26 +203,52 @@ def get_results(self, id): def get_curr_results(self): return self.get_results(self.curr_pl_id) + def get_results_metrics(self, id): + return self.rag_results_dict[id].get_metrics() if id in self.rag_results_dict else None + + def update_result_metrics(self, id, query_id, metrics): + if id in self.rag_results_dict: + return self.rag_results_dict[id].update_result_metrics(query_id, metrics) + else: + return False + def change_best_recall_pl(self, stage: RAGStage = None): + if stage is RAGStage.GENERATION: + print(f"Stage {stage}: Skip change_best_recall_pl()") + return None + best_pl_id = None best_avg_recall = float("-inf") + best_total_score = float("-inf") # tie-breaker metric for pl_id, rag_results in self.rag_results_dict.items(): if not rag_results or not rag_results.metadata: continue - recall_rate_dict = rag_results.metadata.get("recall_rate", {}) - if stage in [RAGStage.RETRIEVAL, RAGStage.POSTPROCESSING]: - recall_rate = recall_rate_dict.get(stage, float("-inf")) + if stage is RAGStage.RETRIEVAL: + recall_rate = rag_results.get_metric(Metrics.RETRIEVAL_RECALL) + elif stage is RAGStage.POSTPROCESSING: + recall_rate = rag_results.get_metric(Metrics.POSTPROCESSING_RECALL) else: recall_rate = float("-inf") - if recall_rate > best_avg_recall: + total_score = sum( + v + for k, v in rag_results.get_metrics().items() + if k in {metric.value for metric in Metrics} and isinstance(v, (int, float)) + ) + + if recall_rate > best_avg_recall or (recall_rate == best_avg_recall and total_score > best_total_score): best_avg_recall = recall_rate + best_total_score = total_score best_pl_id = pl_id if best_pl_id is not None: - self.curr_pl_id = best_pl_id + self.set_curr_pl_by_id(best_pl_id) + + print(f"Stage {stage}: Pipeline is set to {self.get_curr_pl_id()}") + self.get_curr_results().check_metadata() + return self.get_curr_pl() def save_dicts(self): parent_folder = self.base_folder @@ -124,6 +275,7 @@ def save_dicts(self): self.export_config_and_metadata_csv(save_path=f"{parent_folder}/summary.csv") print(f"Saved RAG pipeline and results to {parent_folder}") + return parent_folder def export_config_and_metadata_csv(self, save_path: str): rows = [] @@ -132,31 +284,27 @@ def export_config_and_metadata_csv(self, save_path: str): for pl_id, pipeline in self.rag_pipeline_dict.items(): config = pipeline.pl.dict() rag_results = self.rag_results_dict.get(pl_id) - recall_rates = {} + rates = {} if rag_results: - recall_rate = rag_results.metadata.get("recall_rate", {}) - retrieval_recall_rate = recall_rate.get(ContextType.RETRIEVAL, None) - postprocessing_recall_rate = recall_rate.get(ContextType.POSTPROCESSING, None) - - if retrieval_recall_rate is not None: - recall_rates["retrieval_recall_rate"] = retrieval_recall_rate - if postprocessing_recall_rate is not None: - recall_rates["postprocessing_recall_rate"] = postprocessing_recall_rate + for metric in Metrics: + rate = rag_results.get_metric(metric, None) + if rate: + rates[metric.value] = rate for key in config.keys(): key = f"config_{key}" if key not in fieldnames: fieldnames.append(key) - for recall_key in recall_rates.keys(): + for recall_key in rates.keys(): if recall_key not in fieldnames: fieldnames.append(recall_key) row = { "pipeline_id": pl_id, **{f"config_{key}": value for key, value in config.items()}, - **recall_rates, # Add recall rates to the row + **rates, } rows.append(row) @@ -167,3 +315,14 @@ def export_config_and_metadata_csv(self, save_path: str): writer.writeheader() for row in rows: writer.writerow(row) + + +pilot = Pilot() + + +def init_active_pipeline(): + pl_raw = get_active_pipeline() + if pl_raw: + active_pl = RAGPipeline(pl_raw) + active_pl.regenerate_id() + pilot.add_rag_pipeline(active_pl) diff --git a/evals/evaluation/rag_pilot/components/tuner/adaptor.py b/evals/evaluation/rag_pilot/components/tuner/adaptor.py index 61985020..9e2fc323 100644 --- a/evals/evaluation/rag_pilot/components/tuner/adaptor.py +++ b/evals/evaluation/rag_pilot/components/tuner/adaptor.py @@ -3,11 +3,11 @@ import ast from copy import deepcopy -from dataclasses import dataclass, field -from typing import Any, Callable, Dict, Optional, Tuple +from dataclasses import dataclass +from typing import Any, Callable, Dict, Optional +from components.connect_utils import COMP_TYPE_MAP, get_ecrag_module_map from components.pilot.base import RAGPipeline -from components.pilot.connector import COMP_TYPE_MAP, get_ecrag_module_map def get_support_modules(module_name: str, module_map) -> Callable: @@ -225,9 +225,9 @@ def get_rag_pipelines_candidates(self, params_candidates): for params_candidate in params_candidates: rag_pl = self.rag_pipeline.copy() self.update_all_module_functions_tmp(rag_pl) - for attr, ((node_type, module_type), val) in params_candidate.items(): - module = self.get_module(node_type, module_type) - module.set_value(attr, val) + for attr, tunerUpdate in params_candidate.items(): + module = self.get_module(tunerUpdate.node_type, tunerUpdate.module_type) + module.set_value(attr, tunerUpdate.val) rag_pl.regenerate_id() rag_pls.append(rag_pl) self.update_all_module_functions(self.rag_pipeline) diff --git a/evals/evaluation/rag_pilot/components/tuner/base.py b/evals/evaluation/rag_pilot/components/tuner/base.py index a93cb828..b03e03ff 100644 --- a/evals/evaluation/rag_pilot/components/tuner/base.py +++ b/evals/evaluation/rag_pilot/components/tuner/base.py @@ -66,6 +66,7 @@ class Suggestion(UserInput): class Feedback(BaseModel): feedback: bool | int + auto: bool class DirectionType(Enum): @@ -80,3 +81,14 @@ class Target(BaseModel): orig_val: Optional[Union[int, float, str]] = None new_vals: List[Union[int, float, str]] = None suggestion: Suggestion = None + + def as_string(self) -> str: + module = f"{self.module_type}." if self.module_type else "" + return f"{self.node_type}.{module}{self.attribute}" + + +class TargetUpdate(BaseModel): + node_type: str + module_type: Optional[str] = None + attribute: str + val: Optional[Union[int, float, str]] = None diff --git a/evals/evaluation/rag_pilot/components/tuner/tuner.py b/evals/evaluation/rag_pilot/components/tuner/tuner.py index 2295ab04..daa5aafc 100644 --- a/evals/evaluation/rag_pilot/components/tuner/tuner.py +++ b/evals/evaluation/rag_pilot/components/tuner/tuner.py @@ -1,12 +1,15 @@ # Copyright (C) 2025 Intel Corporation # SPDX-License-Identifier: Apache-2.0 +import glob +import os from abc import ABC, abstractmethod from itertools import product from typing import Dict, Optional +from api_schema import RunningStatus from components.tuner.adaptor import Adaptor -from components.tuner.base import ContentType, Feedback, Question, Suggestion, SuggestionType, Target +from components.tuner.base import ContentType, Feedback, Question, Suggestion, SuggestionType, Target, TargetUpdate def input_parser(upper_limit: int = None): @@ -42,10 +45,11 @@ def display_list(list): class Tuner(ABC): def __init__(self, question: Question, adaptor: Adaptor, targets: Dict[str, Target]): + self.name = self.__class__.__name__ self.question = question - self.adaptor = adaptor self.targets = targets + self._status = RunningStatus.NOT_STARTED def check_active(self): for target in self.targets.values(): @@ -54,6 +58,15 @@ def check_active(self): return False return True + def get_status(self): + return self._status + + def set_status(self, status: RunningStatus): + self._status = status + + def set_status_completed(self): + self._status = RunningStatus.COMPLETED + def set_param( self, param_name, @@ -124,16 +137,22 @@ def set_param( target.suggestion = Suggestion(hint=hint, options=target.new_vals, suggestion_type=suggestion_type) - def request_feedback(self): + def request_feedback(self, auto=False): if not self.check_active(): + self.set_status(RunningStatus.INACTIVE) return False print(f"\033[1m\033[93m{self}\033[0m: {self.question}\n") - valid, user_input = input_parser(len(self.question.options)) - if not valid: - return False + if not auto: + valid, user_input = input_parser(len(self.question.options)) + if not valid: + return False + auto = False + else: + user_input = -1 + auto = True - self.user_feedback = Feedback(feedback=user_input) + self.user_feedback = Feedback(feedback=user_input, auto=auto) return self._feedback_to_suggestions() @abstractmethod @@ -142,10 +161,10 @@ def _feedback_to_suggestions(self): def apply_suggestions(self): if not self.check_active(): - return + self.set_status(RunningStatus.INACTIVE) + return None, None params_candidates = [] - new_values_dict = {} # STEPWISE_GROUPED @@ -160,14 +179,14 @@ def apply_suggestions(self): for idx in range(count): candidate = {a: t.new_vals[idx] for a, t in grouped_targets.items()} new_values_dict = { - a: [(t.node_type, t.module_type), t.new_vals[idx]] for a, t in grouped_targets.items() + a: TargetUpdate(node_type=t.node_type, module_type=t.module_type, attribute=a, val=t.new_vals[idx]) + for a, t in grouped_targets.items() } params_candidates.append(new_values_dict) if len(params_candidates) > 0: return self.adaptor.get_rag_pipelines_candidates(params_candidates) # GRID_SEARCH - grid_targets = { a: t for a, t in self.targets.items() @@ -179,7 +198,12 @@ def apply_suggestions(self): candidate = dict(zip(keys, combination)) new_values_dict = {} for a, val in candidate.items(): - new_values_dict[a] = [(self.targets[a].node_type, self.targets[a].module_type), val] + new_values_dict[a] = TargetUpdate( + node_type=self.targets[a].node_type, + module_type=self.targets[a].module_type, + attribute=a, + val=val, + ) params_candidates.append(new_values_dict) if len(params_candidates) > 0: return self.adaptor.get_rag_pipelines_candidates(params_candidates) @@ -195,11 +219,21 @@ def apply_suggestions(self): case SuggestionType.SET: print(f"{suggestion}") if suggestion.options: - new_values_dict[attr] = [(target.node_type, target.module_type), suggestion.options[0].content] + new_values_dict[attr] = TargetUpdate( + node_type=target.node_type, + module_type=target.module_type, + attribute=attr, + val=suggestion.options[0].content, + ) else: valid, user_input = input_parser() if valid: - new_values_dict[attr] = [(target.node_type, target.module_type), user_input] + new_values_dict[attr] = TargetUpdate( + node_type=target.node_type, + module_type=target.module_type, + attribute=attr, + val=user_input, + ) case SuggestionType.CHOOSE: print(f"{suggestion}") @@ -207,13 +241,23 @@ def apply_suggestions(self): valid, user_input = input_parser(len(new_options)) if valid: chosed_val = suggestion.options[user_input - 1] - new_values_dict[attr] = [(target.node_type, target.module_type), chosed_val.content] + new_values_dict[attr] = TargetUpdate( + node_type=target.node_type, + module_type=target.module_type, + attribute=attr, + val=chosed_val.content, + ) case SuggestionType.ITERATE: print(f"{suggestion}") for option in suggestion.options: new_values_dict = {} - new_values_dict[attr] = [(target.node_type, target.module_type), option.content] + new_values_dict[attr] = TargetUpdate( + node_type=target.node_type, + module_type=target.module_type, + attribute=attr, + val=option.content, + ) params_candidates.append(new_values_dict) if len(params_candidates) > 0: return self.adaptor.get_rag_pipelines_candidates(params_candidates) @@ -221,12 +265,16 @@ def apply_suggestions(self): case SuggestionType.STEPWISE: if len(target.new_vals) == 1: val = target.new_vals[idx] - new_values_dict[attr] = [(target.node_type, target.module_type), val] + new_values_dict[attr] = TargetUpdate( + node_type=target.node_type, module_type=target.module_type, attribute=attr, val=val + ) else: for idx in range(len(target.new_vals)): new_values_dict = {} val = target.new_vals[idx] - new_values_dict[attr] = [(target.node_type, target.module_type), val] + new_values_dict[attr] = TargetUpdate( + node_type=target.node_type, module_type=target.module_type, attribute=attr, val=val + ) params_candidates.append(new_values_dict) if len(params_candidates) > 0: return self.adaptor.get_rag_pipelines_candidates(params_candidates) @@ -237,6 +285,14 @@ def apply_suggestions(self): params_candidates.append(new_values_dict) return self.adaptor.get_rag_pipelines_candidates(params_candidates) + def run(self, pl): + self.adaptor.update_all_module_functions(pl) + if self.request_feedback(auto=True): + pl_list, params_candidates = self.apply_suggestions() + else: + pl_list, params_candidates = None, None + return pl_list, params_candidates + def __str__(self): return f"{self.__class__.__name__}" @@ -262,7 +318,7 @@ def __init__(self, adaptor: Adaptor): def _feedback_to_suggestions(self): assert isinstance(self.user_feedback, Feedback) - if self.user_feedback.feedback == 1: + if self.user_feedback.feedback == 1 or self.user_feedback.auto: self.set_param(param_name="embedding_model", suggestion_type=SuggestionType.ITERATE) return True else: @@ -291,7 +347,7 @@ def __init__(self, adaptor: Adaptor): def _feedback_to_suggestions(self): assert isinstance(self.user_feedback, Feedback) - if self.user_feedback.feedback == 1: + if self.user_feedback.feedback == 1 or self.user_feedback.auto: self.set_param(param_name="parser_type", suggestion_type=SuggestionType.ITERATE) return True else: @@ -333,7 +389,7 @@ def __init__(self, adaptor: Adaptor): def _feedback_to_suggestions(self): assert isinstance(self.user_feedback, Feedback) - if self.user_feedback.feedback == 1: + if self.user_feedback.feedback == 1 or self.user_feedback.auto: self.set_param(param_name="chunk_size", suggestion_type=SuggestionType.STEPWISE_GROUPED, step=100, count=3) self.set_param( param_name="chunk_overlap", suggestion_type=SuggestionType.STEPWISE_GROUPED, step=16, count=3 @@ -373,7 +429,7 @@ def __init__(self, adaptor: Adaptor): def _feedback_to_suggestions(self): assert isinstance(self.user_feedback, Feedback) - if self.user_feedback.feedback == 1: + if self.user_feedback.feedback == 1 or self.user_feedback.auto: self.set_param( param_name="retrieve_topk", suggestion_type=SuggestionType.STEPWISE, step=15, lower_limit=30, count=4 ) @@ -411,8 +467,8 @@ def __init__(self, adaptor: Adaptor): def _feedback_to_suggestions(self): assert isinstance(self.user_feedback, Feedback) - if self.user_feedback.feedback == 1: - self.set_param(param_name="top_n", suggestion_type=SuggestionType.STEPWISE, step=5, lower_limit=5, count=2) + if self.user_feedback.feedback == 1 or self.user_feedback.auto: + self.set_param(param_name="top_n", suggestion_type=SuggestionType.STEPWISE, step=2, lower_limit=3, count=2) return True else: return False @@ -452,7 +508,7 @@ def __init__(self, adaptor: Adaptor): def _feedback_to_suggestions(self): assert isinstance(self.user_feedback, Feedback) - if self.user_feedback.feedback == 1: + if self.user_feedback.feedback == 1 or self.user_feedback.auto: self.set_param( param_name="retrieve_topk", suggestion_type=SuggestionType.GRID_SEARCH, step=15, lower_limit=30, count=4 ) @@ -470,3 +526,70 @@ def _feedback_to_suggestions(self): return True else: return False + + +class PromptTuner(Tuner): + + def __init__(self, adaptor: Adaptor): + # question + question = Question( + hint="Do you want to tune the prompt template?", + options=[ + "Yes, iterate all prompts based on prompt candidates", + "Yes, choose from available prompt templates", + "No, skip this tuner", + ], + ) + targets = {} + # targets + attribute = "prompt_path" + target = Target( + node_type="generator", + attribute=attribute, + ) + targets[attribute] = target + + attribute = "prompt_content" + target = Target( + node_type="generator", + attribute=attribute, + ) + targets[attribute] = target + super().__init__(question, adaptor, targets) + + path_target = targets["prompt_path"] + content_target = targets["prompt_content"] + target_obj_path = self.adaptor.get_module(path_target.node_type, path_target.module_type) + target_obj_content = self.adaptor.get_module(content_target.node_type, content_target.module_type) + + prompt_contents = [] + if target_obj_path: + paths = target_obj_path.get_params(path_target.attribute) + all_files = [] + for cur_path in paths: + if os.path.isdir(cur_path): + txt_files = glob.glob(os.path.join(cur_path, "*.txt")) + all_files.extend(txt_files) + elif os.path.isfile(cur_path) and cur_path.endswith(".txt"): + all_files.append(cur_path) + if all_files: + for file_path in all_files: + try: + with open(file_path, "r", encoding="utf-8") as f: + content = f.read() + prompt_contents.append(content) + except Exception as e: + print(f"Warning: Could not read file {file_path}: {e}") + if target_obj_content and prompt_contents: + target_obj_content.params[content_target.attribute].extend(prompt_contents) + + def _feedback_to_suggestions(self): + assert isinstance(self.user_feedback, Feedback) + if self.user_feedback.feedback == 1 or self.user_feedback.auto: + self.set_param(param_name="prompt_content", suggestion_type=SuggestionType.ITERATE) + return True + elif self.user_feedback.feedback == 2: + self.set_param(param_name="prompt_content", suggestion_type=SuggestionType.CHOOSE) + return True + else: + return False diff --git a/evals/evaluation/rag_pilot/components/tuner/tunermgr.py b/evals/evaluation/rag_pilot/components/tuner/tunermgr.py new file mode 100644 index 00000000..f15421b3 --- /dev/null +++ b/evals/evaluation/rag_pilot/components/tuner/tunermgr.py @@ -0,0 +1,198 @@ +# Copyright (C) 2025 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +import uuid +from typing import Dict, List, Optional, Type + +from api_schema import RAGStage, RunningStatus, TunerOut, TunerUpdateOut +from components.tuner.adaptor import Adaptor +from components.tuner.base import TargetUpdate +from components.tuner.tuner import ( + EmbeddingTuner, + NodeParserTuner, + PromptTuner, + RerankerTopnTuner, + RetrievalTopkTuner, + SimpleNodeParserChunkTuner, + Tuner, +) +from components.utils import read_yaml +from pydantic import BaseModel + + +class TunerRecord(BaseModel): + base_pipeline_id: Optional[uuid.UUID] = None + best_pipeline_id: Optional[uuid.UUID] = None + all_pipeline_ids: List[uuid.UUID] = [] + targets: List[Dict[str, TargetUpdate]] = [] + + +class TunerMgr: + def __init__(self): + self._tuners_by_name: Dict[str, Tuner] = {} + self._tuners_by_stage: Dict[RAGStage, List[str]] = {} + self._records: Dict[str, TunerRecord] = {} + self.adaptor: Adaptor = None + + def init_adaptor(self, rag_module_yaml): + self.adaptor = Adaptor(rag_module_yaml) + + def update_adaptor(self, pl): + self.adaptor.update_all_module_functions(pl) + + def register_tuner(self, stage: RAGStage, tuner_cls: Type[Tuner]): + tuner = tuner_cls(self.adaptor) + name = tuner.name + self._tuners_by_name[name] = tuner + self._tuners_by_stage.setdefault(stage, []).append(name) + self._records[name] = TunerRecord() + + def get_tuner_stage(self, name: str) -> Optional[RAGStage]: + for stage, tuner_names in self._tuners_by_stage.items(): + if name in tuner_names: + return stage + return None + + def get_tuners_by_stage(self, stage: RAGStage) -> List[str]: + return self._tuners_by_stage.get(stage, []) + + def get_tuner_out(self, name: str, stage: RAGStage = None) -> TunerOut: + tuner = self._tuners_by_name[name] if name in self._tuners_by_name else None + if tuner: + targets_str = ", ".join([target.as_string() for target in tuner.targets.values()]) + if stage is None: + stage = self.get_tuner_stage(name) + tunerOut = TunerOut( + stage=stage.value if hasattr(stage, "value") else str(stage), + name=name, + targets=targets_str, + status=tuner.get_status().value, + ) + else: + tunerOut = None + return tunerOut + + def get_tuner_update_outs_by_name(self, name: str) -> TunerUpdateOut: + record = self.get_tuner_record(name) + if record is None: + return [] + tunerUpdateOuts = [] + for pl_id, params in zip(record.all_pipeline_ids, record.targets): + targets = {} + for attr, update in params.items(): + parts = [update.node_type] + if update.module_type: + parts.append(update.module_type) + parts.append(update.attribute) + target_key = ".".join(parts) # e.g., "postprocessor.reranker.top_n" + targets[target_key] = update.val + tunerUpdateOuts.append( + TunerUpdateOut( + tuner_name=name, + base_pipeline_id=record.base_pipeline_id, + pipeline_id=pl_id, + targets=targets, + ) + ) + return tunerUpdateOuts + + def get_stage_status(self, stage): + tuner_names = self.get_tuners_by_stage(stage) + statuses = [] + + for tuner_name in tuner_names: + tuner = self.get_tuner(tuner_name) + if tuner: + statuses.append(tuner.get_status()) + + if all(status in (RunningStatus.NOT_STARTED, RunningStatus.INACTIVE) for status in statuses): + return RunningStatus.NOT_STARTED + elif all(status in (RunningStatus.COMPLETED, RunningStatus.INACTIVE) for status in statuses): + return RunningStatus.COMPLETED + else: + return RunningStatus.IN_PROGRESS + + def get_tuner_status(self, tuner_name): + tuner = self.get_tuner(tuner_name) + if tuner: + return tuner.get_status() + else: + return None + + def set_tuner_status(self, tuner_name, status): + tuner = self.get_tuner(tuner_name) + if tuner: + tuner.set_status(status) + + def reset_tuners_by_stage(self, stage): + tuner_names = tunerMgr.get_tuners_by_stage(stage) + for tuner_name in tuner_names: + tunerMgr.set_tuner_status(tuner_name, RunningStatus.NOT_STARTED) + + def complete_tuner(self, tuner_name: str, best_pipeline_id: int = None): + tuner = self.get_tuner(tuner_name) + if tuner: + tuner.set_status_completed() + record = self.get_tuner_record(tuner_name) + record.best_pipeline_id = best_pipeline_id + + def get_all_tuner_outs_by_stage(self, stage: RAGStage) -> List[TunerOut]: + return [self.get_tuner_out(name, stage) for name in self.get_tuners_by_stage(stage)] + + def get_pipeline_best(self, name: str) -> Optional[uuid.UUID]: + return self._records[name].best_pipeline_id if name in self._records else None + + def get_pipeline_base(self, name: str) -> Optional[uuid.UUID]: + return self._records[name].base_pipeline_id if name in self._records else None + + def set_base_pipeline(self, name, pipeline_id): + if name in self._records: + self._records[name].base_pipeline_id = pipeline_id + + def set_best_pipeline(self, name, pipeline_id): + if name in self._records: + self._records[name].best_pipeline_id = pipeline_id + + def get_tuner(self, name): + return self._tuners_by_name[name] if name in self._records else None + + def get_tuner_record(self, name) -> Optional[TunerRecord]: + return self._records[name] if name in self._records else None + + def set_tuner_record(self, name, tunerRecord): + self._records[name] = tunerRecord + + def run_tuner(self, name: str, pl): + tuner = self.get_tuner(name) + pl_list, params_candidates = tuner.run(pl) + + if tuner.get_status() is not RunningStatus.INACTIVE: + tunerRecord = TunerRecord( + name=name, + base_pipeline_id=pl.get_id(), + best_pipeline_id=None, + all_pipeline_ids=[], + targets=[], + ) + self.set_tuner_record(name, tunerRecord) + + for pl, params in zip(pl_list, params_candidates): + tunerRecord.all_pipeline_ids.append(pl.get_id()) + tunerRecord.targets.append(params) + + return pl_list, params_candidates + + +tunerMgr = TunerMgr() + + +def init_tuners(adaptor_yaml="configs/ecrag.yaml"): + tunerMgr.init_adaptor(read_yaml(adaptor_yaml)) + tunerMgr.register_tuner(RAGStage.RETRIEVAL, EmbeddingTuner) + tunerMgr.register_tuner(RAGStage.RETRIEVAL, NodeParserTuner) + tunerMgr.register_tuner(RAGStage.RETRIEVAL, SimpleNodeParserChunkTuner) + tunerMgr.register_tuner(RAGStage.RETRIEVAL, RetrievalTopkTuner) + + tunerMgr.register_tuner(RAGStage.POSTPROCESSING, RerankerTopnTuner) + + tunerMgr.register_tuner(RAGStage.GENERATION, PromptTuner) diff --git a/evals/evaluation/rag_pilot/components/utils.py b/evals/evaluation/rag_pilot/components/utils.py new file mode 100644 index 00000000..06e06f51 --- /dev/null +++ b/evals/evaluation/rag_pilot/components/utils.py @@ -0,0 +1,92 @@ +# Copyright (C) 2025 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + + +from collections import defaultdict +from typing import List, TextIO, Union + +import pandas as pd +import yaml +from api_schema import GroundTruth +from components.pilot.base import ContextItem, ContextType, RAGResult, RAGResults + + +def load_rag_results_from_csv(file_obj: Union[str, TextIO]): + try: + rag_results_raw = pd.read_csv(file_obj) + except Exception as e: + raise ValueError(f"Failed to read CSV: {e}") + + required_columns = {"query_id", "query", "gt_context", "file_name"} + if not required_columns.issubset(rag_results_raw.columns): + raise ValueError( + f"Missing required columns. Required: {required_columns}, Found: {set(rag_results_raw.columns)}" + ) + + rag_results_dict = defaultdict(lambda: {"gt_contexts": []}) + + try: + for _, rag_result in rag_results_raw.iterrows(): + query_id = rag_result.get("query_id") + if pd.isna(query_id): + continue + + if "query" not in rag_results_dict[query_id]: + rag_results_dict[query_id].update( + { + "query": rag_result.get("query", ""), + "ground_truth": ( + rag_result.get("ground_truth", "") if "ground_truth" in rag_results_raw.columns else "" + ), + } + ) + + gt_context = rag_result.get("gt_context", "") + file_name = rag_result.get("file_name", "") + file_name = "" if pd.isna(file_name) else str(file_name) + + if gt_context: + rag_results_dict[query_id]["gt_contexts"].append(ContextItem(text=gt_context, file_name=file_name)) + + rag_results = RAGResults() + for query_id, data in rag_results_dict.items(): + result = RAGResult( + query_id=query_id, + query=data["query"], + gt_contexts=data["gt_contexts"] if data["gt_contexts"] else None, + ground_truth=data.get("ground_truth", ""), + ) + result.init_context_idx(ContextType.GT) + rag_results.add_result(result) + + return rag_results + + except Exception as e: + raise ValueError(f"Error processing RAG results from CSV: {e}") + + +def load_rag_results_from_gt(gts: List[GroundTruth]): + try: + rag_results = RAGResults() + for gt in gts: + result = RAGResult( + query_id=gt.query_id, + query=gt.query, + gt_contexts=[], + ground_truth=gt.answer, + ) + for ctx in gt.contexts: + result.gt_contexts.append(ContextItem(text=ctx.text, file_name=ctx.filename)) + result.init_context_idx(ContextType.GT) + rag_results.add_result(result) + + return rag_results + + except Exception as e: + raise ValueError(f"Error processing RAG results from GroundTruth: {e}") + + +def read_yaml(file_path): + with open(file_path, "r") as file: + yaml_content = file.read() + return yaml.safe_load(yaml_content) diff --git a/evals/evaluation/rag_pilot/configs/ecrag.yaml b/evals/evaluation/rag_pilot/configs/ecrag.yaml index efea8f86..a6b5da75 100644 --- a/evals/evaluation/rag_pilot/configs/ecrag.yaml +++ b/evals/evaluation/rag_pilot/configs/ecrag.yaml @@ -33,6 +33,10 @@ nodes: reranker_model: BAAI/bge-reranker-large - module_type: metadata_replace - node: generator + prompt_path: + - "./prompt_templates" + prompt_content: + - "<|im_start|>System: You are an AI assistant. Your task is to learn from the following context. Then answer the user's question based on what you learned from the context but not your own knowledge.<|im_end|>\n\n<|im_start|>{context}<|im_end|>\n\n<|im_start|>System: Pay attention to your formatting of response. If you need to reference content from context, try to keep the formatting.<|im_end|>\n<|im_start|>System: Try to summarize from the context, do some reasoning before response, then response. Make sure your response is logically sound and self-consistent.<|im_end|>\n\n<|im_start|>{input}" model: - Qwen/Qwen2-7B-Instruct inference_type: diff --git a/evals/evaluation/rag_pilot/docker_compose/intel/gpu/arc/compose.yaml b/evals/evaluation/rag_pilot/docker_compose/intel/gpu/arc/compose.yaml new file mode 100644 index 00000000..42a53ef5 --- /dev/null +++ b/evals/evaluation/rag_pilot/docker_compose/intel/gpu/arc/compose.yaml @@ -0,0 +1,30 @@ +# Copyright (C) 2025 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +services: + ui: + image: ${REGISTRY:-opea}/ragpilot-ui:${TAG:-latest} + container_name: ragpilot-ui + environment: + no_proxy: ${no_proxy} + http_proxy: ${http_proxy} + https_proxy: ${https_proxy} + restart: always + ports: + - ${RAGPILOT_UI_SERVICE_PORT:-8090}:8090 + ragpilot: + image: ${REGISTRY:-opea}/ragpilot:${TAG:-latest} + container_name: ragpilot + environment: + no_proxy: ${no_proxy} + http_proxy: ${http_proxy} + https_proxy: ${https_proxy} + ECRAG_SERVICE_HOST_IP: ${ECRAG_SERVICE_HOST_IP} + ECRAG_SERVICE_PORT: ${ECRAG_SERVICE_PORT:-16010} + restart: always + ports: + - ${RAGPILOT_SERVICE_PORT:-16030}:16030 + +networks: + default: + driver: bridge diff --git a/evals/evaluation/rag_pilot/docker_image_build/build.yaml b/evals/evaluation/rag_pilot/docker_image_build/build.yaml new file mode 100644 index 00000000..9373155f --- /dev/null +++ b/evals/evaluation/rag_pilot/docker_image_build/build.yaml @@ -0,0 +1,21 @@ + +# Copyright (C) 2025 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +services: + ragpilot-ui: + build: + context: .. + args: + http_proxy: ${http_proxy} + https_proxy: ${https_proxy} + dockerfile: ../ui/Dockerfile.ui + image: ${REGISTRY:-opea}/ragpilot-ui:${TAG:-latest} + ragpilot: + build: + context: .. + args: + http_proxy: ${http_proxy} + https_proxy: ${https_proxy} + dockerfile: ../Dockerfile + image: ${REGISTRY:-opea}/ragpilot:${TAG:-latest} diff --git a/evals/evaluation/rag_pilot/prompt_templates/default_prompt_zh.txt b/evals/evaluation/rag_pilot/prompt_templates/default_prompt_zh.txt new file mode 100644 index 00000000..60f3769f --- /dev/null +++ b/evals/evaluation/rag_pilot/prompt_templates/default_prompt_zh.txt @@ -0,0 +1,8 @@ +<|im_start|>็ณป็ปŸ: ไฝ ๆ˜ฏไธ€ไธชAIๅŠฉๆ‰‹ใ€‚ไฝ ็š„ไปปๅŠกๆ˜ฏๅญฆไน ไปฅไธ‹ไธŠไธ‹ๆ–‡ๅ†…ๅฎนใ€‚็„ถๅŽๆ นๆฎไฝ ไปŽไธŠไธ‹ๆ–‡ไธญๅญฆๅˆฐ็š„ๅ†…ๅฎนๅ›ž็ญ”็”จๆˆท็š„้—ฎ้ข˜๏ผŒ่€Œไธๆ˜ฏๅŸบไบŽไฝ ่‡ชๅทฑ็š„็Ÿฅ่ฏ†ใ€‚<|im_end|> + +<|im_start|>{context}<|im_end|> + +<|im_start|>็ณป็ปŸ: ๆณจๆ„ไฝ ็š„ๅ›ž็ญ”ๆ ผๅผใ€‚ๅฆ‚ๆžœไฝ ้œ€่ฆๅผ•็”จไธŠไธ‹ๆ–‡ไธญ็š„ๅ†…ๅฎน๏ผŒ่ฏทๅฐฝ้‡ไฟๆŒๅŽŸๆœ‰็š„ๆ ผๅผใ€‚<|im_end|> +<|im_start|>็ณป็ปŸ: ๅฐ่ฏ•ไปŽไธŠไธ‹ๆ–‡ไธญ่ฟ›่กŒๆ€ป็ป“๏ผŒๅœจๅ›ž็ญ”ๅ‰ๅšไธ€ไบ›ๆŽจ็†๏ผŒ็„ถๅŽๅ†ๅ›ž็ญ”ใ€‚็กฎไฟไฝ ็š„ๅ›ž็ญ”ๅœจ้€ป่พ‘ไธŠๆ˜ฏๅˆ็†็š„ไธ”่‡ชๆดฝ็š„ใ€‚<|im_end|> + +<|im_start|>{input} \ No newline at end of file diff --git a/evals/evaluation/rag_pilot/requirements.txt b/evals/evaluation/rag_pilot/requirements.txt index 6a19ff43..1a0bb29c 100644 --- a/evals/evaluation/rag_pilot/requirements.txt +++ b/evals/evaluation/rag_pilot/requirements.txt @@ -1,2 +1,6 @@ fastapi>=0.115.0 -opea-comps>=1.2 +pandas>=2.3.0 +python-multipart>=0.0.20 +PyYAML>=6.0.2 +requests>=2.32.4 +uvicorn>=0.34.3 diff --git a/evals/evaluation/rag_pilot/run_pilot.py b/evals/evaluation/rag_pilot/run_pilot.py index 6b41c8c2..f8273767 100644 --- a/evals/evaluation/rag_pilot/run_pilot.py +++ b/evals/evaluation/rag_pilot/run_pilot.py @@ -2,91 +2,26 @@ # SPDX-License-Identifier: Apache-2.0 import argparse -import json from collections import defaultdict from enum import Enum from time import sleep -import pandas as pd -import yaml -from components.pilot.base import ( - ContextItem, - ContextType, - RAGPipeline, - RAGResult, - RAGResults, - RAGStage, - convert_dict_to_pipeline, -) -from components.pilot.connector import get_active_pipeline, reindex_data +from api_schema import RAGStage +from components.connect_utils import get_active_pipeline, load_pipeline_from_json, reindex_data +from components.pilot.base import Metrics, RAGPipeline from components.pilot.pilot import Pilot from components.tuner.adaptor import Adaptor from components.tuner.tuner import ( EmbeddingTuner, NodeParserTuner, + PromptTuner, RerankerTopnTuner, RetrievalTopkRerankerTopnTuner, RetrievalTopkTuner, SimpleNodeParserChunkTuner, input_parser, ) - - -def load_rag_results_from_csv(file_path): - rag_results_raw = pd.read_csv(file_path) - rag_results_dict = defaultdict(lambda: {"gt_contexts": []}) - - for _, rag_result in rag_results_raw.iterrows(): - query_id = rag_result.get("query_id") - - if "query" not in rag_results_dict[query_id]: - rag_results_dict[query_id].update( - { - "query": rag_result.get("query", ""), - "ground_truth": rag_result.get("ground_truth", ""), - } - ) - - gt_context = rag_result.get("gt_context", "") - file_name = rag_result.get("file_name", "") - file_name = "" if pd.isna(file_name) else str(file_name) - - if gt_context: - rag_results_dict[query_id]["gt_contexts"].append(ContextItem(text=gt_context, file_name=file_name)) - - rag_results = RAGResults() - for query_id, data in rag_results_dict.items(): - result = RAGResult( - query_id=query_id, - query=data["query"], - gt_contexts=data["gt_contexts"] if data["gt_contexts"] else None, - ground_truth=data["ground_truth"], - ) - result.init_context_idx(ContextType.GT) - rag_results.add_result(result) - - return rag_results - - -def load_pipeline_from_json(file_path): - try: - with open(file_path, "r", encoding="utf-8") as file: - data = json.load(file) - return convert_dict_to_pipeline(data) - except FileNotFoundError: - print(f"The file '{file_path}' was not found.") - except json.JSONDecodeError: - print(f"Error decoding JSON in the file '{file_path}'.") - except Exception as e: - print(f"An unexpected error occurred: {e}") - - return None - - -def read_yaml(file_path): - with open(file_path, "r") as file: - yaml_content = file.read() - return yaml.safe_load(yaml_content) +from components.utils import load_rag_results_from_csv, read_yaml class Mode(str, Enum): @@ -132,7 +67,7 @@ def main(): RetrievalTopkTuner(adaptor), ] postprocessing_tuner_list = [RerankerTopnTuner(adaptor)] - + prompt_tuner_list = [PromptTuner(adaptor)] rag_results = load_rag_results_from_csv(args.qa_list) pilot = Pilot(rag_results_sample=rag_results, hit_threshold=0.9) @@ -140,13 +75,18 @@ def main(): active_pl.regenerate_id() pilot.add_rag_pipeline(active_pl) - pilot.run_curr_pl() + pilot.run_pipeline() def ask_stage_satisfaction(stage) -> bool: - results = pilot.get_curr_results() - recall_rate = results.metadata.get("recall_rate", {}) if results else {} + rag_results = pilot.get_curr_results() + if stage is RAGStage.RETRIEVAL: + recall_rate = rag_results.metadata.get(Metrics.RETRIEVAL_RECALL, None) + elif stage is RAGStage.POSTPROCESSING: + recall_rate = rag_results.metadata.get(Metrics.POSTPROCESSING_RECALL, None) + else: + recall_rate = None - print(f"\n{BOLD}{YELLOW}[STAGE {stage.value}]{RESET} recall_rate is {recall_rate.get(stage)}") + print(f"\n{BOLD}{YELLOW}[STAGE {stage.value}]{RESET} recall_rate is {recall_rate}") print("Are you satisfied with this metric?\n 1: Yes and jump to next stage\n 2: No and keep tuning") valid, user_input = input_parser(2) return valid and user_input == 1 @@ -166,11 +106,13 @@ def run_tuner_stage(tuner_list, stage): pl_list, params_candidates = tuner.apply_suggestions() for pl, params in zip(pl_list, params_candidates): print(f"Trying to update pipeline to {params}") + is_prompt_tuning = stage == RAGStage.GENERATION and "prompt_content" in params if pl.id != active_pl.id: pilot.add_rag_pipeline(pl) pilot.curr_pl_id = pl.id - reindex_data() - pilot.run_curr_pl() + if not is_prompt_tuning: + reindex_data() + pilot.run_pipeline() print("Metrics of this pipeline:") results = pilot.get_results(pl.id) if results: @@ -207,15 +149,19 @@ def run_full_tuning(): print("User satisfied with RETRIEVAL. Proceeding to POSTPROCESSING tuning...") else: _ = run_tuner_stage(retrieval_tuner_list, RAGStage.RETRIEVAL) + sleep(1) if ask_stage_satisfaction(RAGStage.POSTPROCESSING): print("User satisfied with POSTPROCESSING. Exiting.") return - sleep(1) # Step 3: POSTPROCESSING tuning print("\nStarting POSTPROCESSING tuning...") _ = run_tuner_stage(postprocessing_tuner_list, RAGStage.POSTPROCESSING) + # Step 4: Optional PROMPT tuning + print("\nStarting PROMPT tuning...") + _ = run_tuner_stage(prompt_tuner_list, RAGStage.GENERATION) + print(f"\n{BOLD}{GREEN}๐ŸŽฏ Tuning complete.{RESET}") run_full_tuning() diff --git a/evals/evaluation/rag_pilot/server.py b/evals/evaluation/rag_pilot/server.py new file mode 100644 index 00000000..73c493b3 --- /dev/null +++ b/evals/evaluation/rag_pilot/server.py @@ -0,0 +1,39 @@ +# Copyright (C) 2025 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +import os + +import uvicorn +from api.v1.pilot import pilot_app +from api.v1.tuner import tuner_app +from components.pilot.pilot import init_active_pipeline +from components.tuner.tunermgr import init_tuners +from fastapi import FastAPI +from fastapi.middleware.cors import CORSMiddleware + +app = FastAPI() +app.add_middleware( + CORSMiddleware, + allow_origins=["*"], + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + + +sub_apps = [pilot_app, tuner_app] +for sub_app in sub_apps: + for route in sub_app.routes: + app.router.routes.append(route) + + +@app.on_event("startup") +def startup(): + init_active_pipeline() + init_tuners() + + +if __name__ == "__main__": + host = os.getenv("RAG_PILOT_SERVICE_HOST_IP", "0.0.0.0") + port = int(os.getenv("RAG_PILOT_SERVICE_PORT", 16030)) + uvicorn.run(app, host=host, port=port) diff --git a/evals/evaluation/rag_pilot/ui/.env.development b/evals/evaluation/rag_pilot/ui/.env.development new file mode 100644 index 00000000..bb77a0be --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/.env.development @@ -0,0 +1,5 @@ +# Local +ENV = development + +# Local Api +VITE_API_URL = http://10.67.106.189:16030/ diff --git a/evals/evaluation/rag_pilot/ui/.env.production b/evals/evaluation/rag_pilot/ui/.env.production new file mode 100644 index 00000000..a19b6ba5 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/.env.production @@ -0,0 +1,5 @@ +# Online +ENV = production + +# Online Api +VITE_API_URL = / \ No newline at end of file diff --git a/evals/evaluation/rag_pilot/ui/.gitignore b/evals/evaluation/rag_pilot/ui/.gitignore new file mode 100644 index 00000000..a547bf36 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/evals/evaluation/rag_pilot/ui/Dockerfile.ui b/evals/evaluation/rag_pilot/ui/Dockerfile.ui new file mode 100644 index 00000000..32ab1c15 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/Dockerfile.ui @@ -0,0 +1,28 @@ +FROM node:20.18.1 AS ui-app + +RUN apt-get update -y && apt-get install -y git + +RUN useradd -m -s /bin/bash user && \ + mkdir -p /home/user && \ + chown -R user /home/user/ + +COPY ./ui /home/user/ui + +RUN mkdir -p /home/user/ui + +WORKDIR /home/user/ui + +RUN npm install + +RUN npm run build + +FROM nginx:stable-alpine + +COPY --from=ui-app home/user/ui/dist /usr/share/nginx/html + +COPY ./ui/nginx.conf /etc/nginx/nginx.conf + +EXPOSE 8090 + +CMD ["nginx", "-g", "daemon off;"] + diff --git a/evals/evaluation/rag_pilot/ui/README.md b/evals/evaluation/rag_pilot/ui/README.md new file mode 100644 index 00000000..e69de29b diff --git a/evals/evaluation/rag_pilot/ui/auto-imports.d.ts b/evals/evaluation/rag_pilot/ui/auto-imports.d.ts new file mode 100644 index 00000000..b75b9826 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/auto-imports.d.ts @@ -0,0 +1,91 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +/* eslint-disable */ +/* prettier-ignore */ +// @ts-nocheck +// noinspection JSUnusedGlobalSymbols +// Generated by unplugin-auto-import +// biome-ignore lint: disable +export {} +declare global { + const EffectScope: typeof import('vue')['EffectScope'] + const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate'] + const computed: typeof import('vue')['computed'] + const createApp: typeof import('vue')['createApp'] + const createPinia: typeof import('pinia')['createPinia'] + const customRef: typeof import('vue')['customRef'] + const defineAsyncComponent: typeof import('vue')['defineAsyncComponent'] + const defineComponent: typeof import('vue')['defineComponent'] + const defineStore: typeof import('pinia')['defineStore'] + const effectScope: typeof import('vue')['effectScope'] + const getActivePinia: typeof import('pinia')['getActivePinia'] + const getCurrentInstance: typeof import('vue')['getCurrentInstance'] + const getCurrentScope: typeof import('vue')['getCurrentScope'] + const h: typeof import('vue')['h'] + const inject: typeof import('vue')['inject'] + const isProxy: typeof import('vue')['isProxy'] + const isReactive: typeof import('vue')['isReactive'] + const isReadonly: typeof import('vue')['isReadonly'] + const isRef: typeof import('vue')['isRef'] + const mapActions: typeof import('pinia')['mapActions'] + const mapGetters: typeof import('pinia')['mapGetters'] + const mapState: typeof import('pinia')['mapState'] + const mapStores: typeof import('pinia')['mapStores'] + const mapWritableState: typeof import('pinia')['mapWritableState'] + const markRaw: typeof import('vue')['markRaw'] + const nextTick: typeof import('vue')['nextTick'] + const onActivated: typeof import('vue')['onActivated'] + const onBeforeMount: typeof import('vue')['onBeforeMount'] + const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave'] + const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate'] + const onBeforeUnmount: typeof import('vue')['onBeforeUnmount'] + const onBeforeUpdate: typeof import('vue')['onBeforeUpdate'] + const onDeactivated: typeof import('vue')['onDeactivated'] + const onErrorCaptured: typeof import('vue')['onErrorCaptured'] + const onMounted: typeof import('vue')['onMounted'] + const onRenderTracked: typeof import('vue')['onRenderTracked'] + const onRenderTriggered: typeof import('vue')['onRenderTriggered'] + const onScopeDispose: typeof import('vue')['onScopeDispose'] + const onServerPrefetch: typeof import('vue')['onServerPrefetch'] + const onUnmounted: typeof import('vue')['onUnmounted'] + const onUpdated: typeof import('vue')['onUpdated'] + const onWatcherCleanup: typeof import('vue')['onWatcherCleanup'] + const provide: typeof import('vue')['provide'] + const reactive: typeof import('vue')['reactive'] + const readonly: typeof import('vue')['readonly'] + const ref: typeof import('vue')['ref'] + const resolveComponent: typeof import('vue')['resolveComponent'] + const setActivePinia: typeof import('pinia')['setActivePinia'] + const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix'] + const shallowReactive: typeof import('vue')['shallowReactive'] + const shallowReadonly: typeof import('vue')['shallowReadonly'] + const shallowRef: typeof import('vue')['shallowRef'] + const storeToRefs: typeof import('pinia')['storeToRefs'] + const toRaw: typeof import('vue')['toRaw'] + const toRef: typeof import('vue')['toRef'] + const toRefs: typeof import('vue')['toRefs'] + const toValue: typeof import('vue')['toValue'] + const triggerRef: typeof import('vue')['triggerRef'] + const unref: typeof import('vue')['unref'] + const useAttrs: typeof import('vue')['useAttrs'] + const useCssModule: typeof import('vue')['useCssModule'] + const useCssVars: typeof import('vue')['useCssVars'] + const useId: typeof import('vue')['useId'] + const useLink: typeof import('vue-router')['useLink'] + const useModel: typeof import('vue')['useModel'] + const useRoute: typeof import('vue-router')['useRoute'] + const useRouter: typeof import('vue-router')['useRouter'] + const useSlots: typeof import('vue')['useSlots'] + const useTemplateRef: typeof import('vue')['useTemplateRef'] + const watch: typeof import('vue')['watch'] + const watchEffect: typeof import('vue')['watchEffect'] + const watchPostEffect: typeof import('vue')['watchPostEffect'] + const watchSyncEffect: typeof import('vue')['watchSyncEffect'] +} +// for type re-export +declare global { + // @ts-ignore + export type { Component, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue' + import('vue') +} diff --git a/evals/evaluation/rag_pilot/ui/components.d.ts b/evals/evaluation/rag_pilot/ui/components.d.ts new file mode 100644 index 00000000..b9467725 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/components.d.ts @@ -0,0 +1,50 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +/* eslint-disable */ +// @ts-nocheck +// Generated by unplugin-vue-components +// Read more: https://github.com/vuejs/core/pull/3399 +export {} + +/* prettier-ignore */ +declare module 'vue' { + export interface GlobalComponents { + AAffix: typeof import('ant-design-vue/es')['Affix'] + ABadgeRibbon: typeof import('ant-design-vue/es')['BadgeRibbon'] + AButton: typeof import('ant-design-vue/es')['Button'] + ACol: typeof import('ant-design-vue/es')['Col'] + ACollapse: typeof import('ant-design-vue/es')['Collapse'] + ACollapsePanel: typeof import('ant-design-vue/es')['CollapsePanel'] + AConfigProvider: typeof import('ant-design-vue/es')['ConfigProvider'] + ADivider: typeof import('ant-design-vue/es')['Divider'] + ADrawer: typeof import('ant-design-vue/es')['Drawer'] + ADropdown: typeof import('ant-design-vue/es')['Dropdown'] + AForm: typeof import('ant-design-vue/es')['Form'] + AFormItem: typeof import('ant-design-vue/es')['FormItem'] + AInput: typeof import('ant-design-vue/es')['Input'] + ALayout: typeof import('ant-design-vue/es')['Layout'] + ALayoutContent: typeof import('ant-design-vue/es')['LayoutContent'] + ALayoutHeader: typeof import('ant-design-vue/es')['LayoutHeader'] + AMenu: typeof import('ant-design-vue/es')['Menu'] + AMenuItem: typeof import('ant-design-vue/es')['MenuItem'] + APagination: typeof import('ant-design-vue/es')['Pagination'] + ARate: typeof import('ant-design-vue/es')['Rate'] + ARow: typeof import('ant-design-vue/es')['Row'] + ASlider: typeof import('ant-design-vue/es')['Slider'] + ASpin: typeof import('ant-design-vue/es')['Spin'] + AStep: typeof import('ant-design-vue/es')['Step'] + ASteps: typeof import('ant-design-vue/es')['Steps'] + ATable: typeof import('ant-design-vue/es')['Table'] + ATabPane: typeof import('ant-design-vue/es')['TabPane'] + ATabs: typeof import('ant-design-vue/es')['Tabs'] + ATag: typeof import('ant-design-vue/es')['Tag'] + ATextarea: typeof import('ant-design-vue/es')['Textarea'] + ATooltip: typeof import('ant-design-vue/es')['Tooltip'] + AUploadDragger: typeof import('ant-design-vue/es')['UploadDragger'] + FormTooltip: typeof import('./src/components/FormTooltip.vue')['default'] + RouterLink: typeof import('vue-router')['RouterLink'] + RouterView: typeof import('vue-router')['RouterView'] + SvgIcon: typeof import('./src/components/SvgIcon.vue')['default'] + } +} diff --git a/evals/evaluation/rag_pilot/ui/index.html b/evals/evaluation/rag_pilot/ui/index.html new file mode 100644 index 00000000..1cacbdf1 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/index.html @@ -0,0 +1,22 @@ + + + + + + + + + + + RAG Pilot Pipeline Autotune Tool + + + +
+ + + + diff --git a/evals/evaluation/rag_pilot/ui/nginx.conf b/evals/evaluation/rag_pilot/ui/nginx.conf new file mode 100644 index 00000000..8dd1fcc4 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/nginx.conf @@ -0,0 +1,36 @@ + +worker_processes 1; + +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + client_max_body_size 50M; + + sendfile on; + keepalive_timeout 120s; + + server { + listen 8090; + server_name _; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + add_header Cache-Control "no-cache"; + try_files $uri $uri/ /index.html; + } + + location /v1/ { + proxy_pass http://ragpilot:16030; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_http_version 1.1; + proxy_set_header Connection ""; + proxy_read_timeout 600s; + } + + } +} diff --git a/evals/evaluation/rag_pilot/ui/package-lock.json b/evals/evaluation/rag_pilot/ui/package-lock.json new file mode 100644 index 00000000..24fbbb47 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/package-lock.json @@ -0,0 +1,4850 @@ +{ + "name": "rag-pilot-ui", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "rag-pilot-ui", + "version": "0.0.0", + "license": "ISC", + "dependencies": { + "@vueuse/i18n": "^4.0.0-beta.12", + "ant-design-vue": "^4.0.0-rc.6", + "axios": "^1.7.9", + "clipboard": "^2.0.11", + "echarts": "^5.6.0", + "event-source-polyfill": "^1.0.31", + "highlight.js": "^11.11.1", + "http": "^0.0.1-security", + "js-cookie": "^3.0.5", + "json-editor-vue": "^0.18.1", + "jsoneditor": "^10.2.0", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "marked": "^15.0.6", + "pinia": "^3.0.2", + "pinia-plugin-persistedstate": "^4.2.0", + "qs": "^6.13.1", + "vite-plugin-compression": "^0.5.1", + "vue": "^3.5.13", + "vue-echarts": "^7.0.3", + "vue-i18n": "^10.0.5", + "vue-json-editor": "^1.4.3", + "vue-json-pretty": "^2.4.0", + "vue-router": "^4.5.0", + "ws": "^8.18.0" + }, + "devDependencies": { + "@types/eventsource": "^1.1.15", + "@types/js-cookie": "^3.0.6", + "@types/jsoneditor": "^9.9.5", + "@types/lodash-es": "^4.17.12", + "@types/marked": "^5.0.2", + "@types/node": "^22.10.2", + "@vitejs/plugin-vue": "^5.2.1", + "less": "^4.2.1", + "less-loader": "^12.2.0", + "typescript": "~5.6.2", + "unplugin-auto-import": "^0.19.0", + "unplugin-vue-components": "^0.27.5", + "vite": "^6.0.1", + "vue-tsc": "^2.1.10" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@ant-design/colors": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-6.0.0.tgz", + "integrity": "sha512-qAZRvPzfdWHtfameEGP2Qvuf838NhergR35o+EuVyB5XvSA98xod5r4utvi4TJ3ywmevm290g9nsCG5MryrdWQ==", + "license": "MIT", + "dependencies": { + "@ctrl/tinycolor": "^3.4.0" + } + }, + "node_modules/@ant-design/icons-svg": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@ant-design/icons-svg/-/icons-svg-4.4.2.tgz", + "integrity": "sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA==", + "license": "MIT" + }, + "node_modules/@ant-design/icons-vue": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@ant-design/icons-vue/-/icons-vue-7.0.1.tgz", + "integrity": "sha512-eCqY2unfZK6Fe02AwFlDHLfoyEFreP6rBwAZMIJ1LugmfMiVgwWDYlp1YsRugaPtICYOabV1iWxXdP12u9U43Q==", + "license": "MIT", + "dependencies": { + "@ant-design/colors": "^6.0.0", + "@ant-design/icons-svg": "^4.2.1" + }, + "peerDependencies": { + "vue": ">=3.0.3" + } + }, + "node_modules/@antfu/utils": { + "version": "0.7.10", + "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-0.7.10.tgz", + "integrity": "sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.27.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.5.tgz", + "integrity": "sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.27.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz", + "integrity": "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.27.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.6.tgz", + "integrity": "sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@codemirror/autocomplete": { + "version": "6.18.6", + "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.18.6.tgz", + "integrity": "sha512-PHHBXFomUs5DF+9tCOM/UoW6XQ4R44lLNNhRaW9PKPTU0D7lIjRg3ElxaJnTwsl/oHiR93WSXDBrekhoUGCPtg==", + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@codemirror/commands": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.8.1.tgz", + "integrity": "sha512-KlGVYufHMQzxbdQONiLyGQDUW0itrLZwq3CcY7xpv9ZLRHqzkBSoteocBHtMCoY7/Ci4xhzSrToIeLg7FxHuaw==", + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.4.0", + "@codemirror/view": "^6.27.0", + "@lezer/common": "^1.1.0" + } + }, + "node_modules/@codemirror/lang-json": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@codemirror/lang-json/-/lang-json-6.0.1.tgz", + "integrity": "sha512-+T1flHdgpqDDlJZ2Lkil/rLiRy684WMLc74xUnjJH48GQdfJo/pudlTRreZmKwzP8/tGdKf83wlbAdOCzlJOGQ==", + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@lezer/json": "^1.0.0" + } + }, + "node_modules/@codemirror/language": { + "version": "6.11.1", + "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.11.1.tgz", + "integrity": "sha512-5kS1U7emOGV84vxC+ruBty5sUgcD0te6dyupyRVG2zaSjhTDM73LhVKUtVwiqSe6QwmEoA4SCiU8AKPFyumAWQ==", + "license": "MIT", + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.23.0", + "@lezer/common": "^1.1.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0", + "style-mod": "^4.0.0" + } + }, + "node_modules/@codemirror/lint": { + "version": "6.8.5", + "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.8.5.tgz", + "integrity": "sha512-s3n3KisH7dx3vsoeGMxsbRAgKe4O1vbrnKBClm99PU0fWxmxsx5rR2PfqQgIt+2MMJBHbiJ5rfIdLYfB9NNvsA==", + "license": "MIT", + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.35.0", + "crelt": "^1.0.5" + } + }, + "node_modules/@codemirror/search": { + "version": "6.5.11", + "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.11.tgz", + "integrity": "sha512-KmWepDE6jUdL6n8cAAqIpRmLPBZ5ZKnicE8oGU/s3QrAVID+0VhLFrzUucVKHG5035/BSykhExDL/Xm7dHthiA==", + "license": "MIT", + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "crelt": "^1.0.5" + } + }, + "node_modules/@codemirror/state": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.5.2.tgz", + "integrity": "sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==", + "license": "MIT", + "dependencies": { + "@marijn/find-cluster-break": "^1.0.0" + } + }, + "node_modules/@codemirror/view": { + "version": "6.37.1", + "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.37.1.tgz", + "integrity": "sha512-Qy4CAUwngy/VQkEz0XzMKVRcckQuqLYWKqVpDDDghBe5FSXSqfVrJn49nw3ePZHxRUz4nRmb05Lgi+9csWo4eg==", + "license": "MIT", + "dependencies": { + "@codemirror/state": "^6.5.0", + "crelt": "^1.0.6", + "style-mod": "^4.1.0", + "w3c-keyname": "^2.2.4" + } + }, + "node_modules/@ctrl/tinycolor": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz", + "integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==", + "license": "MIT" + }, + "node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==", + "license": "MIT" + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz", + "integrity": "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.5.tgz", + "integrity": "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz", + "integrity": "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.5.tgz", + "integrity": "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz", + "integrity": "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz", + "integrity": "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz", + "integrity": "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz", + "integrity": "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz", + "integrity": "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz", + "integrity": "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz", + "integrity": "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz", + "integrity": "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz", + "integrity": "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz", + "integrity": "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz", + "integrity": "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz", + "integrity": "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz", + "integrity": "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz", + "integrity": "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz", + "integrity": "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz", + "integrity": "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz", + "integrity": "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz", + "integrity": "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz", + "integrity": "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz", + "integrity": "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz", + "integrity": "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@fortawesome/fontawesome-common-types": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.7.2.tgz", + "integrity": "sha512-Zs+YeHUC5fkt7Mg1l6XTniei3k4bwG/yo3iFUtZWd/pMx9g3fdvkSK9E0FOC+++phXOka78uJcYb8JaFkW52Xg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-regular-svg-icons": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.7.2.tgz", + "integrity": "sha512-7Z/ur0gvCMW8G93dXIQOkQqHo2M5HLhYrRVC0//fakJXxcF1VmMPsxnG6Ee8qEylA8b8Q3peQXWMNZ62lYF28g==", + "license": "(CC-BY-4.0 AND MIT)", + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.7.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-solid-svg-icons": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.7.2.tgz", + "integrity": "sha512-GsBrnOzU8uj0LECDfD5zomZJIjrPhIlWU82AHwa2s40FKH+kcxQaBvBo3Z4TxyZHIyX8XTDxsyA33/Vx9eFuQA==", + "license": "(CC-BY-4.0 AND MIT)", + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.7.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@intlify/core-base": { + "version": "10.0.7", + "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-10.0.7.tgz", + "integrity": "sha512-mE71aUH5baH0me8duB4FY5qevUJizypHsYw3eCvmOx07QvmKppgOONx3dYINxuA89Z2qkAGb/K6Nrpi7aAMwew==", + "license": "MIT", + "dependencies": { + "@intlify/message-compiler": "10.0.7", + "@intlify/shared": "10.0.7" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/kazupon" + } + }, + "node_modules/@intlify/message-compiler": { + "version": "10.0.7", + "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-10.0.7.tgz", + "integrity": "sha512-nrC4cDL/UHZSUqd8sRbVz+DPukzZ8NnG5OK+EB/nlxsH35deyzyVkXP/QuR8mFZrISJ+4hCd6VtCQCcT+RO+5g==", + "license": "MIT", + "dependencies": { + "@intlify/shared": "10.0.7", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/kazupon" + } + }, + "node_modules/@intlify/shared": { + "version": "10.0.7", + "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-10.0.7.tgz", + "integrity": "sha512-oeoq0L5+5P4ShXa6jBQcx+BT+USe3MjX0xJexZO1y7rfDJdwZ9+QP3jO4tcS1nxhBYYdjvFTqe4bmnLijV0GxQ==", + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/kazupon" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jsep-plugin/assignment": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@jsep-plugin/assignment/-/assignment-1.3.0.tgz", + "integrity": "sha512-VVgV+CXrhbMI3aSusQyclHkenWSAm95WaiKrMxRFam3JSUiIaQjoMIw2sEs/OX4XifnqeQUN4DYbJjlA8EfktQ==", + "license": "MIT", + "engines": { + "node": ">= 10.16.0" + }, + "peerDependencies": { + "jsep": "^0.4.0||^1.0.0" + } + }, + "node_modules/@jsep-plugin/regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@jsep-plugin/regex/-/regex-1.0.4.tgz", + "integrity": "sha512-q7qL4Mgjs1vByCaTnDFcBnV9HS7GVPJX5vyVoCgZHNSC9rjwIlmbXG5sUuorR5ndfHAIlJ8pVStxvjXHbNvtUg==", + "license": "MIT", + "engines": { + "node": ">= 10.16.0" + }, + "peerDependencies": { + "jsep": "^0.4.0||^1.0.0" + } + }, + "node_modules/@jsonquerylang/jsonquery": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@jsonquerylang/jsonquery/-/jsonquery-5.0.3.tgz", + "integrity": "sha512-aH9paBzg4E2Kel/1e04GoqexIcH5tUMp0gdBhrA7aOFL4oJOIzcRv5Bdr31IJlzt+yP7BMJ3/tViSolFL3w8pw==", + "license": "ISC", + "bin": { + "jsonquery": "bin/cli.js" + } + }, + "node_modules/@lezer/common": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.3.tgz", + "integrity": "sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA==", + "license": "MIT" + }, + "node_modules/@lezer/highlight": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.1.tgz", + "integrity": "sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@lezer/json": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@lezer/json/-/json-1.0.3.tgz", + "integrity": "sha512-BP9KzdF9Y35PDpv04r0VeSTKDeox5vVr3efE7eBbx3r4s3oNLfunchejZhjArmeieBH+nVOpgIiBJpEAv8ilqQ==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lezer/lr": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.2.tgz", + "integrity": "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@marijn/find-cluster-break": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz", + "integrity": "sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==", + "license": "MIT" + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nuxt/kit": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/@nuxt/kit/-/kit-3.17.5.tgz", + "integrity": "sha512-NdCepmA+S/SzgcaL3oYUeSlXGYO6BXGr9K/m1D0t0O9rApF8CSq/QQ+ja5KYaYMO1kZAEWH4s2XVcE3uPrrAVg==", + "license": "MIT", + "dependencies": { + "c12": "^3.0.4", + "consola": "^3.4.2", + "defu": "^6.1.4", + "destr": "^2.0.5", + "errx": "^0.1.0", + "exsolve": "^1.0.5", + "ignore": "^7.0.5", + "jiti": "^2.4.2", + "klona": "^2.0.6", + "knitwork": "^1.2.0", + "mlly": "^1.7.4", + "ohash": "^2.0.11", + "pathe": "^2.0.3", + "pkg-types": "^2.1.0", + "scule": "^1.3.0", + "semver": "^7.7.2", + "std-env": "^3.9.0", + "tinyglobby": "^0.2.14", + "ufo": "^1.6.1", + "unctx": "^2.4.1", + "unimport": "^5.0.1", + "untyped": "^2.0.0" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/@nuxt/kit/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@replit/codemirror-indentation-markers": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/@replit/codemirror-indentation-markers/-/codemirror-indentation-markers-6.5.3.tgz", + "integrity": "sha512-hL5Sfvw3C1vgg7GolLe/uxX5T3tmgOA3ZzqlMv47zjU1ON51pzNWiVbS22oh6crYhtVhv8b3gdXwoYp++2ilHw==", + "license": "MIT", + "peerDependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0" + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz", + "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.42.0.tgz", + "integrity": "sha512-gldmAyS9hpj+H6LpRNlcjQWbuKUtb94lodB9uCz71Jm+7BxK1VIOo7y62tZZwxhA7j1ylv/yQz080L5WkS+LoQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.42.0.tgz", + "integrity": "sha512-bpRipfTgmGFdCZDFLRvIkSNO1/3RGS74aWkJJTFJBH7h3MRV4UijkaEUeOMbi9wxtxYmtAbVcnMtHTPBhLEkaw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.42.0.tgz", + "integrity": "sha512-JxHtA081izPBVCHLKnl6GEA0w3920mlJPLh89NojpU2GsBSB6ypu4erFg/Wx1qbpUbepn0jY4dVWMGZM8gplgA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.42.0.tgz", + "integrity": "sha512-rv5UZaWVIJTDMyQ3dCEK+m0SAn6G7H3PRc2AZmExvbDvtaDc+qXkei0knQWcI3+c9tEs7iL/4I4pTQoPbNL2SA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.42.0.tgz", + "integrity": "sha512-fJcN4uSGPWdpVmvLuMtALUFwCHgb2XiQjuECkHT3lWLZhSQ3MBQ9pq+WoWeJq2PrNxr9rPM1Qx+IjyGj8/c6zQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.42.0.tgz", + "integrity": "sha512-CziHfyzpp8hJpCVE/ZdTizw58gr+m7Y2Xq5VOuCSrZR++th2xWAz4Nqk52MoIIrV3JHtVBhbBsJcAxs6NammOQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.42.0.tgz", + "integrity": "sha512-UsQD5fyLWm2Fe5CDM7VPYAo+UC7+2Px4Y+N3AcPh/LdZu23YcuGPegQly++XEVaC8XUTFVPscl5y5Cl1twEI4A==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.42.0.tgz", + "integrity": "sha512-/i8NIrlgc/+4n1lnoWl1zgH7Uo0XK5xK3EDqVTf38KvyYgCU/Rm04+o1VvvzJZnVS5/cWSd07owkzcVasgfIkQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.42.0.tgz", + "integrity": "sha512-eoujJFOvoIBjZEi9hJnXAbWg+Vo1Ov8n/0IKZZcPZ7JhBzxh2A+2NFyeMZIRkY9iwBvSjloKgcvnjTbGKHE44Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.42.0.tgz", + "integrity": "sha512-/3NrcOWFSR7RQUQIuZQChLND36aTU9IYE4j+TB40VU78S+RA0IiqHR30oSh6P1S9f9/wVOenHQnacs/Byb824g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.42.0.tgz", + "integrity": "sha512-O8AplvIeavK5ABmZlKBq9/STdZlnQo7Sle0LLhVA7QT+CiGpNVe197/t8Aph9bhJqbDVGCHpY2i7QyfEDDStDg==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.42.0.tgz", + "integrity": "sha512-6Qb66tbKVN7VyQrekhEzbHRxXXFFD8QKiFAwX5v9Xt6FiJ3BnCVBuyBxa2fkFGqxOCSGGYNejxd8ht+q5SnmtA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.42.0.tgz", + "integrity": "sha512-KQETDSEBamQFvg/d8jajtRwLNBlGc3aKpaGiP/LvEbnmVUKlFta1vqJqTrvPtsYsfbE/DLg5CC9zyXRX3fnBiA==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.42.0.tgz", + "integrity": "sha512-qMvnyjcU37sCo/tuC+JqeDKSuukGAd+pVlRl/oyDbkvPJ3awk6G6ua7tyum02O3lI+fio+eM5wsVd66X0jQtxw==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.42.0.tgz", + "integrity": "sha512-I2Y1ZUgTgU2RLddUHXTIgyrdOwljjkmcZ/VilvaEumtS3Fkuhbw4p4hgHc39Ypwvo2o7sBFNl2MquNvGCa55Iw==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.42.0.tgz", + "integrity": "sha512-Gfm6cV6mj3hCUY8TqWa63DB8Mx3NADoFwiJrMpoZ1uESbK8FQV3LXkhfry+8bOniq9pqY1OdsjFWNsSbfjPugw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.42.0.tgz", + "integrity": "sha512-g86PF8YZ9GRqkdi0VoGlcDUb4rYtQKyTD1IVtxxN4Hpe7YqLBShA7oHMKU6oKTCi3uxwW4VkIGnOaH/El8de3w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.42.0.tgz", + "integrity": "sha512-+axkdyDGSp6hjyzQ5m1pgcvQScfHnMCcsXkx8pTgy/6qBmWVhtRVlgxjWwDp67wEXXUr0x+vD6tp5W4x6V7u1A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.42.0.tgz", + "integrity": "sha512-F+5J9pelstXKwRSDq92J0TEBXn2nfUrQGg+HK1+Tk7VOL09e0gBqUHugZv7SW4MGrYj41oNCUe3IKCDGVlis2g==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.42.0.tgz", + "integrity": "sha512-LpHiJRwkaVz/LqjHjK8LCi8osq7elmpwujwbXKNW88bM8eeGxavJIKKjkjpMHAh/2xfnrt1ZSnhTv41WYUHYmA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@simonwep/pickr": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/@simonwep/pickr/-/pickr-1.8.2.tgz", + "integrity": "sha512-/l5w8BIkrpP6n1xsetx9MWPWlU6OblN5YgZZphxan0Tq4BByTCETL6lyIeY8lagalS2Nbt4F2W034KHLIiunKA==", + "license": "MIT", + "dependencies": { + "core-js": "^3.15.1", + "nanopop": "^2.1.0" + } + }, + "node_modules/@sphinxxxx/color-conversion": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@sphinxxxx/color-conversion/-/color-conversion-2.2.2.tgz", + "integrity": "sha512-XExJS3cLqgrmNBIP3bBw6+1oQ1ksGjFh0+oClDKFYpCCqx/hlqwWO5KO/S63fzUo67SxI9dMrF0y5T/Ey7h8Zw==", + "license": "ISC" + }, + "node_modules/@sveltejs/acorn-typescript": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.5.tgz", + "integrity": "sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ==", + "license": "MIT", + "peerDependencies": { + "acorn": "^8.9.0" + } + }, + "node_modules/@types/ace": { + "version": "0.0.52", + "resolved": "https://registry.npmjs.org/@types/ace/-/ace-0.0.52.tgz", + "integrity": "sha512-YPF9S7fzpuyrxru+sG/rrTpZkC6gpHBPF14W3x70kqVOD+ks6jkYLapk4yceh36xej7K4HYxcyz9ZDQ2lTvwgQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "license": "MIT" + }, + "node_modules/@types/eventsource": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@types/eventsource/-/eventsource-1.1.15.tgz", + "integrity": "sha512-XQmGcbnxUNa06HR3VBVkc9+A2Vpi9ZyLJcdS5dwaQQ/4ZMWFO+5c90FnMUpbtMZwB/FChoYHwuVg8TvkECacTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/js-cookie": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-3.0.6.tgz", + "integrity": "sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/jsoneditor": { + "version": "9.9.5", + "resolved": "https://registry.npmjs.org/@types/jsoneditor/-/jsoneditor-9.9.5.tgz", + "integrity": "sha512-+Wex7QCirPcG90WA8/CmvDO21KUjz63/G7Yk52Yx/NhWHw5DyeET/L+wjZHAeNeNCCnMOTEtVX5gc3F4UXwXMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/ace": "*", + "ajv": "^6.12.0" + } + }, + "node_modules/@types/lodash": { + "version": "4.17.17", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.17.tgz", + "integrity": "sha512-RRVJ+J3J+WmyOTqnz3PiBLA501eKwXl2noseKOrNo/6+XEHjTAxO4xHvxQB6QuNm+s4WRbn6rSiap8+EA+ykFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/lodash-es": { + "version": "4.17.12", + "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz", + "integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/marked": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@types/marked/-/marked-5.0.2.tgz", + "integrity": "sha512-OucS4KMHhFzhz27KxmWg7J+kIYqyqoW5kdIEI319hqARQQUTqhao3M/F+uFnDXD0Rg72iDDZxZNxq5gvctmLlg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.15.31", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.31.tgz", + "integrity": "sha512-jnVe5ULKl6tijxUhvQeNbQG/84fHfg+yMak02cT8QVhBx/F05rAVxCGBYYTh2EKz22D6JF5ktXuNwdx7b9iEGw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@vitejs/plugin-vue": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz", + "integrity": "sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "vite": "^5.0.0 || ^6.0.0", + "vue": "^3.2.25" + } + }, + "node_modules/@volar/language-core": { + "version": "2.4.14", + "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.14.tgz", + "integrity": "sha512-X6beusV0DvuVseaOEy7GoagS4rYHgDHnTrdOj5jeUb49fW5ceQyP9Ej5rBhqgz2wJggl+2fDbbojq1XKaxDi6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/source-map": "2.4.14" + } + }, + "node_modules/@volar/source-map": { + "version": "2.4.14", + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.14.tgz", + "integrity": "sha512-5TeKKMh7Sfxo8021cJfmBzcjfY1SsXsPMMjMvjY7ivesdnybqqS+GxGAoXHAOUawQTwtdUxgP65Im+dEmvWtYQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@volar/typescript": { + "version": "2.4.14", + "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.14.tgz", + "integrity": "sha512-p8Z6f/bZM3/HyCdRNFZOEEzts51uV8WHeN8Tnfnm2EBv6FDB2TQLzfVx7aJvnl8ofKAOnS64B2O8bImBFaauRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/language-core": "2.4.14", + "path-browserify": "^1.0.1", + "vscode-uri": "^3.0.8" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.5.16", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.16.tgz", + "integrity": "sha512-AOQS2eaQOaaZQoL1u+2rCJIKDruNXVBZSiUD3chnUrsoX5ZTQMaCvXlWNIfxBJuU15r1o7+mpo5223KVtIhAgQ==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.27.2", + "@vue/shared": "3.5.16", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-core/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.16", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.16.tgz", + "integrity": "sha512-SSJIhBr/teipXiXjmWOVWLnxjNGo65Oj/8wTEQz0nqwQeP75jWZ0n4sF24Zxoht1cuJoWopwj0J0exYwCJ0dCQ==", + "license": "MIT", + "dependencies": { + "@vue/compiler-core": "3.5.16", + "@vue/shared": "3.5.16" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.5.16", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.16.tgz", + "integrity": "sha512-rQR6VSFNpiinDy/DVUE0vHoIDUF++6p910cgcZoaAUm3POxgNOOdS/xgoll3rNdKYTYPnnbARDCZOyZ+QSe6Pw==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.27.2", + "@vue/compiler-core": "3.5.16", + "@vue/compiler-dom": "3.5.16", + "@vue/compiler-ssr": "3.5.16", + "@vue/shared": "3.5.16", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.17", + "postcss": "^8.5.3", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-sfc/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.5.16", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.16.tgz", + "integrity": "sha512-d2V7kfxbdsjrDSGlJE7my1ZzCXViEcqN6w14DOsDrUCHEA6vbnVCpRFfrc4ryCP/lCKzX2eS1YtnLE/BuC9f/A==", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.16", + "@vue/shared": "3.5.16" + } + }, + "node_modules/@vue/compiler-vue2": { + "version": "2.7.16", + "resolved": "https://registry.npmjs.org/@vue/compiler-vue2/-/compiler-vue2-2.7.16.tgz", + "integrity": "sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==", + "dev": true, + "license": "MIT", + "dependencies": { + "de-indent": "^1.0.2", + "he": "^1.2.0" + } + }, + "node_modules/@vue/devtools-api": { + "version": "7.7.6", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.6.tgz", + "integrity": "sha512-b2Xx0KvXZObePpXPYHvBRRJLDQn5nhKjXh7vUhMEtWxz1AYNFOVIsh5+HLP8xDGL7sy+Q7hXeUxPHB/KgbtsPw==", + "license": "MIT", + "dependencies": { + "@vue/devtools-kit": "^7.7.6" + } + }, + "node_modules/@vue/devtools-kit": { + "version": "7.7.6", + "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.6.tgz", + "integrity": "sha512-geu7ds7tem2Y7Wz+WgbnbZ6T5eadOvozHZ23Atk/8tksHMFOFylKi1xgGlQlVn0wlkEf4hu+vd5ctj1G4kFtwA==", + "license": "MIT", + "dependencies": { + "@vue/devtools-shared": "^7.7.6", + "birpc": "^2.3.0", + "hookable": "^5.5.3", + "mitt": "^3.0.1", + "perfect-debounce": "^1.0.0", + "speakingurl": "^14.0.1", + "superjson": "^2.2.2" + } + }, + "node_modules/@vue/devtools-shared": { + "version": "7.7.6", + "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.6.tgz", + "integrity": "sha512-yFEgJZ/WblEsojQQceuyK6FzpFDx4kqrz2ohInxNj5/DnhoX023upTv4OD6lNPLAA5LLkbwPVb10o/7b+Y4FVA==", + "license": "MIT", + "dependencies": { + "rfdc": "^1.4.1" + } + }, + "node_modules/@vue/language-core": { + "version": "2.2.10", + "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-2.2.10.tgz", + "integrity": "sha512-+yNoYx6XIKuAO8Mqh1vGytu8jkFEOH5C8iOv3i8Z/65A7x9iAOXA97Q+PqZ3nlm2lxf5rOJuIGI/wDtx/riNYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/language-core": "~2.4.11", + "@vue/compiler-dom": "^3.5.0", + "@vue/compiler-vue2": "^2.7.16", + "@vue/shared": "^3.5.0", + "alien-signals": "^1.0.3", + "minimatch": "^9.0.3", + "muggle-string": "^0.4.1", + "path-browserify": "^1.0.1" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@vue/reactivity": { + "version": "3.5.16", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.16.tgz", + "integrity": "sha512-FG5Q5ee/kxhIm1p2bykPpPwqiUBV3kFySsHEQha5BJvjXdZTUfmya7wP7zC39dFuZAcf/PD5S4Lni55vGLMhvA==", + "license": "MIT", + "dependencies": { + "@vue/shared": "3.5.16" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.5.16", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.16.tgz", + "integrity": "sha512-bw5Ykq6+JFHYxrQa7Tjr+VSzw7Dj4ldR/udyBZbq73fCdJmyy5MPIFR9IX/M5Qs+TtTjuyUTCnmK3lWWwpAcFQ==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.16", + "@vue/shared": "3.5.16" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.5.16", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.16.tgz", + "integrity": "sha512-T1qqYJsG2xMGhImRUV9y/RseB9d0eCYZQ4CWca9ztCuiPj/XWNNN+lkNBuzVbia5z4/cgxdL28NoQCvC0Xcfww==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.16", + "@vue/runtime-core": "3.5.16", + "@vue/shared": "3.5.16", + "csstype": "^3.1.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.5.16", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.16.tgz", + "integrity": "sha512-BrX0qLiv/WugguGsnQUJiYOE0Fe5mZTwi6b7X/ybGB0vfrPH9z0gD/Y6WOR1sGCgX4gc25L1RYS5eYQKDMoNIg==", + "license": "MIT", + "dependencies": { + "@vue/compiler-ssr": "3.5.16", + "@vue/shared": "3.5.16" + }, + "peerDependencies": { + "vue": "3.5.16" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.16", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.16.tgz", + "integrity": "sha512-c/0fWy3Jw6Z8L9FmTyYfkpM5zklnqqa9+a6dz3DvONRKW2NEbh46BP0FHuLFSWi2TnQEtp91Z6zOWNrU6QiyPg==", + "license": "MIT" + }, + "node_modules/@vueuse/i18n": { + "version": "4.0.0-beta.12", + "resolved": "https://registry.npmjs.org/@vueuse/i18n/-/i18n-4.0.0-beta.12.tgz", + "integrity": "sha512-nRPfmmWxekoazrBDcO9UsqQTSC7xl8M5GxOv0KixCX0i6/knLDM/AL6l4C6fVy2sa4o20mHH4ue9p20i+ody9Q==", + "license": "MIT", + "dependencies": { + "vue-demi": "latest" + } + }, + "node_modules/@vueuse/i18n/node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/ace-builds": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.42.0.tgz", + "integrity": "sha512-nRDbpHguujCh9Lb00jtJAblR6d5JEi6RVrHtj+TAlUqRYwWl5Es7iHnyXUOmTcMfkzQ2/TPn45G/yvdQGa0ZXw==", + "license": "BSD-3-Clause" + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/alien-signals": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-1.0.13.tgz", + "integrity": "sha512-OGj9yyTnJEttvzhTUWuscOvtqxq5vrhF7vL9oS0xJ2mK0ItPYP1/y+vCFebfxoEyAz0++1AIwJ5CMr+Fk3nDmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ant-design-vue": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/ant-design-vue/-/ant-design-vue-4.2.6.tgz", + "integrity": "sha512-t7eX13Yj3i9+i5g9lqFyYneoIb3OzTvQjq9Tts1i+eiOd3Eva/6GagxBSXM1fOCjqemIu0FYVE1ByZ/38epR3Q==", + "license": "MIT", + "dependencies": { + "@ant-design/colors": "^6.0.0", + "@ant-design/icons-vue": "^7.0.0", + "@babel/runtime": "^7.10.5", + "@ctrl/tinycolor": "^3.5.0", + "@emotion/hash": "^0.9.0", + "@emotion/unitless": "^0.8.0", + "@simonwep/pickr": "~1.8.0", + "array-tree-filter": "^2.1.0", + "async-validator": "^4.0.0", + "csstype": "^3.1.1", + "dayjs": "^1.10.5", + "dom-align": "^1.12.1", + "dom-scroll-into-view": "^2.0.0", + "lodash": "^4.17.21", + "lodash-es": "^4.17.15", + "resize-observer-polyfill": "^1.5.1", + "scroll-into-view-if-needed": "^2.2.25", + "shallow-equal": "^1.0.0", + "stylis": "^4.1.3", + "throttle-debounce": "^5.0.0", + "vue-types": "^3.0.0", + "warning": "^4.0.0" + }, + "engines": { + "node": ">=12.22.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ant-design-vue" + }, + "peerDependencies": { + "vue": ">=3.2.0" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array-tree-filter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-tree-filter/-/array-tree-filter-2.1.0.tgz", + "integrity": "sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw==", + "license": "MIT" + }, + "node_modules/async-validator": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz", + "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==", + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz", + "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/birpc": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.3.0.tgz", + "integrity": "sha512-ijbtkn/F3Pvzb6jHypHRyve2QApOCZDR25D/VnkY2G/lBNcXCTsnsCxgY4k4PkVB7zfwzYbY3O9Lcqe3xufS5g==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/c12": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/c12/-/c12-3.0.4.tgz", + "integrity": "sha512-t5FaZTYbbCtvxuZq9xxIruYydrAGsJ+8UdP0pZzMiK2xl/gNiSOy0OxhLzHUEEb0m1QXYqfzfvyIFEmz/g9lqg==", + "license": "MIT", + "dependencies": { + "chokidar": "^4.0.3", + "confbox": "^0.2.2", + "defu": "^6.1.4", + "dotenv": "^16.5.0", + "exsolve": "^1.0.5", + "giget": "^2.0.0", + "jiti": "^2.4.2", + "ohash": "^2.0.11", + "pathe": "^2.0.3", + "perfect-debounce": "^1.0.0", + "pkg-types": "^2.1.0", + "rc9": "^2.1.2" + }, + "peerDependencies": { + "magicast": "^0.3.5" + }, + "peerDependenciesMeta": { + "magicast": { + "optional": true + } + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/citty": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/citty/-/citty-0.1.6.tgz", + "integrity": "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==", + "license": "MIT", + "dependencies": { + "consola": "^3.2.3" + } + }, + "node_modules/clipboard": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.11.tgz", + "integrity": "sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==", + "license": "MIT", + "dependencies": { + "good-listener": "^1.2.2", + "select": "^1.1.2", + "tiny-emitter": "^2.0.0" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/codemirror-wrapped-line-indent": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/codemirror-wrapped-line-indent/-/codemirror-wrapped-line-indent-1.0.9.tgz", + "integrity": "sha512-oc976hHLt35u6Ojbhub+IWOxEpapZSqYieLEdGhsgFZ4rtYQtdb5KjxzgjCCyVe3t0yk+a6hmaIOEsjU/tZRxQ==", + "license": "MIT", + "peerDependencies": { + "@codemirror/language": "^6.9.0", + "@codemirror/state": "^6.2.1", + "@codemirror/view": "^6.17.1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/compute-scroll-into-view": { + "version": "1.0.20", + "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz", + "integrity": "sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==", + "license": "MIT" + }, + "node_modules/confbox": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz", + "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==", + "license": "MIT" + }, + "node_modules/consola": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", + "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "node_modules/copy-anything": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz", + "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "is-what": "^3.14.1" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/core-js": { + "version": "3.43.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.43.0.tgz", + "integrity": "sha512-N6wEbTTZSYOY2rYAn85CuvWWkCK6QweMn7/4Nr3w+gDBeBhk/x4EJeY6FPo4QzDoJZxVTv8U7CMvgWk6pOHHqA==", + "hasInstallScript": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/crelt": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", + "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==", + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/dayjs": { + "version": "1.11.13", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", + "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==", + "license": "MIT" + }, + "node_modules/de-indent": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", + "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-pick-omit": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/deep-pick-omit/-/deep-pick-omit-1.2.1.tgz", + "integrity": "sha512-2J6Kc/m3irCeqVG42T+SaUMesaK7oGWaedGnQQK/+O0gYc+2SP5bKh/KKTE7d7SJ+GCA9UUE1GRzh6oDe0EnGw==", + "license": "MIT" + }, + "node_modules/defu": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", + "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", + "license": "MIT" + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/delegate": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", + "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==", + "license": "MIT" + }, + "node_modules/destr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.5.tgz", + "integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==", + "license": "MIT" + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/dom-align": { + "version": "1.12.4", + "resolved": "https://registry.npmjs.org/dom-align/-/dom-align-1.12.4.tgz", + "integrity": "sha512-R8LUSEay/68zE5c8/3BDxiTEvgb4xZTF0RKmAHfiEVN3klfIpXfi2/QCoiWPccVQ0J/ZGdz9OjzL4uJEP/MRAw==", + "license": "MIT" + }, + "node_modules/dom-scroll-into-view": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/dom-scroll-into-view/-/dom-scroll-into-view-2.0.1.tgz", + "integrity": "sha512-bvVTQe1lfaUr1oFzZX80ce9KLDlZ3iU+XGNE/bz9HnGdklTieqsbmsLHe+rT2XWqopvL0PckkYqN7ksmm5pe3w==", + "license": "MIT" + }, + "node_modules/dotenv": { + "version": "16.5.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.5.0.tgz", + "integrity": "sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/echarts": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/echarts/-/echarts-5.6.0.tgz", + "integrity": "sha512-oTbVTsXfKuEhxftHqL5xprgLoc0k7uScAwtryCgWF6hPYFLRwOUHiFmHGCBKP5NPFNkDVopOieyUqYGH8Fa3kA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "2.3.0", + "zrender": "5.6.1" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "license": "MIT", + "optional": true, + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/errx": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/errx/-/errx-0.1.0.tgz", + "integrity": "sha512-fZmsRiDNv07K6s2KkKFTiD2aIvECa7++PKyD5NC32tpRw46qZA3sOz+aM+/V9V0GDHxVTKLziveV4JhzBHDp9Q==", + "license": "MIT" + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz", + "integrity": "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.5", + "@esbuild/android-arm": "0.25.5", + "@esbuild/android-arm64": "0.25.5", + "@esbuild/android-x64": "0.25.5", + "@esbuild/darwin-arm64": "0.25.5", + "@esbuild/darwin-x64": "0.25.5", + "@esbuild/freebsd-arm64": "0.25.5", + "@esbuild/freebsd-x64": "0.25.5", + "@esbuild/linux-arm": "0.25.5", + "@esbuild/linux-arm64": "0.25.5", + "@esbuild/linux-ia32": "0.25.5", + "@esbuild/linux-loong64": "0.25.5", + "@esbuild/linux-mips64el": "0.25.5", + "@esbuild/linux-ppc64": "0.25.5", + "@esbuild/linux-riscv64": "0.25.5", + "@esbuild/linux-s390x": "0.25.5", + "@esbuild/linux-x64": "0.25.5", + "@esbuild/netbsd-arm64": "0.25.5", + "@esbuild/netbsd-x64": "0.25.5", + "@esbuild/openbsd-arm64": "0.25.5", + "@esbuild/openbsd-x64": "0.25.5", + "@esbuild/sunos-x64": "0.25.5", + "@esbuild/win32-arm64": "0.25.5", + "@esbuild/win32-ia32": "0.25.5", + "@esbuild/win32-x64": "0.25.5" + } + }, + "node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/esm-env": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz", + "integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==", + "license": "MIT" + }, + "node_modules/esrap": { + "version": "1.4.9", + "resolved": "https://registry.npmjs.org/esrap/-/esrap-1.4.9.tgz", + "integrity": "sha512-3OMlcd0a03UGuZpPeUC1HxR3nA23l+HEyCiZw3b3FumJIN9KphoGzDJKMXI1S72jVS1dsenDyQC0kJlO1U9E1g==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/event-source-polyfill": { + "version": "1.0.31", + "resolved": "https://registry.npmjs.org/event-source-polyfill/-/event-source-polyfill-1.0.31.tgz", + "integrity": "sha512-4IJSItgS/41IxN5UVAVuAyczwZF7ZIEsM1XAoUzIHA6A+xzusEZUutdXz2Nr+MQPLxfTiCvqE79/C8HT8fKFvA==", + "license": "MIT" + }, + "node_modules/exsolve": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.5.tgz", + "integrity": "sha512-pz5dvkYYKQ1AHVrgOzBKWeP4u4FRb3a6DNK2ucr0OoNwYIU4QWsJ+NM36LLzORT+z845MzKHHhpXiUF5nvQoJg==", + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fdir": { + "version": "6.4.5", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.5.tgz", + "integrity": "sha512-4BG7puHpVsIYxZUbiUE3RqGloLaSSwzYie5jvasC4LWuBWzZawynvYouhjbQKw2JuIGYdm0DzIxl8iVidKlUEw==", + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz", + "integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/giget": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/giget/-/giget-2.0.0.tgz", + "integrity": "sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==", + "license": "MIT", + "dependencies": { + "citty": "^0.1.6", + "consola": "^3.4.0", + "defu": "^6.1.4", + "node-fetch-native": "^1.6.6", + "nypm": "^0.6.0", + "pathe": "^2.0.3" + }, + "bin": { + "giget": "dist/cli.mjs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/good-listener": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", + "integrity": "sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==", + "license": "MIT", + "dependencies": { + "delegate": "^3.1.2" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/highlight.js": { + "version": "11.11.1", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz", + "integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/hookable": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz", + "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==", + "license": "MIT" + }, + "node_modules/http": { + "version": "0.0.1-security", + "resolved": "https://registry.npmjs.org/http/-/http-0.0.1-security.tgz", + "integrity": "sha512-RnDvP10Ty9FxqOtPZuxtebw1j4L/WiqNMDtuc1YMH1XQm5TgDRaR1G9u8upL6KD1bXHSp9eSXo/ED+8Q7FAr+g==" + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/image-size": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", + "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==", + "license": "MIT", + "optional": true, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/immutable-json-patch": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/immutable-json-patch/-/immutable-json-patch-6.0.1.tgz", + "integrity": "sha512-BHL/cXMjwFZlTOffiWNdY8ZTvNyYLrutCnWxrcKPHr5FqpAb6vsO6WWSPnVSys3+DruFN6lhHJJPHi8uELQL5g==", + "license": "ISC" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-object": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.1.tgz", + "integrity": "sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-reference": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz", + "integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.6" + } + }, + "node_modules/is-what": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", + "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/javascript-natural-sort": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", + "integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==", + "license": "MIT" + }, + "node_modules/jiti": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", + "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/jmespath": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", + "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/js-cookie": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", + "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "license": "MIT" + }, + "node_modules/jsep": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.4.0.tgz", + "integrity": "sha512-B7qPcEVE3NVkmSJbaYxvv4cHkVW7DQsZz13pUMrfS8z8Q/BuShN+gcTXrUlPiGqM2/t/EEaI030bpxMqY8gMlw==", + "license": "MIT", + "engines": { + "node": ">= 10.16.0" + } + }, + "node_modules/json-editor-vue": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/json-editor-vue/-/json-editor-vue-0.18.1.tgz", + "integrity": "sha512-SQCtNngo/ScFjXC7KUOqLOeeLgvl+xwWbxfNelqIOHC6uLilQl7AlWzNJyrDqo+RWnc53nT0OngXki5uTx9SJg==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "vanilla-jsoneditor": "^3.0.0", + "vue-demi": "^0.14.10" + }, + "peerDependencies": { + "@vue/composition-api": ">=1", + "vue": "2||3" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/json-editor-vue/node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "license": "MIT" + }, + "node_modules/json-source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/json-source-map/-/json-source-map-0.6.1.tgz", + "integrity": "sha512-1QoztHPsMQqhDq0hlXY5ZqcEdUzxQEIxgFkKl4WUp2pgShObl+9ovi4kRh2TfvAfxAoHOJ9vIMEqk3k4iex7tg==", + "license": "MIT" + }, + "node_modules/jsoneditor": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/jsoneditor/-/jsoneditor-10.2.0.tgz", + "integrity": "sha512-vwXKAUYQ0EFBUWTq2+wl9fi+rf4K4f/xdw6nyJdlXeQ374/NnaBobYmZUosuv9nMMPRP4KbfUGhZ3GH1l4QZqg==", + "license": "Apache-2.0", + "dependencies": { + "ace-builds": "^1.36.2", + "ajv": "^6.12.6", + "javascript-natural-sort": "^0.7.1", + "jmespath": "^0.16.0", + "json-source-map": "^0.6.1", + "jsonrepair": "^3.8.1", + "picomodal": "^3.0.0", + "vanilla-picker": "^2.12.3" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonpath-plus": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-10.3.0.tgz", + "integrity": "sha512-8TNmfeTCk2Le33A3vRRwtuworG/L5RrgMvdjhKZxvyShO+mBu2fP50OWUjRLNtvw344DdDarFh9buFAZs5ujeA==", + "license": "MIT", + "dependencies": { + "@jsep-plugin/assignment": "^1.3.0", + "@jsep-plugin/regex": "^1.0.4", + "jsep": "^1.4.0" + }, + "bin": { + "jsonpath": "bin/jsonpath-cli.js", + "jsonpath-plus": "bin/jsonpath-cli.js" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/jsonrepair": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/jsonrepair/-/jsonrepair-3.12.0.tgz", + "integrity": "sha512-SWfjz8SuQ0wZjwsxtSJ3Zy8vvLg6aO/kxcp9TWNPGwJKgTZVfhNEQBMk/vPOpYCDFWRxD6QWuI6IHR1t615f0w==", + "license": "ISC", + "bin": { + "jsonrepair": "bin/cli.js" + } + }, + "node_modules/klona": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", + "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/knitwork": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/knitwork/-/knitwork-1.2.0.tgz", + "integrity": "sha512-xYSH7AvuQ6nXkq42x0v5S8/Iry+cfulBz/DJQzhIyESdLD7425jXsPy4vn5cCXU+HhRN2kVw51Vd1K6/By4BQg==", + "license": "MIT" + }, + "node_modules/less": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/less/-/less-4.3.0.tgz", + "integrity": "sha512-X9RyH9fvemArzfdP8Pi3irr7lor2Ok4rOttDXBhlwDg+wKQsXOXgHWduAJE1EsF7JJx0w0bcO6BC6tCKKYnXKA==", + "devOptional": true, + "license": "Apache-2.0", + "dependencies": { + "copy-anything": "^2.0.1", + "parse-node-version": "^1.0.1", + "tslib": "^2.3.0" + }, + "bin": { + "lessc": "bin/lessc" + }, + "engines": { + "node": ">=14" + }, + "optionalDependencies": { + "errno": "^0.1.1", + "graceful-fs": "^4.1.2", + "image-size": "~0.5.0", + "make-dir": "^2.1.0", + "mime": "^1.4.1", + "needle": "^3.1.0", + "source-map": "~0.6.0" + } + }, + "node_modules/less-loader": { + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-12.3.0.tgz", + "integrity": "sha512-0M6+uYulvYIWs52y0LqN4+QM9TqWAohYSNTo4htE8Z7Cn3G/qQMEmktfHmyJT23k+20kU9zHH2wrfFXkxNLtVw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "less": "^3.5.0 || ^4.0.0", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/local-pkg": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.1.tgz", + "integrity": "sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==", + "license": "MIT", + "dependencies": { + "mlly": "^1.7.4", + "pkg-types": "^2.0.1", + "quansync": "^0.2.8" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/locate-character": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", + "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", + "license": "MIT" + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/loose-envify/node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "license": "MIT", + "optional": true, + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/marked": { + "version": "15.0.12", + "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.12.tgz", + "integrity": "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/memoize-one": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", + "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==", + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", + "optional": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "license": "MIT" + }, + "node_modules/mlly": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz", + "integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==", + "license": "MIT", + "dependencies": { + "acorn": "^8.14.0", + "pathe": "^2.0.1", + "pkg-types": "^1.3.0", + "ufo": "^1.5.4" + } + }, + "node_modules/mlly/node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "license": "MIT" + }, + "node_modules/mlly/node_modules/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/muggle-string": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz", + "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/nanopop": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/nanopop/-/nanopop-2.4.2.tgz", + "integrity": "sha512-NzOgmMQ+elxxHeIha+OG/Pv3Oc3p4RU2aBhwWwAqDpXrdTbtRylbRLQztLy8dMMwfl6pclznBdfUhccEn9ZIzw==", + "license": "MIT" + }, + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "license": "MIT" + }, + "node_modules/needle": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/needle/-/needle-3.3.1.tgz", + "integrity": "sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==", + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.3", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "node_modules/node-fetch-native": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.6.tgz", + "integrity": "sha512-8Mc2HhqPdlIfedsuZoc3yioPuzp6b+L5jRCRY1QzuWZh2EGJVQrGppC6V6cF0bLdbW0+O2YpqCA25aF/1lvipQ==", + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nypm": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.6.0.tgz", + "integrity": "sha512-mn8wBFV9G9+UFHIrq+pZ2r2zL4aPau/by3kJb3cM7+5tQHMt6HGQB8FDIeKFYp8o0D2pnH6nVsO88N4AmUxIWg==", + "license": "MIT", + "dependencies": { + "citty": "^0.1.6", + "consola": "^3.4.0", + "pathe": "^2.0.3", + "pkg-types": "^2.0.0", + "tinyexec": "^0.3.2" + }, + "bin": { + "nypm": "dist/cli.mjs" + }, + "engines": { + "node": "^14.16.0 || >=16.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ohash": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz", + "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", + "license": "MIT" + }, + "node_modules/parse-node-version": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "license": "MIT" + }, + "node_modules/perfect-debounce": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", + "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/picomodal": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/picomodal/-/picomodal-3.0.0.tgz", + "integrity": "sha512-FoR3TDfuLlqUvcEeK5ifpKSVVns6B4BQvc8SDF6THVMuadya6LLtji0QgUDSStw0ZR2J7I6UGi5V2V23rnPWTw==", + "license": "MIT" + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pinia": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pinia/-/pinia-3.0.3.tgz", + "integrity": "sha512-ttXO/InUULUXkMHpTdp9Fj4hLpD/2AoJdmAbAeW2yu1iy1k+pkFekQXw5VpC0/5p51IOR/jDaDRfRWRnMMsGOA==", + "license": "MIT", + "dependencies": { + "@vue/devtools-api": "^7.7.2" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "typescript": ">=4.4.4", + "vue": "^2.7.0 || ^3.5.11" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/pinia-plugin-persistedstate": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/pinia-plugin-persistedstate/-/pinia-plugin-persistedstate-4.3.0.tgz", + "integrity": "sha512-x9wxpHj6iFDj5ITQJ3rj6+KesEqyRk/vqcE3WE+VGfetleV9Zufqwa9qJ6AkA5wmRSQEp7BTA1us/MDVTRHFFw==", + "license": "MIT", + "dependencies": { + "@nuxt/kit": "^3.17.2", + "deep-pick-omit": "^1.2.1", + "defu": "^6.1.4", + "destr": "^2.0.5" + }, + "peerDependencies": { + "@pinia/nuxt": ">=0.10.0", + "pinia": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@pinia/nuxt": { + "optional": true + }, + "pinia": { + "optional": true + } + } + }, + "node_modules/pkg-types": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.1.0.tgz", + "integrity": "sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==", + "license": "MIT", + "dependencies": { + "confbox": "^0.2.1", + "exsolve": "^1.0.1", + "pathe": "^2.0.3" + } + }, + "node_modules/postcss": { + "version": "8.5.4", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.4.tgz", + "integrity": "sha512-QSa9EBe+uwlGTFmHsPKokv3B/oEMQZxfqW0QqNCyhpa6mB1afzulwn8hihglqAb2pOw+BJgNlmXQ8la2VeHB7w==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "license": "MIT", + "optional": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", + "license": "MIT", + "optional": true + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/quansync": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.10.tgz", + "integrity": "sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/antfu" + }, + { + "type": "individual", + "url": "https://github.com/sponsors/sxzz" + } + ], + "license": "MIT" + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/rc9": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/rc9/-/rc9-2.1.2.tgz", + "integrity": "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==", + "license": "MIT", + "dependencies": { + "defu": "^6.1.4", + "destr": "^2.0.3" + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==", + "license": "MIT" + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "license": "MIT" + }, + "node_modules/rollup": { + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.42.0.tgz", + "integrity": "sha512-LW+Vse3BJPyGJGAJt1j8pWDKPd73QM8cRXYK1IxOBgL2AGLu7Xd2YOW0M2sLUBCkF5MshXXtMApyEAEzMVMsnw==", + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.7" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.42.0", + "@rollup/rollup-android-arm64": "4.42.0", + "@rollup/rollup-darwin-arm64": "4.42.0", + "@rollup/rollup-darwin-x64": "4.42.0", + "@rollup/rollup-freebsd-arm64": "4.42.0", + "@rollup/rollup-freebsd-x64": "4.42.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.42.0", + "@rollup/rollup-linux-arm-musleabihf": "4.42.0", + "@rollup/rollup-linux-arm64-gnu": "4.42.0", + "@rollup/rollup-linux-arm64-musl": "4.42.0", + "@rollup/rollup-linux-loongarch64-gnu": "4.42.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.42.0", + "@rollup/rollup-linux-riscv64-gnu": "4.42.0", + "@rollup/rollup-linux-riscv64-musl": "4.42.0", + "@rollup/rollup-linux-s390x-gnu": "4.42.0", + "@rollup/rollup-linux-x64-gnu": "4.42.0", + "@rollup/rollup-linux-x64-musl": "4.42.0", + "@rollup/rollup-win32-arm64-msvc": "4.42.0", + "@rollup/rollup-win32-ia32-msvc": "4.42.0", + "@rollup/rollup-win32-x64-msvc": "4.42.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup/node_modules/@types/estree": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", + "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", + "license": "MIT" + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT", + "optional": true + }, + "node_modules/sax": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", + "license": "ISC", + "optional": true + }, + "node_modules/scroll-into-view-if-needed": { + "version": "2.2.31", + "resolved": "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.31.tgz", + "integrity": "sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==", + "license": "MIT", + "dependencies": { + "compute-scroll-into-view": "^1.0.20" + } + }, + "node_modules/scule": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/scule/-/scule-1.3.0.tgz", + "integrity": "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==", + "license": "MIT" + }, + "node_modules/select": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", + "integrity": "sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/shallow-equal": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz", + "integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==", + "license": "MIT" + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/speakingurl": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz", + "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/std-env": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz", + "integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==", + "license": "MIT" + }, + "node_modules/strip-literal": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.0.0.tgz", + "integrity": "sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==", + "license": "MIT", + "dependencies": { + "js-tokens": "^9.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/style-mod": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz", + "integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==", + "license": "MIT" + }, + "node_modules/stylis": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.6.tgz", + "integrity": "sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==", + "license": "MIT" + }, + "node_modules/superjson": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.2.tgz", + "integrity": "sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==", + "license": "MIT", + "dependencies": { + "copy-anything": "^3.0.2" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/superjson/node_modules/copy-anything": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz", + "integrity": "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==", + "license": "MIT", + "dependencies": { + "is-what": "^4.1.8" + }, + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/superjson/node_modules/is-what": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz", + "integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==", + "license": "MIT", + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/svelte": { + "version": "5.33.18", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.33.18.tgz", + "integrity": "sha512-GVAhi8vi8pGne/wlEdnfWIJvSR9eKvEknxjfL5Sr8gQALiyk8Ey+H0lhUYLpjW+MrqgH9h4dgh2NF6/BTFprRg==", + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.3.0", + "@jridgewell/sourcemap-codec": "^1.5.0", + "@sveltejs/acorn-typescript": "^1.0.5", + "@types/estree": "^1.0.5", + "acorn": "^8.12.1", + "aria-query": "^5.3.1", + "axobject-query": "^4.1.0", + "clsx": "^2.1.1", + "esm-env": "^1.2.1", + "esrap": "^1.4.8", + "is-reference": "^3.0.3", + "locate-character": "^3.0.0", + "magic-string": "^0.30.11", + "zimmerframe": "^1.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/throttle-debounce": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-5.0.2.tgz", + "integrity": "sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==", + "license": "MIT", + "engines": { + "node": ">=12.22" + } + }, + "node_modules/tiny-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", + "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", + "license": "MIT", + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", + "license": "0BSD" + }, + "node_modules/typescript": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "devOptional": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz", + "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", + "license": "MIT" + }, + "node_modules/unctx": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/unctx/-/unctx-2.4.1.tgz", + "integrity": "sha512-AbaYw0Nm4mK4qjhns67C+kgxR2YWiwlDBPzxrN8h8C6VtAdCgditAY5Dezu3IJy4XVqAnbrXt9oQJvsn3fyozg==", + "license": "MIT", + "dependencies": { + "acorn": "^8.14.0", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.17", + "unplugin": "^2.1.0" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/unimport": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/unimport/-/unimport-5.0.1.tgz", + "integrity": "sha512-1YWzPj6wYhtwHE+9LxRlyqP4DiRrhGfJxdtH475im8ktyZXO3jHj/3PZ97zDdvkYoovFdi0K4SKl3a7l92v3sQ==", + "license": "MIT", + "dependencies": { + "acorn": "^8.14.1", + "escape-string-regexp": "^5.0.0", + "estree-walker": "^3.0.3", + "local-pkg": "^1.1.1", + "magic-string": "^0.30.17", + "mlly": "^1.7.4", + "pathe": "^2.0.3", + "picomatch": "^4.0.2", + "pkg-types": "^2.1.0", + "scule": "^1.3.0", + "strip-literal": "^3.0.0", + "tinyglobby": "^0.2.13", + "unplugin": "^2.3.2", + "unplugin-utils": "^0.2.4" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unplugin": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-2.3.5.tgz", + "integrity": "sha512-RyWSb5AHmGtjjNQ6gIlA67sHOsWpsbWpwDokLwTcejVdOjEkJZh7QKu14J00gDDVSh8kGH4KYC/TNBceXFZhtw==", + "license": "MIT", + "dependencies": { + "acorn": "^8.14.1", + "picomatch": "^4.0.2", + "webpack-virtual-modules": "^0.6.2" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/unplugin-auto-import": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/unplugin-auto-import/-/unplugin-auto-import-0.19.0.tgz", + "integrity": "sha512-W97gTDEWu/L1EcKCXY5Ni8bsMW1E9kv12wYQv3mYpd7zcFctXYlLKsqeva6sbCQbzS8t9AG/XdU5/WkEJKPlFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@antfu/utils": "^0.7.10", + "@rollup/pluginutils": "^5.1.3", + "local-pkg": "^0.5.1", + "magic-string": "^0.30.15", + "picomatch": "^4.0.2", + "unimport": "^3.14.5", + "unplugin": "^2.1.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@nuxt/kit": "^3.2.2", + "@vueuse/core": "*" + }, + "peerDependenciesMeta": { + "@nuxt/kit": { + "optional": true + }, + "@vueuse/core": { + "optional": true + } + } + }, + "node_modules/unplugin-auto-import/node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/unplugin-auto-import/node_modules/local-pkg": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.1.tgz", + "integrity": "sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mlly": "^1.7.3", + "pkg-types": "^1.2.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/unplugin-auto-import/node_modules/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, + "node_modules/unplugin-auto-import/node_modules/strip-literal": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.1.tgz", + "integrity": "sha512-631UJ6O00eNGfMiWG78ck80dfBab8X6IVFB51jZK5Icd7XAs60Z5y7QdSd/wGIklnWvRbUNloVzhOKKmutxQ6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^9.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/unplugin-auto-import/node_modules/unimport": { + "version": "3.14.6", + "resolved": "https://registry.npmjs.org/unimport/-/unimport-3.14.6.tgz", + "integrity": "sha512-CYvbDaTT04Rh8bmD8jz3WPmHYZRG/NnvYVzwD6V1YAlvvKROlAeNDUBhkBGzNav2RKaeuXvlWYaa1V4Lfi/O0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.1.4", + "acorn": "^8.14.0", + "escape-string-regexp": "^5.0.0", + "estree-walker": "^3.0.3", + "fast-glob": "^3.3.3", + "local-pkg": "^1.0.0", + "magic-string": "^0.30.17", + "mlly": "^1.7.4", + "pathe": "^2.0.1", + "picomatch": "^4.0.2", + "pkg-types": "^1.3.0", + "scule": "^1.3.0", + "strip-literal": "^2.1.1", + "unplugin": "^1.16.1" + } + }, + "node_modules/unplugin-auto-import/node_modules/unimport/node_modules/confbox": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz", + "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/unplugin-auto-import/node_modules/unimport/node_modules/local-pkg": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.1.tgz", + "integrity": "sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mlly": "^1.7.4", + "pkg-types": "^2.0.1", + "quansync": "^0.2.8" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/unplugin-auto-import/node_modules/unimport/node_modules/local-pkg/node_modules/pkg-types": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.1.0.tgz", + "integrity": "sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "confbox": "^0.2.1", + "exsolve": "^1.0.1", + "pathe": "^2.0.3" + } + }, + "node_modules/unplugin-auto-import/node_modules/unimport/node_modules/unplugin": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.16.1.tgz", + "integrity": "sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.14.0", + "webpack-virtual-modules": "^0.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/unplugin-utils": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/unplugin-utils/-/unplugin-utils-0.2.4.tgz", + "integrity": "sha512-8U/MtpkPkkk3Atewj1+RcKIjb5WBimZ/WSLhhR3w6SsIj8XJuKTacSP8g+2JhfSGw0Cb125Y+2zA/IzJZDVbhA==", + "license": "MIT", + "dependencies": { + "pathe": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=18.12.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + } + }, + "node_modules/unplugin-vue-components": { + "version": "0.27.5", + "resolved": "https://registry.npmjs.org/unplugin-vue-components/-/unplugin-vue-components-0.27.5.tgz", + "integrity": "sha512-m9j4goBeNwXyNN8oZHHxvIIYiG8FQ9UfmKWeNllpDvhU7btKNNELGPt+o3mckQKuPwrE7e0PvCsx+IWuDSD9Vg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@antfu/utils": "^0.7.10", + "@rollup/pluginutils": "^5.1.3", + "chokidar": "^3.6.0", + "debug": "^4.3.7", + "fast-glob": "^3.3.2", + "local-pkg": "^0.5.1", + "magic-string": "^0.30.14", + "minimatch": "^9.0.5", + "mlly": "^1.7.3", + "unplugin": "^1.16.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@babel/parser": "^7.15.8", + "@nuxt/kit": "^3.2.2", + "vue": "2 || 3" + }, + "peerDependenciesMeta": { + "@babel/parser": { + "optional": true + }, + "@nuxt/kit": { + "optional": true + } + } + }, + "node_modules/unplugin-vue-components/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/unplugin-vue-components/node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/unplugin-vue-components/node_modules/local-pkg": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.1.tgz", + "integrity": "sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mlly": "^1.7.3", + "pkg-types": "^1.2.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/unplugin-vue-components/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/unplugin-vue-components/node_modules/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, + "node_modules/unplugin-vue-components/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/unplugin-vue-components/node_modules/unplugin": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.16.1.tgz", + "integrity": "sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.14.0", + "webpack-virtual-modules": "^0.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/untyped": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/untyped/-/untyped-2.0.0.tgz", + "integrity": "sha512-nwNCjxJTjNuLCgFr42fEak5OcLuB3ecca+9ksPFNvtfYSLpjf+iJqSIaSnIile6ZPbKYxI5k2AfXqeopGudK/g==", + "license": "MIT", + "dependencies": { + "citty": "^0.1.6", + "defu": "^6.1.4", + "jiti": "^2.4.2", + "knitwork": "^1.2.0", + "scule": "^1.3.0" + }, + "bin": { + "untyped": "dist/cli.mjs" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/vanilla-jsoneditor": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/vanilla-jsoneditor/-/vanilla-jsoneditor-3.5.0.tgz", + "integrity": "sha512-BLr3AajXQAMQ1cPTW5yT8k3sBQ89b/YMlE5AX1toE36vqPJEAZTj6ZXtD8CeBpNaC1W0DWgZQDI9MzeAPORR1g==", + "license": "ISC", + "dependencies": { + "@codemirror/autocomplete": "^6.18.1", + "@codemirror/commands": "^6.7.1", + "@codemirror/lang-json": "^6.0.1", + "@codemirror/language": "^6.10.3", + "@codemirror/lint": "^6.8.2", + "@codemirror/search": "^6.5.6", + "@codemirror/state": "^6.4.1", + "@codemirror/view": "^6.34.1", + "@fortawesome/free-regular-svg-icons": "^6.6.0", + "@fortawesome/free-solid-svg-icons": "^6.6.0", + "@jsonquerylang/jsonquery": "^3.1.1 || ^4.0.0 || ^5.0.0", + "@lezer/highlight": "^1.2.1", + "@replit/codemirror-indentation-markers": "^6.5.3", + "ajv": "^8.17.1", + "codemirror-wrapped-line-indent": "^1.0.8", + "diff-sequences": "^29.6.3", + "immutable-json-patch": "^6.0.1", + "jmespath": "^0.16.0", + "json-source-map": "^0.6.1", + "jsonpath-plus": "^10.3.0", + "jsonrepair": "^3.0.0", + "lodash-es": "^4.17.21", + "memoize-one": "^6.0.0", + "natural-compare-lite": "^1.4.0", + "svelte": "^5.0.0", + "vanilla-picker": "^2.12.3" + } + }, + "node_modules/vanilla-jsoneditor/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/vanilla-jsoneditor/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/vanilla-picker": { + "version": "2.12.3", + "resolved": "https://registry.npmjs.org/vanilla-picker/-/vanilla-picker-2.12.3.tgz", + "integrity": "sha512-qVkT1E7yMbUsB2mmJNFmaXMWE2hF8ffqzMMwe9zdAikd8u2VfnsVY2HQcOUi2F38bgbxzlJBEdS1UUhOXdF9GQ==", + "license": "ISC", + "dependencies": { + "@sphinxxxx/color-conversion": "^2.2.2" + } + }, + "node_modules/vite": { + "version": "6.3.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz", + "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==", + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite-plugin-compression": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/vite-plugin-compression/-/vite-plugin-compression-0.5.1.tgz", + "integrity": "sha512-5QJKBDc+gNYVqL/skgFAP81Yuzo9R+EAf19d+EtsMF/i8kFUpNi3J/H01QD3Oo8zBQn+NzoCIFkpPLynoOzaJg==", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "debug": "^4.3.3", + "fs-extra": "^10.0.0" + }, + "peerDependencies": { + "vite": ">=2.0.0" + } + }, + "node_modules/vscode-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz", + "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/vue": { + "version": "3.5.16", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.16.tgz", + "integrity": "sha512-rjOV2ecxMd5SiAmof2xzh2WxntRcigkX/He4YFJ6WdRvVUrbt6DxC1Iujh10XLl8xCDRDtGKMeO3D+pRQ1PP9w==", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.16", + "@vue/compiler-sfc": "3.5.16", + "@vue/runtime-dom": "3.5.16", + "@vue/server-renderer": "3.5.16", + "@vue/shared": "3.5.16" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/vue-demi": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz", + "integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/vue-echarts": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/vue-echarts/-/vue-echarts-7.0.3.tgz", + "integrity": "sha512-/jSxNwOsw5+dYAUcwSfkLwKPuzTQ0Cepz1LxCOpj2QcHrrmUa/Ql0eQqMmc1rTPQVrh2JQ29n2dhq75ZcHvRDw==", + "license": "MIT", + "dependencies": { + "vue-demi": "^0.13.11" + }, + "peerDependencies": { + "@vue/runtime-core": "^3.0.0", + "echarts": "^5.5.1", + "vue": "^2.7.0 || ^3.1.1" + }, + "peerDependenciesMeta": { + "@vue/runtime-core": { + "optional": true + } + } + }, + "node_modules/vue-i18n": { + "version": "10.0.7", + "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-10.0.7.tgz", + "integrity": "sha512-bKsk0PYwP9gdYF4nqSAT0kDpnLu1gZzlxFl885VH4mHVhEnqP16+/mAU05r1U6NIrc0fGDWP89tZ8GzeJZpe+w==", + "license": "MIT", + "dependencies": { + "@intlify/core-base": "10.0.7", + "@intlify/shared": "10.0.7", + "@vue/devtools-api": "^6.5.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/kazupon" + }, + "peerDependencies": { + "vue": "^3.0.0" + } + }, + "node_modules/vue-i18n/node_modules/@vue/devtools-api": { + "version": "6.6.4", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz", + "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", + "license": "MIT" + }, + "node_modules/vue-json-editor": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/vue-json-editor/-/vue-json-editor-1.4.3.tgz", + "integrity": "sha512-st9HdXBgCnyEmmfWrZQiKzp4KuYXzmYVUNDn5h6Fa18MrrGS1amnyUFyv7hQFsNBDW27B7BKkdGOqszYT1srAg==", + "license": "ISC", + "dependencies": { + "vue": "^2.2.6" + }, + "engines": { + "node": ">= 4.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/vue-json-editor/node_modules/@vue/compiler-sfc": { + "version": "2.7.16", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-2.7.16.tgz", + "integrity": "sha512-KWhJ9k5nXuNtygPU7+t1rX6baZeqOYLEforUPjgNDBnLicfHCoi48H87Q8XyLZOrNNsmhuwKqtpDQWjEFe6Ekg==", + "dependencies": { + "@babel/parser": "^7.23.5", + "postcss": "^8.4.14", + "source-map": "^0.6.1" + }, + "optionalDependencies": { + "prettier": "^1.18.2 || ^2.0.0" + } + }, + "node_modules/vue-json-editor/node_modules/vue": { + "version": "2.7.16", + "resolved": "https://registry.npmjs.org/vue/-/vue-2.7.16.tgz", + "integrity": "sha512-4gCtFXaAA3zYZdTp5s4Hl2sozuySsgz4jy1EnpBHNfpMa9dK1ZCG7viqBPCwXtmgc8nHqUsAu3G4gtmXkkY3Sw==", + "deprecated": "Vue 2 has reached EOL and is no longer actively maintained. See https://v2.vuejs.org/eol/ for more details.", + "license": "MIT", + "dependencies": { + "@vue/compiler-sfc": "2.7.16", + "csstype": "^3.1.0" + } + }, + "node_modules/vue-json-pretty": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/vue-json-pretty/-/vue-json-pretty-2.4.0.tgz", + "integrity": "sha512-e9bP41DYYIc2tWaB6KuwqFJq5odZ8/GkE6vHQuGcbPn37kGk4a3n1RNw3ZYeDrl66NWXgTlOfS+M6NKkowmkWw==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0", + "npm": ">= 5.0.0" + }, + "peerDependencies": { + "vue": ">=3.0.0" + } + }, + "node_modules/vue-router": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.5.1.tgz", + "integrity": "sha512-ogAF3P97NPm8fJsE4by9dwSYtDwXIY1nFY9T6DyQnGHd1E2Da94w9JIolpe42LJGIl0DwOHBi8TcRPlPGwbTtw==", + "license": "MIT", + "dependencies": { + "@vue/devtools-api": "^6.6.4" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "vue": "^3.2.0" + } + }, + "node_modules/vue-router/node_modules/@vue/devtools-api": { + "version": "6.6.4", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz", + "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", + "license": "MIT" + }, + "node_modules/vue-tsc": { + "version": "2.2.10", + "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-2.2.10.tgz", + "integrity": "sha512-jWZ1xSaNbabEV3whpIDMbjVSVawjAyW+x1n3JeGQo7S0uv2n9F/JMgWW90tGWNFRKya4YwKMZgCtr0vRAM7DeQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/typescript": "~2.4.11", + "@vue/language-core": "2.2.10" + }, + "bin": { + "vue-tsc": "bin/vue-tsc.js" + }, + "peerDependencies": { + "typescript": ">=5.0.0" + } + }, + "node_modules/vue-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vue-types/-/vue-types-3.0.2.tgz", + "integrity": "sha512-IwUC0Aq2zwaXqy74h4WCvFCUtoV0iSWr0snWnE9TnU18S66GAQyqQbRf2qfJtUuiFsBf6qp0MEwdonlwznlcrw==", + "license": "MIT", + "dependencies": { + "is-plain-object": "3.0.1" + }, + "engines": { + "node": ">=10.15.0" + }, + "peerDependencies": { + "vue": "^3.0.0" + } + }, + "node_modules/w3c-keyname": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", + "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==", + "license": "MIT" + }, + "node_modules/warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/webpack-virtual-modules": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", + "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", + "license": "MIT" + }, + "node_modules/ws": { + "version": "8.18.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz", + "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/zimmerframe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.2.tgz", + "integrity": "sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==", + "license": "MIT" + }, + "node_modules/zrender": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/zrender/-/zrender-5.6.1.tgz", + "integrity": "sha512-OFXkDJKcrlx5su2XbzJvj/34Q3m6PvyCZkVPHGYpcCJ52ek4U/ymZyfuV1nKE23AyBJ51E/6Yr0mhZ7xGTO4ag==", + "license": "BSD-3-Clause", + "dependencies": { + "tslib": "2.3.0" + } + } + } +} diff --git a/evals/evaluation/rag_pilot/ui/package.json b/evals/evaluation/rag_pilot/ui/package.json new file mode 100644 index 00000000..34eaba78 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/package.json @@ -0,0 +1,59 @@ +{ + "name": "rag-pilot-ui", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "dependencies": { + "@vueuse/i18n": "^4.0.0-beta.12", + "ant-design-vue": "^4.0.0-rc.6", + "axios": "^1.7.9", + "clipboard": "^2.0.11", + "echarts": "^5.6.0", + "event-source-polyfill": "^1.0.31", + "http": "^0.0.1-security", + "highlight.js": "^11.11.1", + "js-cookie": "^3.0.5", + "json-editor-vue": "^0.18.1", + "jsoneditor": "^10.2.0", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "marked": "^15.0.6", + "pinia": "^3.0.2", + "pinia-plugin-persistedstate": "^4.2.0", + "qs": "^6.13.1", + "vite-plugin-compression": "^0.5.1", + "vue": "^3.5.13", + "vue-echarts": "^7.0.3", + "vue-i18n": "^10.0.5", + "vue-json-editor": "^1.4.3", + "vue-json-pretty": "^2.4.0", + "vue-router": "^4.5.0", + "ws": "^8.18.0" + }, + "devDependencies": { + "@types/eventsource": "^1.1.15", + "@types/js-cookie": "^3.0.6", + "@types/jsoneditor": "^9.9.5", + "@types/lodash-es": "^4.17.12", + "@types/marked": "^5.0.2", + "@types/node": "^22.10.2", + "@vitejs/plugin-vue": "^5.2.1", + "less": "^4.2.1", + "less-loader": "^12.2.0", + "typescript": "~5.6.2", + "unplugin-auto-import": "^0.19.0", + "unplugin-vue-components": "^0.27.5", + "vite": "^6.0.1", + "vue-tsc": "^2.1.10" + }, + "description": "This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 ` + diff --git a/evals/evaluation/rag_pilot/ui/src/api/ragPilot/index.ts b/evals/evaluation/rag_pilot/ui/src/api/ragPilot/index.ts new file mode 100644 index 00000000..c64d7c61 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/api/ragPilot/index.ts @@ -0,0 +1,201 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +import request from "../request"; +export const getActivePipeline = () => { + return request({ + url: "v1/pilot/pipeline/active/id", + method: "get", + showLoading: true, + }); +}; + +export const getActivePipelineDetail = () => { + return request({ + url: "v1/pilot/pipeline/active", + method: "get", + showLoading: true, + }); +}; + +export const getPipelineDetailById = (pipelineId: Number) => { + return request({ + url: `v1/pilot/pipeline/${pipelineId}`, + method: "get", + }); +}; + +export const requestResultsMetrics = ( + pipelineId: Number, + data: EmptyArrayType +) => { + return request({ + url: `/v1/pilot/pipeline/${pipelineId}/results/metrics`, + method: "patch", + data, + showLoading: true, + }); +}; + +export const getResultsByPipelineId = (pipelineId: Number) => { + return request({ + url: `v1/pilot/pipeline/${pipelineId}/results`, + method: "get", + }); +}; + +export const getMetricsByPipelineId = (pipelineId: Number) => { + return request({ + url: `v1/pilot/pipeline/${pipelineId}/results/metrics`, + method: "get", + showLoading: true, + }); +}; + +export const requesPipelineRun = () => { + return request({ + url: "v1/pilot/pipeline/active/run", + method: "post", + }); +}; + +export const requesStageRun = (stageName: String) => { + return request({ + url: `v1/tuners/stage/${stageName}/run`, + method: "post", + }); +}; + +export const getStageDetail = (stage: String) => { + return request({ + url: `v1/tuners/stage/${stage}`, + method: "get", + }); +}; +export const getStageStatus = (stage: String) => { + return request({ + url: `v1/tuners/stage/${stage}/status`, + method: "get", + }); +}; + +export const getStagePipelines = (stage: String) => { + return request({ + url: `v1/tuners/stage/${stage}/pipelines`, + method: "get", + }); +}; + +export const getResultsByStage = (stage: String) => { + return request({ + url: `v1/tuners/stage/${stage}/results`, + method: "get", + }); +}; + +export const getMetricsByStage = (stage: String) => { + return request({ + url: `v1/tuners/stage/${stage}/results/metrics`, + method: "get", + }); +}; +export const getBasePipelineByTuner = (tunerName: String) => { + return request({ + url: `v1/tuners/${tunerName}/pipeline/base`, + method: "get", + }); +}; + +export const getTunerStatus = (tuner: String) => { + return request({ + url: `v1/tuners/${tuner}/status`, + method: "get", + }); +}; +export const getPrompById = (pipelineId: number) => { + return request({ + url: `v1/pilot/pipeline/${pipelineId}/prompt`, + method: "get", + showLoading: true, + }); +}; + +export const requesPromptUpdate = (data: Object) => { + return request({ + url: `v1/tuners/results/getPromptList`, + method: "patch", + data, + showLoading: true, + showSuccessMsg: true, + successMsg: "Prompt update successfully !", + }); +}; + +export const requesPromptActive = (data: Object) => { + return request({ + url: `v1/tuners/results/getPromptList`, + method: "patch", + data, + }); +}; + +export const requesTopnUpdate = (top_n: String) => { + return request({ + url: `v1/pilot/pipeline/active/top_n/${top_n}`, + method: "patch", + }); +}; +export const requesStageReset = (stage: String) => { + return request({ + url: `v1/tuners/stage/${stage}/reset`, + method: "post", + }); +}; + +export const requestPipelineSync = (pipelineId: Number) => { + return request({ + url: `v1/pilot/pipeline/${pipelineId}/active`, + method: "post", + showLoading: true, + showSuccessMsg: true, + successMsg: "Update successful !", + }); +}; +export const requestSubmitQueryJson = (data: EmptyArrayType) => { + return request({ + url: "/v1/pilot/ground_truth", + method: "post", + data, + showLoading: true, + showSuccessMsg: true, + successMsg: "Create successful !", + }); +}; + +export const getResultStatus = () => { + return request({ + url: `v1/tuners/stage/reset`, + method: "post", + }); +}; + +export const getBestPipelineByStage = (stage: String) => { + return request({ + url: `v1/tuners/stage/${stage}/pipelines/best/id`, + method: "get", + }); +}; + +export const uploadPipelineFileUrl = `${ + import.meta.env.VITE_API_URL +}v1/pilot/pipeline/active/import`; + +export const uploadQueryFileUrl = `${ + import.meta.env.VITE_API_URL +}v1/pilot/ground_truth/file`; + +export const exportPipelineUrl = (pipelineId: Number) => { + return `${ + import.meta.env.VITE_API_URL + }v1/pilot/pipeline/${pipelineId}/export`; +}; diff --git a/evals/evaluation/rag_pilot/ui/src/api/request.ts b/evals/evaluation/rag_pilot/ui/src/api/request.ts new file mode 100644 index 00000000..847373c1 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/api/request.ts @@ -0,0 +1,63 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +import { NextLoading } from "@/utils/loading"; +import serviceManager from "@/utils/serviceManager"; +import axios, { AxiosInstance } from "axios"; +import qs from "qs"; + +const antNotification = serviceManager.getService("antNotification"); + +const service: AxiosInstance = axios.create({ + baseURL: import.meta.env.VITE_API_URL, + timeout: 600000, + headers: { "Content-Type": "application/json" }, +}); + +// request interceptor +service.interceptors.request.use( + (config) => { + if (config.type === "formData") { + config.data = qs.stringify(config.data); + } else if (config.type === "files") { + config.headers!["Content-Type"] = "multipart/form-data"; + } + + if (config.showLoading) NextLoading.start(); + return config; + }, + (error) => { + return Promise.reject(error); + } +); + +// response interceptor +service.interceptors.response.use( + (response) => { + const { config } = response; + if (NextLoading) NextLoading.done(); + const res = response.data; + if (config.showSuccessMsg) { + if (antNotification) + antNotification("success", "Success", config.successMsg); + } + return Promise.resolve(res); + }, + (error) => { + if (NextLoading) NextLoading.done(); + let errorMessage = ""; + const { detail = "" } = error.response?.data || {}; + if (error.message.indexOf("timeout") != -1) { + errorMessage = "Timeout"; + } else if (detail) { + errorMessage = detail; + } else { + errorMessage = error.message; + } + if (antNotification) antNotification("error", "Error", errorMessage); + + return Promise.reject(error); + } +); + +export default service; diff --git a/evals/evaluation/rag_pilot/ui/src/assets/iconFont/iconfont.css b/evals/evaluation/rag_pilot/ui/src/assets/iconFont/iconfont.css new file mode 100644 index 00000000..03e5fe8c --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/assets/iconFont/iconfont.css @@ -0,0 +1,219 @@ +@font-face { + font-family: "iconfont"; /* Project id 4784207 */ + src: url('iconfont.woff2?t=1750225675265') format('woff2'), + url('iconfont.woff?t=1750225675265') format('woff'), + url('iconfont.ttf?t=1750225675265') format('truetype'); +} + +.iconfont { + font-family: "iconfont" !important; + font-size: 16px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.icon-skip:before { + content: "\e6d7"; +} + +.icon-prompt:before { + content: "\e641"; +} + +.icon-sync:before { + content: "\e611"; +} + +.icon-process-node:before { + content: "\e986"; +} + +.icon-process:before { + content: "\e64a"; +} + +.icon-sigh:before { + content: "\e8d6"; +} + +.icon-loading1:before { + content: "\e891"; +} + +.icon-download:before { + content: "\e600"; +} + +.icon-newChat:before { + content: "\e6c7"; +} + +.icon-chat:before { + content: "\ecb1"; +} + +.icon-knowledge:before { + content: "\e6f2"; +} + +.icon-system:before { + content: "\e799"; +} + +.icon-chatbot1:before { + content: "\e630"; +} + +.icon-lang-zh:before { + content: "\e6c5"; +} + +.icon-lang-en:before { + content: "\e609"; +} + +.icon-exit:before { + content: "\e6d9"; +} + +.icon-loading:before { + content: "\e61a"; +} + +.icon-success:before { + content: "\e8ca"; +} + +.icon-results:before { + content: "\e603"; +} + +.icon-rating:before { + content: "\e7b9"; +} + +.icon-chart-line:before { + content: "\e790"; +} + +.icon-export:before { + content: "\e619"; +} + +.icon-rename:before { + content: "\e618"; +} + +.icon-delete:before { + content: "\e664"; +} + +.icon-setting1:before { + content: "\e61b"; +} + +.icon-upload:before { + content: "\e617"; +} + +.icon-clear:before { + content: "\e765"; +} + +.icon-copy-success:before { + content: "\e666"; +} + +.icon-copy:before { + content: "\e660"; +} + +.icon-subway:before { + content: "\e6ed"; +} + +.icon-stop:before { + content: "\e904"; +} + +.icon-time-expand:before { + content: "\e616"; +} + +.icon-time-retract:before { + content: "\e615"; +} + +.icon-search-time:before { + content: "\ea85"; +} + +.icon-handle-time:before { + content: "\e7a2"; +} + +.icon-generation:before { + content: "\e6b9"; +} + +.icon-generator:before { + content: "\e67e"; +} + +.icon-user:before { + content: "\e730"; +} + +.icon-send:before { + content: "\e7db"; +} + +.icon-uploaded:before { + content: "\e614"; +} + +.icon-notice-board:before { + content: "\e674"; +} + +.icon-setting:before { + content: "\e64c"; +} + +.icon-chatbot:before { + content: "\e669"; +} + +.icon-cloudupload-fill:before { + content: "\e7da"; +} + +.icon-basic:before { + content: "\e613"; +} + +.icon-indexer:before { + content: "\e612"; +} + +.icon-retriever:before { + content: "\e694"; +} + +.icon-node-parser:before { + content: "\e65d"; +} + +.icon-generator1:before { + content: "\e656"; +} + +.icon-post-processor:before { + content: "\e718"; +} + +.icon-active:before { + content: "\e795"; +} + diff --git a/evals/evaluation/rag_pilot/ui/src/assets/iconFont/iconfont.js b/evals/evaluation/rag_pilot/ui/src/assets/iconFont/iconfont.js new file mode 100644 index 00000000..49460df1 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/assets/iconFont/iconfont.js @@ -0,0 +1,4 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +window._iconfont_svg_string_4784207='',(h=>{var l=(a=(a=document.getElementsByTagName("script"))[a.length-1]).getAttribute("data-injectcss"),a=a.getAttribute("data-disable-injectsvg");if(!a){var c,t,i,o,v,e=function(l,a){a.parentNode.insertBefore(l,a)};if(l&&!h.__iconfont__svg__cssinject__){h.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(l){console&&console.log(l)}}c=function(){var l,a=document.createElement("div");a.innerHTML=h._iconfont_svg_string_4784207,(a=a.getElementsByTagName("svg")[0])&&(a.setAttribute("aria-hidden","true"),a.style.position="absolute",a.style.width=0,a.style.height=0,a.style.overflow="hidden",a=a,(l=document.body).firstChild?e(a,l.firstChild):l.appendChild(a))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(c,0):(t=function(){document.removeEventListener("DOMContentLoaded",t,!1),c()},document.addEventListener("DOMContentLoaded",t,!1)):document.attachEvent&&(i=c,o=h.document,v=!1,s(),o.onreadystatechange=function(){"complete"==o.readyState&&(o.onreadystatechange=null,m())})}function m(){v||(v=!0,i())}function s(){try{o.documentElement.doScroll("left")}catch(l){return void setTimeout(s,50)}m()}})(window); diff --git a/evals/evaluation/rag_pilot/ui/src/assets/iconFont/iconfont.json b/evals/evaluation/rag_pilot/ui/src/assets/iconFont/iconfont.json new file mode 100644 index 00000000..2474afe9 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/assets/iconFont/iconfont.json @@ -0,0 +1,366 @@ +{ + "id": "4784207", + "name": "intel-ECRAG", + "font_family": "iconfont", + "css_prefix_text": "icon-", + "description": "", + "glyphs": [ + { + "icon_id": "11753455", + "name": "skip", + "font_class": "skip", + "unicode": "e6d7", + "unicode_decimal": 59095 + }, + { + "icon_id": "36657468", + "name": "prompt", + "font_class": "prompt", + "unicode": "e641", + "unicode_decimal": 58945 + }, + { + "icon_id": "22325372", + "name": "sync", + "font_class": "sync", + "unicode": "e611", + "unicode_decimal": 58897 + }, + { + "icon_id": "8855141", + "name": "process-node", + "font_class": "process-node", + "unicode": "e986", + "unicode_decimal": 59782 + }, + { + "icon_id": "14772879", + "name": "process", + "font_class": "process", + "unicode": "e64a", + "unicode_decimal": 58954 + }, + { + "icon_id": "29808383", + "name": "sigh", + "font_class": "sigh", + "unicode": "e8d6", + "unicode_decimal": 59606 + }, + { + "icon_id": "10273624", + "name": "loading", + "font_class": "loading1", + "unicode": "e891", + "unicode_decimal": 59537 + }, + { + "icon_id": "136387", + "name": "download", + "font_class": "download", + "unicode": "e600", + "unicode_decimal": 58880 + }, + { + "icon_id": "43508860", + "name": "newChat", + "font_class": "newChat", + "unicode": "e6c7", + "unicode_decimal": 59079 + }, + { + "icon_id": "6807699", + "name": "chat", + "font_class": "chat", + "unicode": "ecb1", + "unicode_decimal": 60593 + }, + { + "icon_id": "12237229", + "name": "knowledge", + "font_class": "knowledge", + "unicode": "e6f2", + "unicode_decimal": 59122 + }, + { + "icon_id": "25013769", + "name": "system", + "font_class": "system", + "unicode": "e799", + "unicode_decimal": 59289 + }, + { + "icon_id": "28670155", + "name": "chatbot", + "font_class": "chatbot1", + "unicode": "e630", + "unicode_decimal": 58928 + }, + { + "icon_id": "8358946", + "name": "lang-zh", + "font_class": "lang-zh", + "unicode": "e6c5", + "unicode_decimal": 59077 + }, + { + "icon_id": "26283816", + "name": "lang-en", + "font_class": "lang-en", + "unicode": "e609", + "unicode_decimal": 58889 + }, + { + "icon_id": "1786168", + "name": "exit", + "font_class": "exit", + "unicode": "e6d9", + "unicode_decimal": 59097 + }, + { + "icon_id": "40154691", + "name": "loading", + "font_class": "loading", + "unicode": "e61a", + "unicode_decimal": 58906 + }, + { + "icon_id": "20939277", + "name": "success", + "font_class": "success", + "unicode": "e8ca", + "unicode_decimal": 59594 + }, + { + "icon_id": "6820316", + "name": "results", + "font_class": "results", + "unicode": "e603", + "unicode_decimal": 58883 + }, + { + "icon_id": "36924379", + "name": "rating", + "font_class": "rating", + "unicode": "e7b9", + "unicode_decimal": 59321 + }, + { + "icon_id": "6151034", + "name": "chart-line", + "font_class": "chart-line", + "unicode": "e790", + "unicode_decimal": 59280 + }, + { + "icon_id": "43924556", + "name": "export", + "font_class": "export", + "unicode": "e619", + "unicode_decimal": 58905 + }, + { + "icon_id": "43924554", + "name": "rename", + "font_class": "rename", + "unicode": "e618", + "unicode_decimal": 58904 + }, + { + "icon_id": "2570142", + "name": "delete", + "font_class": "delete", + "unicode": "e664", + "unicode_decimal": 58980 + }, + { + "icon_id": "13253937", + "name": "setting", + "font_class": "setting1", + "unicode": "e61b", + "unicode_decimal": 58907 + }, + { + "icon_id": "43796752", + "name": "upload", + "font_class": "upload", + "unicode": "e617", + "unicode_decimal": 58903 + }, + { + "icon_id": "42194548", + "name": "clear", + "font_class": "clear", + "unicode": "e765", + "unicode_decimal": 59237 + }, + { + "icon_id": "1198529", + "name": "copy-success", + "font_class": "copy-success", + "unicode": "e666", + "unicode_decimal": 58982 + }, + { + "icon_id": "9080698", + "name": "copy", + "font_class": "copy", + "unicode": "e660", + "unicode_decimal": 58976 + }, + { + "icon_id": "796912", + "name": "ๅœฐ้“", + "font_class": "subway", + "unicode": "e6ed", + "unicode_decimal": 59117 + }, + { + "icon_id": "42853460", + "name": "stop", + "font_class": "stop", + "unicode": "e904", + "unicode_decimal": 59652 + }, + { + "icon_id": "43170667", + "name": "time-expand", + "font_class": "time-expand", + "unicode": "e616", + "unicode_decimal": 58902 + }, + { + "icon_id": "43169873", + "name": "time-retract", + "font_class": "time-retract", + "unicode": "e615", + "unicode_decimal": 58901 + }, + { + "icon_id": "30339163", + "name": "search-time", + "font_class": "search-time", + "unicode": "ea85", + "unicode_decimal": 60037 + }, + { + "icon_id": "21506860", + "name": "handle-time", + "font_class": "handle-time", + "unicode": "e7a2", + "unicode_decimal": 59298 + }, + { + "icon_id": "7199746", + "name": "generation", + "font_class": "generation", + "unicode": "e6b9", + "unicode_decimal": 59065 + }, + { + "icon_id": "25198413", + "name": "generator", + "font_class": "generator", + "unicode": "e67e", + "unicode_decimal": 59006 + }, + { + "icon_id": "1262340", + "name": "user", + "font_class": "user", + "unicode": "e730", + "unicode_decimal": 59184 + }, + { + "icon_id": "43165836", + "name": "send", + "font_class": "send", + "unicode": "e7db", + "unicode_decimal": 59355 + }, + { + "icon_id": "1973584", + "name": "uploaded", + "font_class": "uploaded", + "unicode": "e614", + "unicode_decimal": 58900 + }, + { + "icon_id": "33661191", + "name": "notice board", + "font_class": "notice-board", + "unicode": "e674", + "unicode_decimal": 58996 + }, + { + "icon_id": "8094211", + "name": "setting", + "font_class": "setting", + "unicode": "e64c", + "unicode_decimal": 58956 + }, + { + "icon_id": "13990803", + "name": "chatbot", + "font_class": "chatbot", + "unicode": "e669", + "unicode_decimal": 58985 + }, + { + "icon_id": "6151158", + "name": "cloud upload-fill", + "font_class": "cloudupload-fill", + "unicode": "e7da", + "unicode_decimal": 59354 + }, + { + "icon_id": "43084711", + "name": "basic", + "font_class": "basic", + "unicode": "e613", + "unicode_decimal": 58899 + }, + { + "icon_id": "43083946", + "name": "Indexer", + "font_class": "indexer", + "unicode": "e612", + "unicode_decimal": 58898 + }, + { + "icon_id": "145727", + "name": "Retriever", + "font_class": "retriever", + "unicode": "e694", + "unicode_decimal": 59028 + }, + { + "icon_id": "4114056", + "name": "node-parser-icon", + "font_class": "node-parser", + "unicode": "e65d", + "unicode_decimal": 58973 + }, + { + "icon_id": "11791029", + "name": "Generator", + "font_class": "generator1", + "unicode": "e656", + "unicode_decimal": 58966 + }, + { + "icon_id": "21489495", + "name": "PostProcessor", + "font_class": "post-processor", + "unicode": "e718", + "unicode_decimal": 59160 + }, + { + "icon_id": "25487933", + "name": "active", + "font_class": "active", + "unicode": "e795", + "unicode_decimal": 59285 + } + ] +} diff --git a/evals/evaluation/rag_pilot/ui/src/assets/iconFont/iconfont.ttf b/evals/evaluation/rag_pilot/ui/src/assets/iconFont/iconfont.ttf new file mode 100644 index 00000000..2954a383 Binary files /dev/null and b/evals/evaluation/rag_pilot/ui/src/assets/iconFont/iconfont.ttf differ diff --git a/evals/evaluation/rag_pilot/ui/src/assets/iconFont/iconfont.woff b/evals/evaluation/rag_pilot/ui/src/assets/iconFont/iconfont.woff new file mode 100644 index 00000000..d72ed382 Binary files /dev/null and b/evals/evaluation/rag_pilot/ui/src/assets/iconFont/iconfont.woff differ diff --git a/evals/evaluation/rag_pilot/ui/src/assets/iconFont/iconfont.woff2 b/evals/evaluation/rag_pilot/ui/src/assets/iconFont/iconfont.woff2 new file mode 100644 index 00000000..7637fe83 Binary files /dev/null and b/evals/evaluation/rag_pilot/ui/src/assets/iconFont/iconfont.woff2 differ diff --git a/evals/evaluation/rag_pilot/ui/src/assets/images/404-bg.png b/evals/evaluation/rag_pilot/ui/src/assets/images/404-bg.png new file mode 100644 index 00000000..94c8394f Binary files /dev/null and b/evals/evaluation/rag_pilot/ui/src/assets/images/404-bg.png differ diff --git a/evals/evaluation/rag_pilot/ui/src/assets/images/noData.png b/evals/evaluation/rag_pilot/ui/src/assets/images/noData.png new file mode 100644 index 00000000..01e27e21 Binary files /dev/null and b/evals/evaluation/rag_pilot/ui/src/assets/images/noData.png differ diff --git a/evals/evaluation/rag_pilot/ui/src/assets/svgs/404-icon.svg b/evals/evaluation/rag_pilot/ui/src/assets/svgs/404-icon.svg new file mode 100644 index 00000000..dd5b9741 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/assets/svgs/404-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/evals/evaluation/rag_pilot/ui/src/assets/svgs/dark-icon.svg b/evals/evaluation/rag_pilot/ui/src/assets/svgs/dark-icon.svg new file mode 100644 index 00000000..296521d7 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/assets/svgs/dark-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/evals/evaluation/rag_pilot/ui/src/assets/svgs/header-log.svg b/evals/evaluation/rag_pilot/ui/src/assets/svgs/header-log.svg new file mode 100644 index 00000000..a43a6b4e --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/assets/svgs/header-log.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/evals/evaluation/rag_pilot/ui/src/assets/svgs/light-icon.svg b/evals/evaluation/rag_pilot/ui/src/assets/svgs/light-icon.svg new file mode 100644 index 00000000..79041030 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/assets/svgs/light-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/evals/evaluation/rag_pilot/ui/src/assets/svgs/lightBulb.svg b/evals/evaluation/rag_pilot/ui/src/assets/svgs/lightBulb.svg new file mode 100644 index 00000000..e0a41adc --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/assets/svgs/lightBulb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/evals/evaluation/rag_pilot/ui/src/assets/svgs/uploaded.svg b/evals/evaluation/rag_pilot/ui/src/assets/svgs/uploaded.svg new file mode 100644 index 00000000..cdaaf1ff --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/assets/svgs/uploaded.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/evals/evaluation/rag_pilot/ui/src/auto-imports.d.ts b/evals/evaluation/rag_pilot/ui/src/auto-imports.d.ts new file mode 100644 index 00000000..b75b9826 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/auto-imports.d.ts @@ -0,0 +1,91 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +/* eslint-disable */ +/* prettier-ignore */ +// @ts-nocheck +// noinspection JSUnusedGlobalSymbols +// Generated by unplugin-auto-import +// biome-ignore lint: disable +export {} +declare global { + const EffectScope: typeof import('vue')['EffectScope'] + const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate'] + const computed: typeof import('vue')['computed'] + const createApp: typeof import('vue')['createApp'] + const createPinia: typeof import('pinia')['createPinia'] + const customRef: typeof import('vue')['customRef'] + const defineAsyncComponent: typeof import('vue')['defineAsyncComponent'] + const defineComponent: typeof import('vue')['defineComponent'] + const defineStore: typeof import('pinia')['defineStore'] + const effectScope: typeof import('vue')['effectScope'] + const getActivePinia: typeof import('pinia')['getActivePinia'] + const getCurrentInstance: typeof import('vue')['getCurrentInstance'] + const getCurrentScope: typeof import('vue')['getCurrentScope'] + const h: typeof import('vue')['h'] + const inject: typeof import('vue')['inject'] + const isProxy: typeof import('vue')['isProxy'] + const isReactive: typeof import('vue')['isReactive'] + const isReadonly: typeof import('vue')['isReadonly'] + const isRef: typeof import('vue')['isRef'] + const mapActions: typeof import('pinia')['mapActions'] + const mapGetters: typeof import('pinia')['mapGetters'] + const mapState: typeof import('pinia')['mapState'] + const mapStores: typeof import('pinia')['mapStores'] + const mapWritableState: typeof import('pinia')['mapWritableState'] + const markRaw: typeof import('vue')['markRaw'] + const nextTick: typeof import('vue')['nextTick'] + const onActivated: typeof import('vue')['onActivated'] + const onBeforeMount: typeof import('vue')['onBeforeMount'] + const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave'] + const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate'] + const onBeforeUnmount: typeof import('vue')['onBeforeUnmount'] + const onBeforeUpdate: typeof import('vue')['onBeforeUpdate'] + const onDeactivated: typeof import('vue')['onDeactivated'] + const onErrorCaptured: typeof import('vue')['onErrorCaptured'] + const onMounted: typeof import('vue')['onMounted'] + const onRenderTracked: typeof import('vue')['onRenderTracked'] + const onRenderTriggered: typeof import('vue')['onRenderTriggered'] + const onScopeDispose: typeof import('vue')['onScopeDispose'] + const onServerPrefetch: typeof import('vue')['onServerPrefetch'] + const onUnmounted: typeof import('vue')['onUnmounted'] + const onUpdated: typeof import('vue')['onUpdated'] + const onWatcherCleanup: typeof import('vue')['onWatcherCleanup'] + const provide: typeof import('vue')['provide'] + const reactive: typeof import('vue')['reactive'] + const readonly: typeof import('vue')['readonly'] + const ref: typeof import('vue')['ref'] + const resolveComponent: typeof import('vue')['resolveComponent'] + const setActivePinia: typeof import('pinia')['setActivePinia'] + const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix'] + const shallowReactive: typeof import('vue')['shallowReactive'] + const shallowReadonly: typeof import('vue')['shallowReadonly'] + const shallowRef: typeof import('vue')['shallowRef'] + const storeToRefs: typeof import('pinia')['storeToRefs'] + const toRaw: typeof import('vue')['toRaw'] + const toRef: typeof import('vue')['toRef'] + const toRefs: typeof import('vue')['toRefs'] + const toValue: typeof import('vue')['toValue'] + const triggerRef: typeof import('vue')['triggerRef'] + const unref: typeof import('vue')['unref'] + const useAttrs: typeof import('vue')['useAttrs'] + const useCssModule: typeof import('vue')['useCssModule'] + const useCssVars: typeof import('vue')['useCssVars'] + const useId: typeof import('vue')['useId'] + const useLink: typeof import('vue-router')['useLink'] + const useModel: typeof import('vue')['useModel'] + const useRoute: typeof import('vue-router')['useRoute'] + const useRouter: typeof import('vue-router')['useRouter'] + const useSlots: typeof import('vue')['useSlots'] + const useTemplateRef: typeof import('vue')['useTemplateRef'] + const watch: typeof import('vue')['watch'] + const watchEffect: typeof import('vue')['watchEffect'] + const watchPostEffect: typeof import('vue')['watchPostEffect'] + const watchSyncEffect: typeof import('vue')['watchSyncEffect'] +} +// for type re-export +declare global { + // @ts-ignore + export type { Component, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue' + import('vue') +} diff --git a/evals/evaluation/rag_pilot/ui/src/components.d.ts b/evals/evaluation/rag_pilot/ui/src/components.d.ts new file mode 100644 index 00000000..09edca0c --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/components.d.ts @@ -0,0 +1,20 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +/* eslint-disable */ +// @ts-nocheck +// Generated by unplugin-vue-components +// Read more: https://github.com/vuejs/core/pull/3399 +export {} + +/* prettier-ignore */ +declare module 'vue' { + export interface GlobalComponents { + AButton: typeof import('ant-design-vue/es')['Button'] + AInput: typeof import('ant-design-vue/es')['Input'] + ALayout: typeof import('ant-design-vue/es')['Layout'] + ALayoutContent: typeof import('ant-design-vue/es')['LayoutContent'] + RouterLink: typeof import('vue-router')['RouterLink'] + RouterView: typeof import('vue-router')['RouterView'] + } +} diff --git a/evals/evaluation/rag_pilot/ui/src/components/FormTooltip.vue b/evals/evaluation/rag_pilot/ui/src/components/FormTooltip.vue new file mode 100644 index 00000000..9fb0d225 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/components/FormTooltip.vue @@ -0,0 +1,26 @@ + + + + + diff --git a/evals/evaluation/rag_pilot/ui/src/components/SvgIcon.vue b/evals/evaluation/rag_pilot/ui/src/components/SvgIcon.vue new file mode 100644 index 00000000..f51058b3 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/components/SvgIcon.vue @@ -0,0 +1,56 @@ + + + + + diff --git a/evals/evaluation/rag_pilot/ui/src/i18n/en.ts b/evals/evaluation/rag_pilot/ui/src/i18n/en.ts new file mode 100644 index 00000000..c3c65129 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/i18n/en.ts @@ -0,0 +1,153 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +export default { + headerTitle: "RAG Pilot Pipeline Autotune Tool", + common: { + update: "Update", + edit: "Edit", + delete: "Delete", + active: "Activate", + deactivate: "Deactivate", + cancel: "Cancel", + confirm: "Confirm", + save: "Save", + next: "Next", + reset: "Reset", + error: "Error", + exit: "Exit", + back: "Back", + prompt: "Prompt", + download: "Download", + collapse: "Collapse", + expand: "Expand", + original: "Original", + final: "Final", + uploadTip: "Click or drag file to this area to upload", + exitTip: "Are you sure to exit? After exiting, the process will be reset.", + ratingTip: "Please read each question patiently and rate the answer.", + rated: "Rated", + total: "Total", + retry: "Retry", + query: "Query", + selected: "Selected", + configuration: "Pipeline configuration", + waitTip: + "Please wait patiently and do not refresh the page during this period.", + }, + home: { + title: "Hi, I'm RAG Pilot.", + des: "Please upload the file for debugging and analysis.", + tip: "There is no available pipeline. Please create or activate it first.", + create: " Create Ground Truth", + edit: "Edit Ground Truth", + uploadSucc: "Upload Successfully !", + uploadErr: "Files upload failed!", + fileFormat: "Supports CSV JSON format, with file size not exceeding 200M.", + created: "You have successfully created ground truth.", + validSizeErr: "Single file size not exceeding 200M.", + form: { + delContext: "Delete Context", + delQuery: "Delete Query", + addContext: "addete Context", + addQuery: "Delete Query", + label: { + query: "Query", + gt_context: "Contexts Ground Truth", + fileName: "File name", + context: "Context", + gt_answer: "Answer Ground Truth", + }, + placeholder: { + query: "Please enter the query", + fileName: "Please enter the file name", + context: "Please enter the context", + gt_answer: "Please enter the answer ground truth", + }, + valid: { + query: "Query cannot be empty", + gt_context: "Contexts ground truth cannot be empty", + fileName: "File name cannot be empty", + context: "Context cannot be empty", + }, + tip: { + query: "Query description", + fileName: "Reference documents", + context: "Reference contexts ground truth", + gt_answer: "Reference answer ground truth", + }, + }, + }, + tuner: { + rating: "Response rating", + retriever: "Retrieve Context Tuning", + processor: "Postprocess Context Tuning", + generator: "Generation Tuning", + results: "View Results", + }, + retriever: { + gt_context: "Contexts Ground Truth", + search: "Search Retrieve Context", + recall: "Recall rate", + showHit: "Hit Context Details", + hideHit: "Hide Details", + retrieved: "Retrieved Context", + chunk: "Retrieved Chunk", + configuration: "Configuration", + }, + postprocess: { + pipelineRecall: "Pipeline recall rate", + top_n: " Top n", + search: "Search Postprocessed Context", + retrieved: "Retrieved Context", + postprocessed: "Postprocessed Context", + chunk: "Postprocessed Chunk", + tip: "Please select the most suitable Top n.", + tip1: "The current top n is", + tip2: ". Please confirm that you want to use this value to enter the generation tuning?", + }, + prompt: { + title: "Prompt", + activated: "Activated Prompt", + }, + results: { + rating: "User rating", + name: "Pipeline name", + id: "ID", + update: "Update to EC-RAG", + detail: "Configuration details", + download: "Download", + retryTip: + "Are you sure you want to retry? After confirmation, the process will be reset.", + }, + pipeline: { + detail: "Pipeline configuration", + name: "Name", + nodeParser: "Node Parser", + nodeParserType: "Node parser type", + chunkSize: "Chunk size", + chunkOverlap: "Chunk overlap", + windowSize: "Window Size", + indexer: "Indexer", + indexerType: "Indexer Type", + embedding: "Embedding Model", + retriever: "Retriever", + retrieverType: "Retriever Type", + topk: "Search top k", + postProcessor: "PostProcessor", + postProcessorType: "PostProcessor Type", + top_n: "Top n", + rerank: "Rerank Model", + generator: "Generator", + generatorType: "Generator Type", + llm: "LLM Inference Type", + language: "Large Language Model", + weights: "Weights", + local: "Local", + vllm: "Vllm", + }, + error: { + notFoundTip: "Uh oh! It seems like you're lost", + back: "Go Home", + }, +}; diff --git a/evals/evaluation/rag_pilot/ui/src/i18n/index.ts b/evals/evaluation/rag_pilot/ui/src/i18n/index.ts new file mode 100644 index 00000000..ac93f5bf --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/i18n/index.ts @@ -0,0 +1,22 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +import { createI18n } from "vue-i18n"; +import { Local } from "@/utils/storage"; +import enLocale from "ant-design-vue/es/locale/en_US"; +import zhLocale from "ant-design-vue/es/locale/zh_CN"; +import en from "./en"; +import zh from "./zh"; + +const messages = { + en_US: { ...en, ...enLocale }, + zh_CN: { ...zh, ...zhLocale }, +}; + +const i18n = createI18n({ + locale: Local.get("themeInfo")?.lang || "en_US", + fallbackLocale: "en_US", + messages, +}); + +export default i18n; diff --git a/evals/evaluation/rag_pilot/ui/src/i18n/zh.ts b/evals/evaluation/rag_pilot/ui/src/i18n/zh.ts new file mode 100644 index 00000000..c31f100d --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/i18n/zh.ts @@ -0,0 +1,151 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +export default { + headerTitle: "RAG Pilot Pipeline Autotune Tool", + common: { + update: "ๆ›ดๆ–ฐ", + edit: "็ผ–่พ‘", + delete: "ๅˆ ้™ค", + active: "ๅฏ็”จ", + deactivate: "ๅœ็”จ", + cancel: "ๅ–ๆถˆ", + confirm: "็กฎ่ฎค", + save: "ไฟๅญ˜", + next: "ไธ‹ไธ€ๆญฅ", + reset: "้‡็ฝฎ", + error: "้”™่ฏฏ", + exit: "้€€ๅ‡บ", + back: "่ฟ”ๅ›ž", + prompt: "ๆ้†’", + download: "ไธ‹่ฝฝ", + collapse: "ๆ”ถ่ตท", + expand: "ๅฑ•ๅผ€", + original: "ๅˆๅง‹", + final: "ๆœ€็ปˆ", + uploadTip: "็‚นๅ‡ปๆˆ–ๅฐ†ๆ–‡ไปถๆ‹–ๅˆฐๆญคๅŒบๅŸŸ่ฟ›่กŒไธŠไผ ", + exitTip: "ๆ‚จ็กฎๅฎš่ฆ้€€ๅ‡บๅ—๏ผŸ้€€ๅ‡บๅŽ๏ผŒ่ฟ›็จ‹ๅฐ†้‡็ฝฎใ€‚", + ratingTip: "่ฏท่€ๅฟƒ้˜…่ฏปๆฏไธช้—ฎ้ข˜๏ผŒๅนถๅฏน็ญ”ๆกˆ่ฟ›่กŒ่ฏ„ๅˆ†", + rated: "ๅทฒๅฎŒๆˆ", + total: "ๆ€ป่ฎก", + retry: "้‡่ฏ•", + query: "้—ฎ้ข˜", + selected: "้€‰ๆ‹ฉ็š„", + configuration: "Pipeline ้…็ฝฎ", + waitTip: "่ฏท่€ๅฟƒ็ญ‰ๅพ…๏ผŒๅœจๆญคๆœŸ้—ดไธ่ฆๅˆทๆ–ฐ้กต้ขใ€‚", + }, + home: { + title: "ๆ‚จๅฅฝ, ๆˆ‘ๆ˜ฏRAG Pilot.", + des: " ่ฏทไธŠไผ ๆ–‡ไปถไปฅ่ฟ›่กŒ่ฐƒ่ฏ•ๅ’Œๅˆ†ๆž", + tip: "ๆฒกๆœ‰ๅฏ็”จ็š„Pipelineใ€‚่ฏทๅ…ˆๅˆ›ๅปบๆˆ–ๆฟ€ๆดปๅฎƒ", + create: "ๅˆ›ๅปบ่ฐƒ่ฏ•ๆ ทๆœฌ", + edit: "็ผ–่พ‘่ฐƒ่ฏ•ๆ ทๆœฌ", + uploadSucc: "ๆ–‡ไปถไธŠไผ ๆˆๅŠŸ !", + uploadErr: "ๆ–‡ไปถไธŠไผ ๅคฑ่ดฅ!", + fileFormat: "ๆ”ฏๆŒ CSV ๅ’Œ JSON ๆ ผๅผ๏ผŒๆ–‡ไปถๅคงๅฐไธ่ถ…่ฟ‡ 200MB", + created: "ๆ‚จๅทฒๆˆๅŠŸๅˆ›ๅปบ่ฐƒ่ฏ•ๆ ทๆœฌ", + validSizeErr: "ๆ–‡ไปถๅคงๅฐไธ่ƒฝ่ถ…่ฟ‡ 200MB", + form: { + delContext: " ๅˆ ้™คไธŠไธ‹ๆ–‡", + delQuery: " ๅˆ ้™ค้—ฎ้ข˜", + addContext: "ๆ–ฐๅขžไธŠไธ‹ๆ–‡", + addQuery: " ๆ–ฐๅขž้—ฎ้ข˜", + label: { + query: "้—ฎ้ข˜", + gt_context: "ๆ ‡ๅ‡†ไธŠไธ‹ๆ–‡", + fileName: "ๆ–‡ไปถๅ", + context: "ไธŠไธ‹ๆ–‡", + gt_answer: "ๆ ‡ๅ‡†็ญ”ๆกˆ", + }, + placeholder: { + query: "่ฏท่พ“ๅ…ฅ้—ฎ้ข˜", + fileName: "่ฏท่พ“ๅ…ฅๆ–‡ไปถๅ", + context: "่ฏท่พ“ๅ…ฅไธŠไธ‹ๆ–‡", + gt_answer: "่ฏท่พ“ๅ…ฅๆ ‡ๅ‡†็ญ”ๆกˆ", + }, + valid: { + query: "้—ฎ้ข˜ไธ่ƒฝไธบ็ฉบ", + gt_context: "ๆ ‡ๅ‡†ไธŠไธ‹ๆ–‡ไธ่ƒฝไธบ็ฉบ", + fileName: "ๆ–‡ไปถๅไธ่ƒฝไธบ็ฉบ", + context: "ไธŠไธ‹ๆ–‡ไธ่ƒฝไธบ็ฉบ", + }, + tip: { + query: "้—ฎ้ข˜ๆ่ฟฐ", + fileName: "ๅ‚่€ƒๆ–‡ๆกฃ", + context: "ๆไพ›็š„ไธŠไธ‹ๆ–‡ไฟกๆฏ", + gt_answer: "ๆไพ›็š„ๆ ‡ๅ‡†็ญ”ๆกˆ", + }, + }, + }, + tuner: { + rating: "็ญ”ๆกˆ่ฏ„ๅˆ†", + retriever: "ๆฃ€็ดขๅ™จ่ฐƒไผ˜", + processor: "ๅŽๅค„็†ๅ™จ่ฐƒไผ˜", + generator: "็”Ÿๆˆๅ™จ่ฐƒไผ˜", + results: "็ป“ๆžœๆŸฅ็œ‹", + }, + retriever: { + gt_context: "ๆ ‡ๅ‡†ไธŠไธ‹ๆ–‡", + search: "ๆœ็ดขๆฃ€็ดขไธŠไธ‹ๆ–‡", + recall: "ๅฌๅ›ž็އ", + showHit: "ๅ‘ฝไธญไธŠไธ‹ๆ–‡่ฏฆๆƒ…", + hideHit: "้š่—่ฏฆๆƒ…", + retrieved: "ๆฃ€็ดขๅˆฐ็š„ไธŠไธ‹ๆ–‡", + chunk: "ๆฃ€็ดขไธŠไธ‹ๆ–‡", + configuration: "้…็ฝฎ้กน", + }, + postprocess: { + pipelineRecall: "Pipeline ๅฌๅ›ž็އ", + search: "ๆœ็ดขๅŽๅค„็†ไธŠไธ‹ๆ–‡", + top_n: " Top n", + retrieved: "ๆฃ€็ดขไธŠไธ‹ๆ–‡", + postprocessed: "ๅŽๅค„็†ไธŠไธ‹ๆ–‡", + chunk: "ๅŽๅค„็†ไธŠไธ‹ๆ–‡", + tip: "่ฏท้€‰ๆ‹ฉๆœ€้€‚ๅˆ็š„Top n.", + tip1: "ๅฝ“ๅ‰Top n ๆ˜ฏ", + tip2: "๏ผŒ่ฏท็กฎ่ฎคๆ˜ฏๅฆ่ฆไฝฟ็”จๆญคๅ€ผ่ฟ›่กŒไธ‹ไธ€ๆญฅ?", + }, + prompt: { + title: "ๆ็คบ่ฏ ", + activated: "ๅฏ็”จ็š„ๆ็คบ่ฏ ", + }, + results: { + rating: "็”จๆˆท่ฏ„ๅˆ†", + name: "Pipeline ๅ็งฐ", + id: "ID", + update: "ๆ›ดๆ–ฐๅˆฐ EC-RAG", + detail: "้…็ฝฎ่ฏฆๆƒ…", + download: "้…็ฝฎไธ‹่ฝฝ", + retryTip: "ไฝ ็กฎๅฎš่ฆ้‡่ฏ•ๅ—๏ผŸ็กฎ่ฎคๅŽ๏ผŒๆต็จ‹ๅฐ†้‡็ฝฎ", + }, + pipeline: { + detail: "Pipeline ้…็ฝฎ", + name: "ๅ็งฐ", + nodeParser: "่Š‚็‚น่งฃๆžๅ™จ", + nodeParserType: "่Š‚็‚น่งฃๆžๅ™จ็ฑปๅž‹", + chunkSize: "ๅˆ†ๅ—ๅคงๅฐ", + chunkOverlap: "ๅˆ†ๅ—้‡ๅ ้ƒจๅˆ†ๅคงๅฐ", + windowSize: "ๅฅๅญไธŠไธ‹ๆ–‡็ช—ๅฃๅคงๅฐ", + indexer: "็ดขๅผ•ๅ™จ", + indexerType: "็ดขๅผ•ๅ™จ็ฑปๅž‹", + embedding: "ๅตŒๅ…ฅๆจกๅž‹", + retriever: "ๆฃ€็ดขๅ™จ", + retrieverType: "ๆฃ€็ดขๅ™จ็ฑปๅž‹", + topk: "ๆฃ€็ดข top k", + postProcessor: "่Š‚็‚นๅŽๅค„็†ๅ™จ", + postProcessorType: "่Š‚็‚นๅŽๅค„็†ๅ™จ็ฑปๅž‹", + top_n: "Top n", + rerank: "้‡ๆŽ’ๆจกๅž‹", + generator: "็”Ÿๆˆๅ™จ", + generatorType: "็”Ÿๆˆๅ™จ็ฑปๅž‹", + llm: "ๆŽจ็†็ฑปๅž‹", + language: "่ฏญ่จ€ๅคงๆจกๅž‹", + weights: "ๆƒ้‡", + local: "ๆœฌๅœฐ", + vllm: "Vllm", + }, + error: { + notFoundTip: "Oops ๅฅฝๅƒ่ตฐ้”™ๅœฐๆ–นๅ•ฆ๏ฝž", + back: "้ฆ–้กต", + }, +}; diff --git a/evals/evaluation/rag_pilot/ui/src/layout/Header.vue b/evals/evaluation/rag_pilot/ui/src/layout/Header.vue new file mode 100644 index 00000000..018c1484 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/layout/Header.vue @@ -0,0 +1,148 @@ + + + + + diff --git a/evals/evaluation/rag_pilot/ui/src/layout/Main.vue b/evals/evaluation/rag_pilot/ui/src/layout/Main.vue new file mode 100644 index 00000000..f2ea1a5d --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/layout/Main.vue @@ -0,0 +1,16 @@ + + + diff --git a/evals/evaluation/rag_pilot/ui/src/main.ts b/evals/evaluation/rag_pilot/ui/src/main.ts new file mode 100644 index 00000000..5639d342 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/main.ts @@ -0,0 +1,44 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +import { createApp } from "vue"; +import App from "./App.vue"; +import i18n from "./i18n"; +import router from "./router"; +import pinia from "./store"; +import "@/theme/index.less"; +import { antConfig } from "@/utils/other"; +import dayjs from "dayjs"; +import "dayjs/locale/en"; +import "dayjs/locale/zh-cn"; +import "@/assets/iconFont/iconfont.css"; +import { Local } from "@/utils/storage"; + +// setting dayjs language +const setDayjsLocale = (locale: string) => { + if (locale === "en-US") { + dayjs.locale("en"); + } else { + dayjs.locale("zh-cn"); + } +}; + +const body = document.documentElement as HTMLElement; + +if (Local.get("themeInfo")?.theme === "dark") + body.setAttribute("data-theme", "dark"); +else body.setAttribute("data-theme", ""); + +// watch i18n update dayjs language +watch( + () => i18n.global.locale, + (newLocale) => { + setDayjsLocale(newLocale); + }, + { immediate: true } +); +const app = createApp(App); + +antConfig(app); + +app.use(router).use(pinia).use(i18n).mount("#app"); diff --git a/evals/evaluation/rag_pilot/ui/src/router/index.ts b/evals/evaluation/rag_pilot/ui/src/router/index.ts new file mode 100644 index 00000000..7a1e1a7e --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/router/index.ts @@ -0,0 +1,12 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +import { createRouter, createWebHashHistory } from "vue-router"; +import { notFoundRoute, routeList } from "./routes"; + +const router = createRouter({ + history: createWebHashHistory(), + routes: [...notFoundRoute, ...routeList], +}); + +export default router; diff --git a/evals/evaluation/rag_pilot/ui/src/router/routes.ts b/evals/evaluation/rag_pilot/ui/src/router/routes.ts new file mode 100644 index 00000000..0a951551 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/router/routes.ts @@ -0,0 +1,65 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +import Layout from "@/layout/Main.vue"; + +export const routeList = [ + { + path: "/", + name: "Main", + component: Layout, + redirect: "/home", + children: [ + { + path: "/home", + name: "Home", + component: () => import("@/views/home/index.vue"), + meta: { title: "Home" }, + }, + { + path: "/tuner", + name: "Tuner", + component: () => import("@/views/tuner/index.vue"), + redirect: "/tuner/rating", + children: [ + { + path: "/tuner/rating", + name: "Rating", + component: () => import("@/views/tuner/components/Rating.vue"), + }, + { + path: "/tuner/retrieve", + name: "Retrieve", + component: () => import("@/views/tuner/components/Retrieve.vue"), + }, + { + path: "/tuner/postprocess", + name: "Postprocess", + component: () => import("@/views/tuner/components/Postprocess.vue"), + }, + { + path: "/tuner/generation", + name: "Generation", + component: () => import("@/views/tuner/components/Generation.vue"), + }, + { + path: "/tuner/results", + name: "Results", + component: () => import("@/views/tuner/components/Results.vue"), + }, + ], + }, + ], + }, +]; + +export const notFoundRoute = [ + { + path: "/:path(.*)*", + name: "notFound", + component: () => import("@/views/error/404.vue"), + meta: { + title: "404", + }, + }, +]; diff --git a/evals/evaluation/rag_pilot/ui/src/store/index.ts b/evals/evaluation/rag_pilot/ui/src/store/index.ts new file mode 100644 index 00000000..ecc8127c --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/store/index.ts @@ -0,0 +1,10 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +import { createPinia } from "pinia"; +import piniaPluginPersistedstate from "pinia-plugin-persistedstate"; + +const pinia = createPinia(); +pinia.use(piniaPluginPersistedstate); + +export default pinia; diff --git a/evals/evaluation/rag_pilot/ui/src/store/pipeline.ts b/evals/evaluation/rag_pilot/ui/src/store/pipeline.ts new file mode 100644 index 00000000..14a0f9fa --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/store/pipeline.ts @@ -0,0 +1,19 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +import { defineStore } from "pinia"; + +export const pipelineAppStore = defineStore("pipeline", { + state: () => ({ + basePipeline: null, + }), + persist: { + key: "pipelineInfo", + storage: localStorage, + }, + actions: { + setPipeline(id: any) { + this.basePipeline = id; + }, + }, +}); diff --git a/evals/evaluation/rag_pilot/ui/src/store/theme.ts b/evals/evaluation/rag_pilot/ui/src/store/theme.ts new file mode 100644 index 00000000..072d41d9 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/store/theme.ts @@ -0,0 +1,23 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +import { defineStore } from "pinia"; + +export const themeAppStore = defineStore("theme", { + state: () => ({ + theme: "light", + lang: "en_US", + }), + persist: { + key: "themeInfo", + storage: localStorage, + }, + actions: { + toggleTheme(type: string) { + this.theme = type; + }, + toggleLanguage(lang: string) { + this.lang = lang; + }, + }, +}); diff --git a/evals/evaluation/rag_pilot/ui/src/store/user.ts b/evals/evaluation/rag_pilot/ui/src/store/user.ts new file mode 100644 index 00000000..c9d8a13c --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/store/user.ts @@ -0,0 +1,19 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +import { defineStore } from "pinia"; + +export const userAppStore = defineStore("user", { + state: () => ({ + userGuide: false, + }), + persist: { + key: "userInfo", + storage: localStorage, + }, + actions: { + setUserGuideState(state: boolean) { + this.userGuide = state; + }, + }, +}); diff --git a/evals/evaluation/rag_pilot/ui/src/theme/ant.less b/evals/evaluation/rag_pilot/ui/src/theme/ant.less new file mode 100644 index 00000000..007ad86e --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/theme/ant.less @@ -0,0 +1,157 @@ +.intel-btn { + & + .intel-btn { + margin-left: 12px; + } + &.black-primary-button { + background-color: var(--bg-black-color); + border: 1px solid var(--border-black-color); + + &:hover { + background-color: var(--bg-black-hover-color); + } + } + + &.intel-btn-primary.intel-btn-background-ghost:not(:disabled):hover { + background-color: var(--color-primaryBg); + } + + &.intel-btn-default.intel-btn-dangerous:not(:disabled):hover { + background-color: var(--color-errorBg); + } + + &.intel-btn-success { + color: var(--color-success); + border-color: var(--color-success); + + &:hover { + background-color: var(--color-successBg); + } + } + + &.intel-btn-warning { + color: var(--color-warning); + border-color: var(--color-warning); + + &:hover { + background-color: var(--color-warningBg); + } + } +} + +.intel-btn-sm { + font-size: 12px !important; +} + +.intel-table { + width: 100%; +} + +.intel-btn-background-ghost:disabled, +.ant-btn-background-ghost:disabled { + background-color: rgba(0, 0, 0, 0.04); +} + +.intel-modal { + .intel-modal-content { + padding: 0; + .intel-modal-close { + top: 14px; + } + .intel-modal-header { + padding: 10px 24px; + border-bottom: 1px solid var(--border-main-color); + .intel-modal-title { + color: var(--font-main-color); + } + } + + .intel-modal-body { + padding: 8px 24px; + } + + .intel-modal-footer { + padding: 10px 24px; + border-top: 1px solid var(--border-main-color); + } + } +} +.ant-modal { + .ant-modal-content { + .error-icon { + color: var(--color-error); + } + .ant-btn-dangerous { + background-color: var(--color-error); + color: var(--color-white); + &:hover { + background-color: var(--color-error-hover); + color: var(--color-white); + } + } + } +} +.ant-notification { + .ant-notification-notice-message { + font-weight: 600; + } +} + +.intel-drawer { + .intel-drawer-header { + padding: 12px 20px; + + .intel-drawer-header-title { + position: relative; + + .intel-drawer-title { + font-size: 18px; + } + + .intel-drawer-close { + position: absolute; + right: 0; + color: var(--font-text-color); + margin-inline-end: 0; + margin-inline-start: 12px; + } + } + } + + .intel-drawer-body { + padding: 16px 20px 20px 20px; + } + .intel-drawer-footer { + text-align: end; + } +} +.intel-pagination { + margin-top: 24px; + text-align: end; +} + +.intel-empty-normal .intel-empty-image { + display: none; +} + +.intel-empty-normal .intel-empty-description { + color: var(--font-text-color); + &::before { + content: ""; + display: block; + background-image: url("@/assets/images/noData.png"); + background-size: contain; + background-repeat: no-repeat; + width: 220px; + height: 140px; + margin: 12px auto; + } +} + +.intel-tag-processing { + background-color: var(--color-primaryBg); + color: var(--color-primary); + border-color: var(--color-primary-hover); +} +.intel-tooltip { + max-width: 60vw; +} diff --git a/evals/evaluation/rag_pilot/ui/src/theme/common.less b/evals/evaluation/rag_pilot/ui/src/theme/common.less new file mode 100644 index 00000000..d15cb6db --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/theme/common.less @@ -0,0 +1,328 @@ +.card-shadow { + box-shadow: 0px 1px 2px -1px var(--bg-box-shadow), + 0px 1px 3px 0px var(--bg-box-shadow); +} +.flex-left { + display: flex; + align-items: center; +} +.flex-between { + display: flex; + align-items: center; + justify-content: space-between; +} +.flex-column { + display: flex; + flex-direction: column; +} +.flex-end { + display: flex; + align-items: center; + justify-content: flex-end; +} +.vertical-center { + display: flex; + align-items: center; + justify-content: center; +} +.vertical-center-transform { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} +.icon-button { + width: 24px; + height: 24px; + font-size: 18px; + border-radius: 4px; + border: 1px solid var(--font-tip-color); + .vertical-center; + &.primary { + i { + color: var(--color-primary) !important; + } + &:hover { + background-color: var(--color-primaryBg); + border: 1px solid var(--color-primary); + } + } + &.success { + i { + color: var(--color-success) !important; + } + &:hover { + background-color: var(--color-successBg); + border: 1px solid var(--color-success); + } + } + &.warning { + i { + color: var(--color-warning) !important; + } + &:hover { + background-color: var(--color-warningBg); + border: 1px solid var(--color-warning); + } + } + &.error { + i { + color: var(--color-error) !important; + } + &:hover { + background-color: var(--color-errorBg); + border: 1px solid var(--color-error); + } + } +} +.special-button-primary { + background: linear-gradient( + to bottom, + var(--color-primary-hover), + var(--color-primary) + ); + color: var(--color-white); + border: none; + border-radius: 20px; + transition: background-color 0.3s ease; + font-size: 14px; + &:hover { + color: var(--color-white); + background: var(--color-primary-hover) !important; + transition-duration: 0s; + } +} +.special-dialog { + overflow: hidden; + .intel-modal-header, + .intel-modal-footer { + display: none !important; + } + .intel-modal-body { + padding: 0 !important; + } +} + +.centered-model { + .ant-modal-confirm-btns { + text-align: center; + } +} + +.footer-container { + padding: 16px 3%; + display: flex; + align-items: center; + justify-content: space-between; + width: 100vw; + position: fixed; + left: 0; + bottom: 0; + border-top: 1px solid var(--border-main-color); + background-color: var(--bg-card-color); + z-index: 21; + .text-wrap { + margin-right: 12px; + } +} +.query-item { + display: flex; + gap: 12px; + .index-wrap { + background-color: var(--color-primary-second); + width: 32px; + height: 32px; + border-radius: 50%; + color: var(--color-white); + .vertical-center; + } + .query-wrap { + flex: 1; + position: relative; + .flex-column; + gap: 4px; + .query-title { + display: flex; + justify-content: space-between; + gap: 8px; + .left-wrap { + flex: 1; + + .id-wrap { + color: var(--font-tip-color); + font-size: 12px; + position: relative; + top: -2px; + } + .title-wrap { + color: var(--font-main-color); + font-weight: 600; + line-height: 20px; + height: 20px; + font-size: 14px; + } + } + .right-wrap { + position: relative; + top: -8px; + padding: 2px 8px 4px 8px; + border-radius: 4px; + background-color: var(--bg-content-color); + box-shadow: 0px 2px 4px 4px var(--bg-box-shadow); + } + } + .response-wrap { + width: 100%; + min-height: 24px; + background-color: var(--bg-second-color); + color: var(--font-info-color); + border-left: 3px solid var(--font-tip-color); + line-height: 20px; + padding: 4px 8px; + border-radius: 0 4px 4px 0; + .word-wrap; + } + } +} +.loopStyle(@counter) when (@counter > 0) { + .p-@{counter} { + padding: (1px * @counter); + } + + .pt-@{counter} { + padding-top: (1px * @counter); + } + + .pr-@{counter} { + padding-right: (1px * @counter); + } + + .pb-@{counter} { + padding-bottom: (1px * @counter); + } + + .pl-@{counter} { + padding-left: (1px * @counter); + } + + .m-@{counter} { + margin: (1px * @counter); + } + + .mt-@{counter} { + margin-top: (1px * @counter); + } + + .mr-@{counter} { + margin-right: (1px * @counter); + } + + .mb-@{counter} { + margin-bottom: (1px * @counter); + } + + .ml-@{counter} { + margin-left: (1px * @counter); + } + + .fs-@{counter} { + font-size: (1px * @counter); + } + + .loopStyle((@counter - 1)); +} + +.loopStyle(100); +.expand-fade-enter-active, +.expand-fade-leave-active { + transition: all 0.3s ease; +} +.expand-fade-enter-from, +.expand-fade-leave-to { + opacity: 0; + transform: translateY(-10px); +} + +@keyframes spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} +.highlighted { + color: var(--color-error); + background-color: var(--color-warningBg); + font-style: normal; + padding: 0 2px; + border-radius: 2px; +} +.word-wrap { + word-wrap: break-word; + word-break: break-all; +} +.create-drawer { + background-color: var(--bg-main-color) !important; + .intel-drawer-footer { + background-color: var(--bg-content-color); + padding: 16px 3%; + } +} +.form-wrap { + .intel-form-item-control-input-content { + display: flex; + align-items: center; + gap: 6px; + } + .slider-wrap { + &:not(:last-child) { + padding-bottom: 16px; + margin-bottom: 12px; + border-bottom: 1px dashed var(--border-main-color); + } + .intel-slider { + width: calc(100% - 100px); + } + .intel-form-item-control { + .pl-6; + } + .intel-form-item-control-input-content { + align-items: flex-start; + } + .intel-slider-rail { + width: 100%; + height: 6px; + background-color: var(--color-primaryBg); + } + .intel-slider-step { + top: 4px; + .intel-slider-dot { + width: 10px; + height: 10px; + } + } + + .intel-slider-track { + height: 6px; + border-radius: 3px; + background-color: var(--color-primary); + } + + .intel-slider-handle { + width: 12px; + height: 12px; + } + .intel-input-number { + width: 70px; + margin-left: 8px; + margin-top: 4px; + .intel-input-number-input { + height: 26px; + } + } + .anticon-info-circle { + margin-top: 10px; + } + } +} diff --git a/evals/evaluation/rag_pilot/ui/src/theme/index.less b/evals/evaluation/rag_pilot/ui/src/theme/index.less new file mode 100644 index 00000000..14c4a6da --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/theme/index.less @@ -0,0 +1,6 @@ +@import "./variables.less"; +@import "./layout.less"; +@import "./ant.less"; +@import "./common.less"; +@import "./loading.less"; +@import "./markdown.less"; diff --git a/evals/evaluation/rag_pilot/ui/src/theme/layout.less b/evals/evaluation/rag_pilot/ui/src/theme/layout.less new file mode 100644 index 00000000..5a2e79b9 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/theme/layout.less @@ -0,0 +1,110 @@ +* { + box-sizing: border-box; + outline: none !important; +} + +html, +body, +#app { + margin: 0; + padding: 0; + width: 100%; + height: 100%; + font-family: var(--body-font-family); + font-weight: 400; + -webkit-font-smoothing: antialiased; + -webkit-tap-highlight-color: transparent; + background-color: var(--bg-main-color); + font-size: 14px; + color: var(--font-text-color); + overflow: hidden; + position: relative; +} +.intel-layout { + font-family: var(--body-font-family); + font-weight: 400; + font-size: 14px; + color: var(--font-text-color); +} +h1, +p { + margin: 0; + padding: 0; +} +div[aria-hidden="true"] { + display: none !important; +} +.layout-container { + width: 100%; + height: 100%; + + .layout-header { + position: relative; + z-index: 10; + background-color: var(--bg-content-color); + box-shadow: 0px 1px 2px 0px var(--bg-box-shadow); + } + + .layout-main { + overflow: auto; + width: 100%; + min-width: 1000px; + + .layout-view { + width: 75%; + max-width: 1440px; + min-width: 960px; + margin: 0 auto; + height: 100%; + } + } + @media (max-width: 1100px) { + .layout-main { + } + } +} + +/* ๅฎฝ้ซ˜ 100% +------------------------------- */ +.w100 { + width: 100% !important; +} + +.h100 { + height: 100% !important; +} + +.vh100 { + height: 100vh !important; +} + +.max100vh { + max-height: 100vh !important; +} + +.min100vh { + min-height: 100vh !important; +} + +// ๆปšๅŠจๆกๅ‡นๆงฝ็š„้ขœ่‰ฒ๏ผŒ่ฟ˜ๅฏไปฅ่ฎพ็ฝฎ่พนๆก†ๅฑžๆ€ง +&::-webkit-scrollbar-track-piece { + background-color: var(--bg-content-color); +} + +// ๆปšๅŠจๆก็š„ๅฎฝๅบฆ +&::-webkit-scrollbar { + width: 6px; + height: 6px; +} + +// ๆปšๅŠจๆก็š„่ฎพ็ฝฎ +&::-webkit-scrollbar-thumb { + background-color: var(--bg-scrollbar); + background-clip: padding-box; + min-height: 18px; + border-radius: 3px; +} + +&::-webkit-scrollbar-thumb:hover { + background-color: var(--bg-scrollbar-hover); +} diff --git a/evals/evaluation/rag_pilot/ui/src/theme/loading.less b/evals/evaluation/rag_pilot/ui/src/theme/loading.less new file mode 100644 index 00000000..d0c279e6 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/theme/loading.less @@ -0,0 +1,54 @@ +.loading-next { + width: 100%; + height: 100%; + position: fixed; + z-index: 9999; + background-color: var(--bg-loading-color); +} +.loading-next .loading-next-box { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} +.loading-next .loading-next-box-warp { + width: 80px; + height: 80px; +} +.loading-next .loading-next-box-warp .loading-next-box-item { + width: 33.333333%; + height: 33.333333%; + background: var(--color-primary); + float: left; + animation: loading-next-animation 1.2s infinite ease; + border-radius: 1px; +} +.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(7) { + animation-delay: 0s; +} +.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(4), +.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(8) { + animation-delay: 0.1s; +} +.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(1), +.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(5), +.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(9) { + animation-delay: 0.2s; +} +.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(2), +.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(6) { + animation-delay: 0.3s; +} +.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(3) { + animation-delay: 0.4s; +} +@keyframes loading-next-animation { + 0%, + 70%, + 100% { + transform: scale3D(1, 1, 1); + } + 35% { + transform: scale3D(0, 0, 1); + } +} diff --git a/evals/evaluation/rag_pilot/ui/src/theme/markdown.less b/evals/evaluation/rag_pilot/ui/src/theme/markdown.less new file mode 100644 index 00000000..8b265fb5 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/theme/markdown.less @@ -0,0 +1,120 @@ +.intel-markdown { + color: var(--font-main-color); + strong { + font-weight: 600; + } + code, + pre, + samp, + tt { + font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, + Liberation Mono, monospace; + } + code, + tt { + background-color: var(--message-bg); + border-radius: 6px; + font-size: 85%; + margin: 0; + padding: 0.2em 0.4em; + white-space: break-spaces; + } + pre { + margin-bottom: 0; + } + h1, + h2, + h3, + h4, + h5, + h6 { + font-weight: 600; + line-height: 1.8; + margin: 0.6em 0; + } + + h1 { + font-size: 1.3em; + } + + h2 { + font-size: 1.15em; + } + + h3, + h4, + h5 { + font-size: 1em; + } + a { + background-color: transparent; + color: var(--color-primary-hover); + text-decoration: none; + &:hover { + text-decoration: underline; + } + &:focus { + box-shadow: none; + outline: 2px solid var(--color-primary-hover); + outline-offset: -2px; + } + } + img { + width: 100%; + max-width: 320px; + height: auto; + cursor: pointer; + } + img[align="right"] { + padding-left: 20px; + } + + img[align="left"] { + padding-right: 20px; + } + + blockquote { + color: var(--blockquote-color); + border-left: 3px solid var(--color-scrollbar); + margin: 8px 0px; + padding: 0px 10px; + } + .intel-highlighter { + width: 100%; + border-radius: 4px; + overflow: hidden; + margin-top: 16px; + margin-bottom: 12px; + .header-wrap { + align-items: center; + background-color: var(--code-header-bg); + color: var(--code-header-font); + display: flex; + align-items: center; + justify-content: space-between; + font-size: 14px; + height: 32px; + padding: 0 14px; + .copy-icon { + display: block; + color: var(--font-main-color); + cursor: pointer; + &:hover { + color: var(--color-primary); + } + } + .success-icon { + display: none; + color: var(--color-success); + } + } + .content-wrap { + overflow-x: auto; + background: var(--code-content-bg); + padding: 16px; + font-size: 13px; + margin-top: 0; + color: var(--font-main-color); + } + } +} diff --git a/evals/evaluation/rag_pilot/ui/src/theme/variables.less b/evals/evaluation/rag_pilot/ui/src/theme/variables.less new file mode 100644 index 00000000..2d3bef50 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/theme/variables.less @@ -0,0 +1,126 @@ +:root { + --body-font-family: "IntelOneTextNormal", system-ui, Segoe UI, Helvetica, + sans-serif; + --header-font-family: "IntelOneDisplayNormal"; + --color-white: #ffffff; + --color-primary: #00377c; + --color-primary-hover: #056af8; + --color-primary-tip: #3b82f6; + --color-primary-second: #1677ff; + --color-deep-primaryBg: #bfdbfe; + --color-primaryBg: #e0eaff; + --color-second-primaryBg: #e6f0ff80; + --color-error: #ce0000; + --color-error-hover: #ff5d52; + --color-errorBg: #ffa3a3; + --color-info: #aaaaaa; + --color-infoBg: #f3f4f6; + --color-success: #179958; + --color-successBg: #d6ffe8; + --color-second-successBg: #f0fdf4; + --color-warning: #faad14; + --color-second-warning: #854d0e; + --color-warningBg: #feefd0; + --color-second-warningBg: #fefce8; + --color-purple: #9333ea; + --color-purpleBg: #faf5ff; + --color-big-icon: #111111; + --bg-main-color: #f9fafb; + --bg-second-color: #f5f5f5; + --bg-card-color: var(--color-white); + --bg-second-card-bg: var(--color-white); + --bg-loading-color: rgba(0, 0, 0, 0.3); + --bg-content-color: var(--color-white); + --font-main-color: #333333; + --font-text-color: #595959; + --font-info-color: #808080; + --font-tip-color: #999999; + --bg-scrollbar: #dddddd; + --bg-scrollbar-hover: #bbbbbb; + --bg-box-shadow: rgba(0, 0, 0, 0.05); + --bg-gradient-shadow: 0px 4px 6px -4px rgba(0, 0, 0, 0.1), + 0px 10px 15px -3px rgba(0, 0, 0, 0.1); + --menu-bg: var(--bg-main-color); + --color-switch-theme: #e5e7eb; + --think-done-icon: #356bfd; + --think-done-bg: linear-gradient(180deg, #f3f5fc 30%, #ffffff 100%); + --font-think-color: #5e5e5e; + --face-icon-bg: #a6a6a6; + --bg-switch: var(--color-primaryBg); + --bg-primary-linear: linear-gradient(135deg, #e0eaff 0%, #ffffff 100%); + + //่พนๆก† + --border-main-color: #e5e7eb; + --border-warning: #f8e9ca; + --border-success: #c8f7e0; + --border-primary: #bfdbfe; + --border-purple: #d5daf8; + --border-info: #d9d9d9; + + //้ป‘่‰ฒๆŒ‰้’ฎ + --bg-black-color: #434343; + --bg-black-hover-color: #595959; + --bg-black-active-color: #262626; + --border-black-color: #434343; + + //mdๆ˜พ็คบ + --code-header-bg: #dddddd; + --code-header-font: #2c2c36; + --code-content-bg: #f0f0f0; + --table-th-bg: #dddddd; + --table-td-bg: #f0f0f0; + --blockquote-color: var(--font-info-color); +} + +[data-theme="dark"] { + --bg-main-color: #1e1e1e; + --bg-second-color: #1e1e1e; + --bg-card-color: #2d2d2d; + --bg-loading-color: rgba(255, 255, 255, 0.45); + --bg-content-color: #141414; + --font-main-color: #ffffff; + --font-text-color: #e9e9e9; + --font-info-color: #aeaeae; + --font-tip-color: #aeaeae; + --bg-scrollbar: #595959; + --bg-scrollbar-hover: #666666; + --color-primary: #0054ae; + --color-primary-hover: #1668dc; + --color-primaryBg: #e0eaff; + --color-second-primaryBg: #4597fc33; + --bg-box-shadow: rgba(255, 255, 255, 0.1); + --bg-gradient-shadow: 0px 4px 6px -4px rgba(255, 255, 255, 0.1), + 0px 5px 8px 1px rgba(255, 255, 255, 0.1); + --menu-bg: #3e3e3e; + --color-big-icon: #ffffff; + --bg-second-card-bg: #111111; + --color-switch-theme: #1668dc80; + --think-done-bg: linear-gradient(180deg, #32313a 30%, #2d2d2d 100%); + --font-think-color: #e0ecffcc; + --bg-switch: var(--bg-card-color); + + --color-purpleBg: #9333ea4d; + --color-second-successBg: #1799584d; + //่พนๆก† + --border-main-color: #3b3b3b; + --border-warning: #f8e9ca; + --border-success: #d7f8e8; + --border-primary: #bfdbfe; + --border-purple: #d5daf8; + + //้ป‘่‰ฒๆŒ‰้’ฎ + --bg-black-color: #434343; + --bg-black-hover-color: #595959; + --bg-black-active-color: #262626; + --border-black-color: #434343; + //mdๆ˜พ็คบ + --code-header-bg: #585a73; + --code-header-font: #fafafc; + --code-content-bg: #2c2c36; + --table-th-bg: #585a73; + --table-td-bg: #2c2c36; + --blockquote-color: var(--bg-scrollbar-hover); +} + +@use "ant-design-vue/es/style/themes/default.less"; +@use "ant-design-vue/es/style/themes/dark.less"; diff --git a/evals/evaluation/rag_pilot/ui/src/types/axios.d.ts b/evals/evaluation/rag_pilot/ui/src/types/axios.d.ts new file mode 100644 index 00000000..91a3d6b6 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/types/axios.d.ts @@ -0,0 +1,21 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +import "axios"; + +// extend axios type +declare module "axios" { + export interface AxiosResponse { + code: number; + data: T; + message: string; + type?: string; + showLoading?: boolean; + showSuccessMsg?: boolean; + successMsg?: string; + [key: string]: T; + } + export interface AxiosRequestConfig { + [key: string]: T; + } +} diff --git a/evals/evaluation/rag_pilot/ui/src/types/global.d.ts b/evals/evaluation/rag_pilot/ui/src/types/global.d.ts new file mode 100644 index 00000000..81f8cf57 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/types/global.d.ts @@ -0,0 +1,126 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +// Declaration of External npm Plugin Modules +declare module "js-cookie"; +declare module "qs"; +declare module "vite-plugin-vue-setup-extend-plus"; +declare module "vue3-markdown-it"; +declare module "event-source-polyfill"; +declare module "@kangc/v-md-editor/lib/preview"; +declare module "prismjs"; + +// Declaration module to prevent errors when importing files +declare module "*.json"; +declare module "*.png"; +declare module "*.jpg"; +declare module "*.less"; +declare module "*.ts"; +declare module "*.js"; +declare module "lodash"; + +// Declaration vue file +declare module "*.vue" { + import type { DefineComponent } from "vue"; + const component: DefineComponent<{}, {}, any>; + export default component; +} + +// Global Variable +/* eslint-disable */ +declare interface Window { + nextLoading: boolean; + BMAP_SATELLITE_MAP: any; + BMap: any; +} + +// Declaration Router +declare type RouteItem = { + path: string; + name?: string | symbol | undefined | null; + redirect?: string; + k?: T; + meta?: { + title?: string; + isHide?: boolean; + isKeepAlive?: boolean; + roles?: string[]; + loading?: boolean; + }; + children: T[]; + query?: { [key: string]: T }; + params?: { [key: string]: T }; + contextMenuClickId?: string | number; + commonUrl?: string; + isFnClick?: boolean; + url?: string; + transUrl?: string; + title?: string; + id?: string | number; +}; + +// Route to from +declare interface RouteToFrom extends RouteItem { + path?: string; + children?: T[]; +} + +// RouteItems +declare type RouteItems = T[]; + +// ref +declare type RefType = T | null; + +// HTMLElement +declare type HtmlType = HTMLElement | string | undefined | null; + +// Array +declare type EmptyArrayType = T[]; + +// Object +declare type EmptyObjectType = { + [key: string]: T; +}; + +// Select option +declare type SelectOptionType = { + value: string | number; + label: string | number; +}; + +// Table +declare interface TableType { + total: number; + data: T[]; + param: { + pageNum: number; + pageSize: number; + [key: string]: T; + }; +} + +// Table Pagination +declare interface paginationType { + total: number; + pageNum: number; + pageSize: number; + [key: string]: T; +} + +// Table Columns +declare type TableColumns = { + title: string; + key?: string; + dataIndex: string | string[]; + width?: string | number; + align?: string; + ellipsis?: booleanstring; + fixed?: boolean | string; + [key: string]: T; +}; + +// Dialog +declare interface DialogType { + visible: boolean; + [key: string]: T; +} diff --git a/evals/evaluation/rag_pilot/ui/src/utils/antTheme.ts b/evals/evaluation/rag_pilot/ui/src/utils/antTheme.ts new file mode 100644 index 00000000..c642e78c --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/utils/antTheme.ts @@ -0,0 +1,62 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +import { theme } from "ant-design-vue"; +export const antTheme = { + black: { + token: { + colorPrimary: "#111111", + }, + }, + subTheme: { + token: { + colorPrimary: "#0054AE", + }, + }, + success: { + token: { + colorPrimary: "#008A00", + }, + }, + danger: { + token: { + colorPrimary: "#ce0000", + }, + }, + light: { + algorithm: theme.defaultAlgorithm, + inherit: false, + token: { + colorPrimary: "#00377C", + colorPrimaryBg: "#E0EAFF", + colorError: "#EA0000", + colorInfo: "#AAAAAA", + colorSuccess: "#179958", + colorWarning: "#faad14", + colorTextBase: "#131313", + colorSuccessBg: "#D6FFE8", + colorWarningBg: "#feefd0", + colorErrorBg: "#FFA3A3", + colorInfoBg: "#EEEEEE", + }, + cssVar: true, + }, + dark: { + algorithm: theme.darkAlgorithm, + inherit: false, + // token: { + // colorPrimary: "#0054ae", + // colorPrimaryBg: "#0068B5", + // colorError: "#EA0000", + // colorInfo: "#AAAAAA", + // colorSuccess: "#179958", + // colorWarning: "#faad14", + // colorTextBase: "#ffffff", + // colorSuccessBg: "#D6FFE8", + // colorWarningBg: "#feefd0", + // colorErrorBg: "#FFA3A3", + // colorInfoBg: "#EEEEEE", + // }, + cssVar: true, + }, +}; diff --git a/evals/evaluation/rag_pilot/ui/src/utils/common.ts b/evals/evaluation/rag_pilot/ui/src/utils/common.ts new file mode 100644 index 00000000..4626a796 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/utils/common.ts @@ -0,0 +1,110 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +import { inject } from "vue"; +import { customNotification } from "./notification"; + +export const useNotification = () => { + const customNotificationInjected = + inject("customNotification"); + + if (!customNotificationInjected) { + throw new Error("Notification service not provided"); + } + return { + antNotification: customNotificationInjected, + }; +}; + +export const formatDecimals = (num: number, decimalPlaces: number = 2) => { + const factor = Math.pow(10, decimalPlaces); + return Math.round(num * factor) / factor; +}; + +export const formatPercentage = ( + value: number, + precision: number = 2 +): string => { + const num = value * 100; + return `${num.toFixed(precision)}%`; +}; + +export const formatCapitalize = ( + string: string, + start: number = 0, + length: number = 1 +) => { + const end = start + length; + const part1 = string.slice(0, start); + const part2 = string.slice(start, end).toUpperCase(); + const part3 = string.slice(end); + return part1 + part2 + part3; +}; + +/** + * Convert text to uppercase letters + * * @param preserveSpaces keep consecutive spaces + * * @param keepOriginalCase Maintain non initial capitalization + */ +export const formatTextStrict = ( + str: string, + options?: { + preserveSpaces?: boolean; + keepOriginalCase?: boolean; + } +): string => { + const { preserveSpaces = true, keepOriginalCase = false } = options || {}; + + // replace _ and - + let processed = str.replace(/[_-]/g, " "); + + if (!preserveSpaces) { + processed = processed.replace(/\s+/g, " "); + } + return processed + .split(preserveSpaces ? /(\s+)/ : /\s+/) + .map((segment) => { + if (segment.trim() === "") { + return segment; + } + const firstChar = segment.charAt(0).toUpperCase(); + const restChars = keepOriginalCase + ? segment.slice(1) + : segment.slice(1).toLowerCase(); + return firstChar + restChars; + }) + .join(""); +}; + +export const transformTunerName = (name: String) => { + let result = name.replace(/Tuner/g, ""); + result = result.replace(/([A-Z])/g, " $1").trim(); + + return result; +}; + +/** + * @param data + * @param filename + */ +export const downloadJson = ( + data: object | string, + filename: string = "ground_truth.json" +) => { + const jsonStr: string = + typeof data === "string" ? data : JSON.stringify(data, null, 2); + + const blob: Blob = new Blob([jsonStr], { type: "application/json" }); + + const url: string = URL.createObjectURL(blob); + + const a: HTMLAnchorElement = document.createElement("a"); + a.href = url; + a.download = filename; + document.body.appendChild(a); + a.click(); + + // ๆธ…็† + document.body.removeChild(a); + URL.revokeObjectURL(url); +}; diff --git a/evals/evaluation/rag_pilot/ui/src/utils/customRenderer.ts b/evals/evaluation/rag_pilot/ui/src/utils/customRenderer.ts new file mode 100644 index 00000000..305c6a4d --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/utils/customRenderer.ts @@ -0,0 +1,134 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +import { marked } from "marked"; +import hljs from "highlight.js"; +import { formatCapitalize } from "./common"; +import ClipboardJS from "clipboard"; +import { message } from "ant-design-vue"; + +interface CodeRenderParams { + text: string; + lang?: string; +} + +class ClipboardManager { + private clipboard: ClipboardJS | null = null; + private observer: MutationObserver | null = null; + + constructor() { + this.autoInit(); + } + + private autoInit() { + if (typeof document === "undefined") return; + const init = () => { + this.init(".copy-btn"); + this.setupMutationObserver(); + }; + + if (document.readyState === "complete") { + init(); + } else { + document.addEventListener("DOMContentLoaded", init); + } + } + + private init(selector: string) { + this.destroy(); + + this.clipboard = new ClipboardJS(selector, { container: document.body }); + + this.clipboard.on("success", (e) => this.handleSuccess(e)); + this.clipboard.on("error", (e) => this.handleError(e)); + } + + private setupMutationObserver() { + this.observer = new MutationObserver((mutations) => { + const hasNewButtons = mutations.some((mutation) => + Array.from(mutation.addedNodes).some( + (node) => + node instanceof HTMLElement && + (node.matches(".copy-btn") || node.querySelector(".copy-btn")) + ) + ); + if (hasNewButtons) this.init(".copy-btn"); + }); + + this.observer.observe(document.body, { + childList: true, + subtree: true, + }); + } + + destroy() { + this.clipboard?.destroy(); + this.observer?.disconnect(); + this.clipboard = null; + this.observer = null; + } + + private handleSuccess(e: ClipboardJS.Event) { + e.clearSelection(); + message.success("Copy Successful !"); + const button = e.trigger as HTMLElement; + const copyIcon = button.querySelector(".copy-icon") as HTMLElement; + const successIcon = button.querySelector(".success-icon") as HTMLElement; + + copyIcon.style.display = "none"; + successIcon.style.display = "block"; + + let timeout = null; + if (timeout) clearTimeout(timeout); + + timeout = setTimeout(() => { + copyIcon.style.display = "block"; + successIcon.style.display = "none"; + }, 2000); + } + + private handleError(e: ClipboardJS.Event) { + message.error("Copy Failure !"); + } +} + +export const clipboardManager = new ClipboardManager(); + +const createCustomRenderer = () => { + const renderer = new marked.Renderer(); + + renderer.link = ({ href, title, text }) => { + return `${text}`; + }; + + renderer.code = ({ text, lang }: CodeRenderParams) => { + const language = hljs.getLanguage(lang || "") ? lang : "plaintext"; + const codeTitle = formatCapitalize(language || "Code"); + const codeHtml = hljs.highlight(text, { + language: language || "plaintext", + }).value; + const uniqueId = `code-${Date.now()}-${Math.random() + .toString(16) + .slice(2)}`; + + return ` +
+
+ ${codeTitle} + + + + +
+
${codeHtml}
+
+ `; + }; + + return renderer; +}; + +const CustomRenderer = createCustomRenderer(); +export default CustomRenderer; diff --git a/evals/evaluation/rag_pilot/ui/src/utils/loading.ts b/evals/evaluation/rag_pilot/ui/src/utils/loading.ts new file mode 100644 index 00000000..e0be1ba8 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/utils/loading.ts @@ -0,0 +1,46 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +import { nextTick } from "vue"; +import "@/theme/loading.less"; + +/** + * Global Loading + * @method start create loading + * @method done remove loading + */ +export const NextLoading = { + start: () => { + const bodys: Element = document.body; + const div = document.createElement("div"); + div.setAttribute("class", "loading-next"); + const htmls = ` +
+
+
+
+
+
+
+
+
+
+
+
+
+ `; + div.innerHTML = htmls; + bodys.insertBefore(div, bodys.childNodes[0]); + window.nextLoading = true; + }, + + done: (time: number = 0) => { + nextTick(() => { + setTimeout(() => { + window.nextLoading = false; + const el = document.querySelector(".loading-next"); + el?.parentNode?.removeChild(el); + }, time); + }); + }, +}; diff --git a/evals/evaluation/rag_pilot/ui/src/utils/mitt.ts b/evals/evaluation/rag_pilot/ui/src/utils/mitt.ts new file mode 100644 index 00000000..70ff2988 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/utils/mitt.ts @@ -0,0 +1,8 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +import mitt, { Emitter } from "mitt"; + +const eventBus = mitt(); + +export default eventBus; diff --git a/evals/evaluation/rag_pilot/ui/src/utils/notification.ts b/evals/evaluation/rag_pilot/ui/src/utils/notification.ts new file mode 100644 index 00000000..04c5a7be --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/utils/notification.ts @@ -0,0 +1,47 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +import { + CheckCircleFilled, + CloseCircleFilled, + ExclamationCircleFilled, + InfoCircleFilled, +} from "@ant-design/icons-vue"; +import { notification } from "ant-design-vue"; +interface NotificationIcon { + icon: any; + color: string; +} + +const getNotificationIcon = (type: string): NotificationIcon => { + switch (type) { + case "success": + return { icon: CheckCircleFilled, color: "--color-success" }; + case "error": + return { icon: CloseCircleFilled, color: "--color-error" }; + case "warning": + return { icon: ExclamationCircleFilled, color: "--color-warning" }; + case "info": + return { icon: InfoCircleFilled, color: "--color-info" }; + default: + return { icon: null, color: "" }; + } +}; + +export const customNotification = ( + type: "success" | "warning" | "error" | "info", + message: string, + description: string +) => { + const { icon, color } = getNotificationIcon(type); + + const styledIcon = icon + ? h(icon, { style: { color: `var(${color})` } }) + : null; + + notification[type]({ + message: message, + description: description, + icon: styledIcon, + }); +}; diff --git a/evals/evaluation/rag_pilot/ui/src/utils/other.ts b/evals/evaluation/rag_pilot/ui/src/utils/other.ts new file mode 100644 index 00000000..77538582 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/utils/other.ts @@ -0,0 +1,24 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +import serviceManager from "@/utils/serviceManager"; +import { ConfigProvider, notification } from "ant-design-vue"; +import type { App } from "vue"; +import { customNotification } from "./notification"; +import FormTooltip from "@/components/FormTooltip.vue"; +import SvgIcon from "@/components/SvgIcon.vue"; + +//Global Notification +notification.config({ + placement: "topRight", + duration: 5, + maxCount: 3, +}); + +export const antConfig = (app: App) => { + app.component("SvgIcon", SvgIcon); + app.component("FormTooltip", FormTooltip); + app.use(ConfigProvider); + app.provide("customNotification", customNotification); + serviceManager.registerService("antNotification", customNotification); +}; diff --git a/evals/evaluation/rag_pilot/ui/src/utils/serviceManager.ts b/evals/evaluation/rag_pilot/ui/src/utils/serviceManager.ts new file mode 100644 index 00000000..deb4c191 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/utils/serviceManager.ts @@ -0,0 +1,39 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +type ServiceMap = { + antNotification: ( + type: "success" | "warning" | "error" | "info", + message: string, + description?: string + ) => void; +}; + +class ServiceManager { + private static instance: ServiceManager; + private services: { [P in keyof ServiceMap]?: ServiceMap[P] } = {}; + + private constructor() {} + + public static getInstance(): ServiceManager { + if (!ServiceManager.instance) { + ServiceManager.instance = new ServiceManager(); + } + return ServiceManager.instance; + } + + public registerService( + name: K, + service: ServiceMap[K] + ): void { + this.services[name] = service; + } + + public getService( + name: K + ): ServiceMap[K] | undefined { + return this.services[name]; + } +} + +export default ServiceManager.getInstance(); diff --git a/evals/evaluation/rag_pilot/ui/src/utils/storage.ts b/evals/evaluation/rag_pilot/ui/src/utils/storage.ts new file mode 100644 index 00000000..2c5e6bd8 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/utils/storage.ts @@ -0,0 +1,64 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +import Cookies from "js-cookie"; + +/** + * window.localStorage + * @method set + * @method get + * @method remove + * @method clear + */ +export const Local = { + setKey(key: string) { + return `${key}`; + }, + + set(key: string, val: T) { + window.localStorage.setItem(Local.setKey(key), JSON.stringify(val)); + }, + + get(key: string) { + let json = window.localStorage.getItem(Local.setKey(key)); + return JSON.parse(json); + }, + + remove(key: string) { + window.localStorage.removeItem(Local.setKey(key)); + }, + + clear() { + window.localStorage.clear(); + }, +}; + +/** + * window.sessionStorage + * @method set + * @method get + * @method remove + * @method clear + */ +export const Session = { + set(key: string, val: T) { + if (key === "token") return Cookies.set(key, val); + window.sessionStorage.setItem(Local.setKey(key), JSON.stringify(val)); + }, + + get(key: string) { + if (key === "token") return Cookies.get(key); + let json = window.sessionStorage.getItem(Local.setKey(key)); + return JSON.parse(json); + }, + + remove(key: string) { + if (key === "token") return Cookies.remove(key); + window.sessionStorage.removeItem(Local.setKey(key)); + }, + + clear() { + Cookies.remove("token"); + window.sessionStorage.clear(); + }, +}; diff --git a/evals/evaluation/rag_pilot/ui/src/views/error/404.vue b/evals/evaluation/rag_pilot/ui/src/views/error/404.vue new file mode 100644 index 00000000..4683c892 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/views/error/404.vue @@ -0,0 +1,44 @@ + + + + + diff --git a/evals/evaluation/rag_pilot/ui/src/views/home/components/EnterDrawer.vue b/evals/evaluation/rag_pilot/ui/src/views/home/components/EnterDrawer.vue new file mode 100644 index 00000000..d2d829d3 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/views/home/components/EnterDrawer.vue @@ -0,0 +1,376 @@ + + + diff --git a/evals/evaluation/rag_pilot/ui/src/views/home/index.vue b/evals/evaluation/rag_pilot/ui/src/views/home/index.vue new file mode 100644 index 00000000..478a539f --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/views/home/index.vue @@ -0,0 +1,278 @@ + + + + + diff --git a/evals/evaluation/rag_pilot/ui/src/views/tuner/components/DetailDrawer.vue b/evals/evaluation/rag_pilot/ui/src/views/tuner/components/DetailDrawer.vue new file mode 100644 index 00000000..288fd8b6 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/views/tuner/components/DetailDrawer.vue @@ -0,0 +1,267 @@ + + + diff --git a/evals/evaluation/rag_pilot/ui/src/views/tuner/components/Generation.vue b/evals/evaluation/rag_pilot/ui/src/views/tuner/components/Generation.vue new file mode 100644 index 00000000..efcf8068 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/views/tuner/components/Generation.vue @@ -0,0 +1,148 @@ + + + + + diff --git a/evals/evaluation/rag_pilot/ui/src/views/tuner/components/GenerationResults.vue b/evals/evaluation/rag_pilot/ui/src/views/tuner/components/GenerationResults.vue new file mode 100644 index 00000000..5189c64a --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/views/tuner/components/GenerationResults.vue @@ -0,0 +1,461 @@ + + + + + diff --git a/evals/evaluation/rag_pilot/ui/src/views/tuner/components/Postprocess.vue b/evals/evaluation/rag_pilot/ui/src/views/tuner/components/Postprocess.vue new file mode 100644 index 00000000..3152c4f3 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/views/tuner/components/Postprocess.vue @@ -0,0 +1,890 @@ + + + + + diff --git a/evals/evaluation/rag_pilot/ui/src/views/tuner/components/Prompt.vue b/evals/evaluation/rag_pilot/ui/src/views/tuner/components/Prompt.vue new file mode 100644 index 00000000..884378e6 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/views/tuner/components/Prompt.vue @@ -0,0 +1,192 @@ + + + + + diff --git a/evals/evaluation/rag_pilot/ui/src/views/tuner/components/QueryMenu.vue b/evals/evaluation/rag_pilot/ui/src/views/tuner/components/QueryMenu.vue new file mode 100644 index 00000000..0b68b551 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/views/tuner/components/QueryMenu.vue @@ -0,0 +1,178 @@ + + + + + diff --git a/evals/evaluation/rag_pilot/ui/src/views/tuner/components/Rating.vue b/evals/evaluation/rag_pilot/ui/src/views/tuner/components/Rating.vue new file mode 100644 index 00000000..821b6423 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/views/tuner/components/Rating.vue @@ -0,0 +1,324 @@ + + + + + diff --git a/evals/evaluation/rag_pilot/ui/src/views/tuner/components/Results.vue b/evals/evaluation/rag_pilot/ui/src/views/tuner/components/Results.vue new file mode 100644 index 00000000..94e85836 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/views/tuner/components/Results.vue @@ -0,0 +1,347 @@ + + + + + diff --git a/evals/evaluation/rag_pilot/ui/src/views/tuner/components/Retrieve.vue b/evals/evaluation/rag_pilot/ui/src/views/tuner/components/Retrieve.vue new file mode 100644 index 00000000..39f99dbc --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/views/tuner/components/Retrieve.vue @@ -0,0 +1,897 @@ + + + + + diff --git a/evals/evaluation/rag_pilot/ui/src/views/tuner/components/TunerLoading.vue b/evals/evaluation/rag_pilot/ui/src/views/tuner/components/TunerLoading.vue new file mode 100644 index 00000000..faae5b06 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/views/tuner/components/TunerLoading.vue @@ -0,0 +1,66 @@ + + + + + diff --git a/evals/evaluation/rag_pilot/ui/src/views/tuner/components/UpdateDrawer.vue b/evals/evaluation/rag_pilot/ui/src/views/tuner/components/UpdateDrawer.vue new file mode 100644 index 00000000..d8cc30fc --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/views/tuner/components/UpdateDrawer.vue @@ -0,0 +1,109 @@ + + + diff --git a/evals/evaluation/rag_pilot/ui/src/views/tuner/components/index.ts b/evals/evaluation/rag_pilot/ui/src/views/tuner/components/index.ts new file mode 100644 index 00000000..01f4a300 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/views/tuner/components/index.ts @@ -0,0 +1,26 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +import Retrieve from "./Retrieve.vue"; +import Rating from "./Rating.vue"; +import Postprocess from "./Postprocess.vue"; +import Generation from "./Generation.vue"; +import Results from "./Results.vue"; +import DetailDrawer from "./DetailDrawer.vue"; +import TunerLoading from "./TunerLoading.vue"; +import QueryMenu from "./QueryMenu.vue"; +import GenerationResults from "./GenerationResults.vue"; +import Prompt from "./Prompt.vue"; + +export { + DetailDrawer, + Retrieve, + Rating, + Postprocess, + Generation, + Results, + TunerLoading, + QueryMenu, + GenerationResults, + Prompt, +}; diff --git a/evals/evaluation/rag_pilot/ui/src/views/tuner/index.vue b/evals/evaluation/rag_pilot/ui/src/views/tuner/index.vue new file mode 100644 index 00000000..ec6da09b --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/views/tuner/index.vue @@ -0,0 +1,169 @@ + + + + + diff --git a/evals/evaluation/rag_pilot/ui/src/views/tuner/type.ts b/evals/evaluation/rag_pilot/ui/src/views/tuner/type.ts new file mode 100644 index 00000000..7e8a066c --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/views/tuner/type.ts @@ -0,0 +1,38 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +export interface ContextItem { + context_idx: number; + file_name: string; + text: string; + metadata?: EmptyObjectType; + hitRetrieveContexts?: EmptyArrayType; + [key: string]: any; +} + +export interface ResultOut { + index?: number; + query_id: number; + query: string; + response?: string; + metadata?: EmptyObjectType; + ground_truth?: string; + gt_contexts: ContextItem[]; + retrieval_contexts?: ContextItem[]; + postprocessing_contexts?: ContextItem[]; + base?: EmptyObjectType; + [key: string]: any; +} + +export interface ResultsOut { + metadata?: EmptyObjectType; + results: ResultOut[]; + [key: string]: any; +} + +export interface TunerOut { + stage: string; + name: string; + targets: string; + active: boolean; +} diff --git a/evals/evaluation/rag_pilot/ui/src/vite-env.d.ts b/evals/evaluation/rag_pilot/ui/src/vite-env.d.ts new file mode 100644 index 00000000..465d38cd --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/src/vite-env.d.ts @@ -0,0 +1,4 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +/// diff --git a/evals/evaluation/rag_pilot/ui/tsconfig.app.json b/evals/evaluation/rag_pilot/ui/tsconfig.app.json new file mode 100644 index 00000000..b07df7b0 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/tsconfig.app.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + }, + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "ES2020", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "skipLibCheck": true, + + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "preserve", + + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"] +} diff --git a/evals/evaluation/rag_pilot/ui/tsconfig.json b/evals/evaluation/rag_pilot/ui/tsconfig.json new file mode 100644 index 00000000..1ffef600 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/tsconfig.json @@ -0,0 +1,7 @@ +{ + "files": [], + "references": [ + { "path": "./tsconfig.app.json" }, + { "path": "./tsconfig.node.json" } + ] +} diff --git a/evals/evaluation/rag_pilot/ui/tsconfig.node.json b/evals/evaluation/rag_pilot/ui/tsconfig.node.json new file mode 100644 index 00000000..c921d974 --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/tsconfig.node.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "target": "ES2022", + "lib": ["ES2023"], + "module": "ESNext", + "skipLibCheck": true, + + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/evals/evaluation/rag_pilot/ui/vite.config.ts b/evals/evaluation/rag_pilot/ui/vite.config.ts new file mode 100644 index 00000000..ff27303a --- /dev/null +++ b/evals/evaluation/rag_pilot/ui/vite.config.ts @@ -0,0 +1,79 @@ +// Copyright (C) 2025 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +import vue from "@vitejs/plugin-vue"; +import path, { resolve } from "path"; +import AutoImport from "unplugin-auto-import/vite"; +import { AntDesignVueResolver } from "unplugin-vue-components/resolvers"; +import Components from "unplugin-vue-components/vite"; +import { ConfigEnv, defineConfig } from "vite"; +import viteCompression from "vite-plugin-compression"; + +const pathResolve = (dir: string) => { + return resolve(__dirname, ".", dir); +}; + +const alias: Record = { + "@": pathResolve("./src/"), + "vue-i18n": "vue-i18n/dist/vue-i18n.cjs.js", +}; + +const viteConfig = defineConfig((mode: ConfigEnv) => { + return { + plugins: [ + vue(), + viteCompression(), + AutoImport({ + imports: ["vue", "vue-router", "pinia"], + dts: "src/auto-imports.d.ts", + resolvers: [AntDesignVueResolver()], + }), + Components({ + resolvers: [ + AntDesignVueResolver({ + importStyle: false, // css in js + }), + ], + }), + ], + root: process.cwd(), + resolve: { alias }, + server: { + host: "0.0.0.0", + port: 7777, + hmr: true, + // proxy: { + // '/api': { + // target: 'http://10.67.106.236:16010', + // ws: true, + // changeOrigin: true, + // rewrite: (path) => path.replace(/^\/api/, ''), + // }, + // }, + }, + build: { + outDir: "dist", + chunkSizeWarningLimit: 1500, + rollupOptions: { + output: { + chunkFileNames: "assets/js/[name]-[hash].js", + entryFileNames: "assets/js/[name]-[hash].js", + assetFileNames: "assets/[ext]/[name]-[hash].[ext]", + }, + }, + }, + css: { + preprocessorOptions: { + less: { + javascriptEnabled: true, + additionalData: `@import "${path.resolve( + __dirname, + "src/theme/index.less" + )}";`, + }, + }, + }, + }; +}); + +export default viteConfig; diff --git a/tests/requirements.txt b/tests/requirements.txt index bee5612b..ed9ab31e 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -7,3 +7,4 @@ langchain_huggingface lm-eval==0.4.3 openai ragas==0.1.19 +sentence-transformers