From fb3488b16cfad0da98710f198c72cd75e4b542cf Mon Sep 17 00:00:00 2001 From: Dylan Huang Date: Thu, 28 Aug 2025 10:56:31 -0700 Subject: [PATCH 01/18] fix type checks in IDE --- .vscode/extensions.json | 7 +++++++ .vscode/settings.json | 2 +- pyproject.toml | 31 +------------------------------ 3 files changed, 9 insertions(+), 31 deletions(-) create mode 100644 .vscode/extensions.json diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 00000000..3e423b3b --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,7 @@ +{ + "recommendations": [ + "anysphere.cursorpyright", + "ms-python.python", + "ms-python.debugpy" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json index 6ec04673..d82ea0ef 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,5 +5,5 @@ "python.testing.autoTestDiscoverOnSaveEnabled": true, "python.defaultInterpreterPath": "./.venv/bin/python", "python.testing.cwd": "${workspaceFolder}", - "editor.defaultFormatter": "ms-python.black-formatter" + "cursorpyright.analysis.diagnosticMode": "openFilesOnly" } diff --git a/pyproject.toml b/pyproject.toml index d660bb03..214195dc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -204,38 +204,9 @@ known-first-party = ["eval_protocol"] combine-as-imports = true [tool.pyright] -typeCheckingMode = "basic" +typeCheckingMode = "recommended" pythonVersion = "3.10" -reportMissingImports = "none" -reportMissingTypeStubs = "none" -reportMissingModuleSource = "none" include = ["eval_protocol", "examples", "tests"] exclude = ["vite-app", "vendor"] # Ignore diagnostics for vendored generator code ignore = ["versioneer.py"] -# Relax noisy diagnostics commonly triggered in tests and dynamic libs -reportAttributeAccessIssue = "none" -reportCallIssue = "none" -reportUnknownMemberType = "none" -reportUnknownVariableType = "none" -reportPossiblyUnboundVariable = "none" -# Additional suppressions per request -reportOptionalMemberAccess = "none" -reportIndexIssue = "none" -reportReturnType = "none" -reportOptionalCall = "none" -reportGeneralTypeIssues = "none" -reportOperatorIssue = "none" -reportOptionalSubscript = "none" -reportUnsupportedDunderAll = "none" -reportOptionalContextManager = "none" -reportInvalidTypeForm = "none" -reportRedeclaration = "none" -reportUndefinedVariable = "none" -reportPrivateImportUsage = "none" -reportOptionalIterable = "none" -# Make incompatibilities and argument types warnings instead of errors for now -# and suppress warnings output entirely -reportIncompatibleVariableOverride = "none" -reportArgumentType = "none" -reportAssignmentType = "none" From 0ed7b63deb4d350b7ef44f1aaa969edeed4c6cb5 Mon Sep 17 00:00:00 2001 From: Dylan Huang Date: Thu, 28 Aug 2025 11:47:48 -0700 Subject: [PATCH 02/18] convert to basedpyright and temporarily disable in CI --- .github/workflows/ci.yml | 7 ++++++- pyproject.toml | 2 +- uv.lock | 43 ++++++++++++++++++++++++++-------------- 3 files changed, 35 insertions(+), 17 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c1ae24e1..d291b6c0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,7 +49,12 @@ jobs: run: uv run ruff check . - name: Type check with pyright - run: uv run pyright + run: | + # 'set +e' disables immediate exit on error so we can capture and report errors but exit 0 + # Note: We currently suppress pyright failures to allow CI to pass while we iteratively fix all type issues. + # Once all type errors are resolved, we will remove this suppression and enforce strict type checking. + set +e + uv run basedpyright || true test-core: name: Core Tests (Python ${{ matrix.python-version }}) diff --git a/pyproject.toml b/pyproject.toml index 214195dc..c612c7bf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -65,7 +65,6 @@ dev = [ "pytest-httpserver", "werkzeug>=2.0.0", "ruff>=0.5.0", - "pyright>=1.1.365", "transformers>=4.0.0", "types-setuptools", "types-requests", @@ -174,6 +173,7 @@ tau2 = { git = "https://github.com/sierra-research/tau2-bench.git" } [dependency-groups] dev = [ + "basedpyright>=1.31.3", "fastapi[standard]>=0.116.1", "fastmcp>=2.10.6", "haikus==0.3.8", diff --git a/uv.lock b/uv.lock index cfaf01ef..2f053930 100644 --- a/uv.lock +++ b/uv.lock @@ -383,6 +383,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b9/fa/123043af240e49752f1c4bd24da5053b6bd00cad78c2be53c0d1e8b975bc/backports.tarfile-1.2.0-py3-none-any.whl", hash = "sha256:77e284d754527b01fb1e6fa8a1afe577858ebe4e9dad8919e34c862cb399bc34", size = 30181, upload-time = "2024-05-28T17:01:53.112Z" }, ] +[[package]] +name = "basedpyright" +version = "1.31.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nodejs-wheel-binaries" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/64/3e/e5cd03d33a6ddd341427a0fe2fb27944ae11973069a8b880dad99102361b/basedpyright-1.31.3.tar.gz", hash = "sha256:c77bff2dc7df4fe09c0ee198589d8d24faaf8bfd883ee9e0af770b1a275a58f8", size = 22481852, upload-time = "2025-08-20T15:08:25.131Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/e5/edf168b8dd936bb82a97ebb76e7295c94a4f9d1c2e8e8a04696ef2b3a524/basedpyright-1.31.3-py3-none-any.whl", hash = "sha256:bdb0b5a9abe287a023d330fc71eaed181aaffd48f1dec59567f912cf716f38ff", size = 11722347, upload-time = "2025-08-20T15:08:20.528Z" }, +] + [[package]] name = "beautifulsoup4" version = "4.13.4" @@ -1216,7 +1228,6 @@ dev = [ { name = "openai" }, { name = "pip" }, { name = "pre-commit" }, - { name = "pyright" }, { name = "pytest-cov" }, { name = "pytest-httpserver" }, { name = "pytest-xdist" }, @@ -1262,6 +1273,7 @@ trl = [ [package.dev-dependencies] dev = [ + { name = "basedpyright" }, { name = "fastapi", extra = ["standard"] }, { name = "fastmcp" }, { name = "haikus" }, @@ -1318,7 +1330,6 @@ requires-dist = [ { name = "psycopg2-binary", marker = "extra == 'chinook'", specifier = ">=2.9.10" }, { name = "pydantic", specifier = ">=2.0.0" }, { name = "pydantic-ai", marker = "extra == 'pydantic'" }, - { name = "pyright", marker = "extra == 'dev'", specifier = ">=1.1.365" }, { name = "pytest", specifier = ">=6.0.0" }, { name = "pytest-asyncio", specifier = ">=0.21.0" }, { name = "pytest-cov", marker = "extra == 'dev'" }, @@ -1353,6 +1364,7 @@ provides-extras = ["dev", "trl", "openevals", "fireworks", "box2d", "langfuse", [package.metadata.requires-dev] dev = [ + { name = "basedpyright", specifier = ">=1.31.3" }, { name = "fastapi", extras = ["standard"], specifier = ">=0.116.1" }, { name = "fastmcp", specifier = ">=2.10.6" }, { name = "haikus", specifier = "==0.3.8" }, @@ -3494,6 +3506,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314, upload-time = "2024-06-04T18:44:08.352Z" }, ] +[[package]] +name = "nodejs-wheel-binaries" +version = "22.18.0" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/6d/773e09de4a052cc75c129c3766a3cf77c36bff8504a38693b735f4a1eb55/nodejs_wheel_binaries-22.18.0-py2.py3-none-macosx_11_0_arm64.whl", hash = "sha256:53b04495857755c5d5658f7ac969d84f25898fe0b0c1bdc41172e5e0ac6105ca", size = 50873051, upload-time = "2025-08-01T11:10:29.475Z" }, + { url = "https://files.pythonhosted.org/packages/ae/fc/3d6fd4ad5d26c9acd46052190d6a8895dc5050297b03d9cce03def53df0d/nodejs_wheel_binaries-22.18.0-py2.py3-none-macosx_11_0_x86_64.whl", hash = "sha256:bd4d016257d4dfe604ed526c19bd4695fdc4f4cc32e8afc4738111447aa96d03", size = 51814481, upload-time = "2025-08-01T11:10:33.086Z" }, + { url = "https://files.pythonhosted.org/packages/10/f9/7be44809a861605f844077f9e731a117b669d5ca6846a7820e7dd82c9fad/nodejs_wheel_binaries-22.18.0-py2.py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3b125f94f3f5e8ab9560d3bd637497f02e45470aeea74cf6fe60afe751cfa5f", size = 57804907, upload-time = "2025-08-01T11:10:36.83Z" }, + { url = "https://files.pythonhosted.org/packages/e9/67/563e74a0dff653ec7ddee63dc49b3f37a20df39f23675cfc801d7e8e4bb7/nodejs_wheel_binaries-22.18.0-py2.py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78bbb81b6e67c15f04e2a9c6c220d7615fb46ae8f1ad388df0d66abac6bed5f8", size = 58335587, upload-time = "2025-08-01T11:10:40.716Z" }, + { url = "https://files.pythonhosted.org/packages/b6/b1/ec45fefef60223dd40e7953e2ff087964e200d6ec2d04eae0171d6428679/nodejs_wheel_binaries-22.18.0-py2.py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:f5d3ea8b7f957ae16b73241451f6ce831d6478156f363cce75c7ea71cbe6c6f7", size = 59662356, upload-time = "2025-08-01T11:10:44.795Z" }, + { url = "https://files.pythonhosted.org/packages/a2/ed/6de2c73499eebf49d0d20e0704f64566029a3441c48cd4f655d49befd28b/nodejs_wheel_binaries-22.18.0-py2.py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:bcda35b07677039670102a6f9b78c2313fd526111d407cb7ffc2a4c243a48ef9", size = 60706806, upload-time = "2025-08-01T11:10:48.985Z" }, + { url = "https://files.pythonhosted.org/packages/2b/f5/487434b1792c4f28c63876e4a896f2b6e953e2dc1f0b3940e912bd087755/nodejs_wheel_binaries-22.18.0-py2.py3-none-win_amd64.whl", hash = "sha256:0f55e72733f1df2f542dce07f35145ac2e125408b5e2051cac08e5320e41b4d1", size = 39998139, upload-time = "2025-08-01T11:10:52.676Z" }, +] + [[package]] name = "notebook" version = "7.4.4" @@ -5026,19 +5052,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl", hash = "sha256:9e5c6bfa8dcc30091c74b0cf803c81fdd29d94f01992a7707bc97babb1141913", size = 10216, upload-time = "2024-09-29T09:24:11.978Z" }, ] -[[package]] -name = "pyright" -version = "1.1.403" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "nodeenv" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/fe/f6/35f885264ff08c960b23d1542038d8da86971c5d8c955cfab195a4f672d7/pyright-1.1.403.tar.gz", hash = "sha256:3ab69b9f41c67fb5bbb4d7a36243256f0d549ed3608678d381d5f51863921104", size = 3913526, upload-time = "2025-07-09T07:15:52.882Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/49/b6/b04e5c2f41a5ccad74a1a4759da41adb20b4bc9d59a5e08d29ba60084d07/pyright-1.1.403-py3-none-any.whl", hash = "sha256:c0eeca5aa76cbef3fcc271259bbd785753c7ad7bcac99a9162b4c4c7daed23b3", size = 5684504, upload-time = "2025-07-09T07:15:50.958Z" }, -] - [[package]] name = "pysocks" version = "1.7.1" From be9b34a38b345dc7a24a280172737f6246e859a7 Mon Sep 17 00:00:00 2001 From: Dylan Huang Date: Thu, 28 Aug 2025 12:07:57 -0700 Subject: [PATCH 03/18] Update VSCode settings to include default formatter for Ruff --- .vscode/settings.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index d82ea0ef..75bd4bd3 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,5 +5,6 @@ "python.testing.autoTestDiscoverOnSaveEnabled": true, "python.defaultInterpreterPath": "./.venv/bin/python", "python.testing.cwd": "${workspaceFolder}", - "cursorpyright.analysis.diagnosticMode": "openFilesOnly" + "cursorpyright.analysis.diagnosticMode": "openFilesOnly", + "editor.defaultFormatter": "charliermarsh.ruff" } From 16300bbd750b93c4bacbd93ed043dd7ae0136060 Mon Sep 17 00:00:00 2001 From: Dylan Huang Date: Thu, 28 Aug 2025 13:16:08 -0700 Subject: [PATCH 04/18] save --- eval_protocol/pytest/evaluation_test.py | 72 ++++++++++++------------- 1 file changed, 35 insertions(+), 37 deletions(-) diff --git a/eval_protocol/pytest/evaluation_test.py b/eval_protocol/pytest/evaluation_test.py index dc152252..9dcaa321 100644 --- a/eval_protocol/pytest/evaluation_test.py +++ b/eval_protocol/pytest/evaluation_test.py @@ -1,19 +1,14 @@ import asyncio -import copy import inspect import json import math import os import pathlib -import re import statistics import time -from dataclasses import replace -from typing import Any, Callable, Dict, List, Literal, Optional, Union from collections import defaultdict -import hashlib -import ast -from mcp.types import Completion +from typing import Any, Callable + import pytest from eval_protocol.dataset_logger import default_logger @@ -21,7 +16,6 @@ from eval_protocol.human_id import generate_id, num_combinations from eval_protocol.models import ( CompletionParams, - ErrorInfo, EvalMetadata, EvaluationRow, EvaluationThreshold, @@ -32,6 +26,7 @@ from eval_protocol.pytest.default_dataset_adapter import default_dataset_adapter from eval_protocol.pytest.default_mcp_gym_rollout_processor import MCPGymRolloutProcessor from eval_protocol.pytest.default_no_op_rollout_processor import NoOpRolloutProcessor +from eval_protocol.pytest.exception_config import ExceptionHandlerConfig from eval_protocol.pytest.rollout_processor import RolloutProcessor from eval_protocol.pytest.types import ( Dataset, @@ -39,7 +34,6 @@ EvaluationInputParam, EvaluationTestMode, InputMessagesParam, - ModelParam, RolloutProcessorConfig, RolloutProcessorInputParam, TestFunction, @@ -48,29 +42,26 @@ AggregationMethod, aggregate, create_dynamically_parameterized_wrapper, - deep_update_dict, extract_effort_tag, generate_parameter_combinations, log_eval_status_and_rows, - parse_ep_max_rows, + parse_ep_completion_params, parse_ep_max_concurrent_rollouts, + parse_ep_max_rows, parse_ep_num_runs, - parse_ep_completion_params, parse_ep_passed_threshold, rollout_processor_with_retry, sanitize_filename, ) -from eval_protocol.pytest.exception_config import ExceptionHandlerConfig from eval_protocol.stats.confidence_intervals import compute_fixed_set_mu_ci -from eval_protocol.types.types import TerminationReason from ..common_utils import load_jsonl def postprocess( - all_results: List[List[EvaluationRow]], + all_results: list[list[EvaluationRow]], aggregation_method: AggregationMethod, - threshold: Optional[EvaluationThreshold], + threshold: EvaluationThreshold | None, active_logger: DatasetLogger, mode: EvaluationTestMode, completion_params: CompletionParams, @@ -85,6 +76,7 @@ def postprocess( # Compute 95% confidence interval for the fixed-set mean μ (by-question, using repeats) ci_low: float | None = None ci_high: float | None = None + standard_error: float | None = None if aggregation_method == "mean": try: result_ci = compute_fixed_set_mu_ci([item for sublist in all_results for item in sublist]) @@ -127,12 +119,12 @@ def postprocess( should_print = os.getenv("EP_PRINT_SUMMARY") == "1" summary_path = os.getenv("EP_SUMMARY_JSON") suite_name = test_func_name - model_used = completion_params["model"] + model_used = completion_params["model"] # pyright: ignore[reportAny] total_rows = len([item for sublist in all_results for item in sublist]) summary_obj = { "suite": suite_name, "model": model_used, - "agg_score": float(agg_score) if agg_score is not None else None, + "agg_score": float(agg_score), "num_runs": num_runs, "rows": total_rows, } @@ -142,13 +134,13 @@ def postprocess( summary_obj["standard_error"] = standard_error # Aggregate per-metric mean and 95% CI when available - metrics_summary: Dict[str, Dict[str, float]] = {} + metrics_summary: dict[str, dict[str, float]] = {} - metric_scores: Dict[str, list] = defaultdict(list) + metric_scores: dict[str, list[float]] = defaultdict(list) for r in [item for sublist in all_results for item in sublist]: if r.evaluation_result and r.evaluation_result.metrics: for m_name, m_res in r.evaluation_result.metrics.items(): - if m_res is not None and getattr(m_res, "score", None) is not None: + if getattr(m_res, "score", None) is not None: metric_scores[m_name].append(m_res.score) for m_name, vals in metric_scores.items(): if len(vals) == 0: @@ -166,7 +158,7 @@ def postprocess( except Exception: m_low = None m_high = None - entry: Dict[str, float] = {"mean": float(m_mean)} + entry: dict[str, float] = {"mean": float(m_mean)} if m_low is not None and m_high is not None: entry["ci_low"] = float(m_low) entry["ci_high"] = float(m_high) @@ -184,6 +176,8 @@ def postprocess( ) # As per project convention, avoid printing per-metric CI lines to reduce noise if summary_path: + if not isinstance(model_used, str): + raise ValueError(f"Model used is not a string: {model_used}") model_slug = sanitize_filename(model_used) effort_tag = extract_effort_tag(completion_params) or "" effort_suffix = f"__effort-{sanitize_filename(effort_tag)}" if effort_tag else "" @@ -240,29 +234,29 @@ def postprocess( ) -def evaluation_test( # noqa: C901 +def evaluation_test( *, - completion_params: List[CompletionParams] = [None], - input_messages: Optional[List[InputMessagesParam]] = None, - input_dataset: Optional[List[DatasetPathParam]] = None, - input_rows: Optional[List[EvaluationRow]] = None, - dataset_adapter: Callable[[List[Dict[str, Any]]], Dataset] = default_dataset_adapter, - rollout_processor: RolloutProcessor = NoOpRolloutProcessor(), - evaluation_test_kwargs: Optional[List[EvaluationInputParam]] = None, - rollout_processor_kwargs: Optional[RolloutProcessorInputParam] = None, + completion_params: list[CompletionParams | None] | None = None, + input_messages: list[InputMessagesParam] | None = None, + input_dataset: list[DatasetPathParam] | None = None, + input_rows: list[EvaluationRow] | None = None, + dataset_adapter: Callable[[list[dict[str, Any]]], Dataset] = default_dataset_adapter, # pyright: ignore[reportExplicitAny] + rollout_processor: RolloutProcessor | None = None, + evaluation_test_kwargs: list[EvaluationInputParam] | None = None, + rollout_processor_kwargs: RolloutProcessorInputParam | None = None, aggregation_method: AggregationMethod = "mean", - passed_threshold: Optional[Union[EvaluationThreshold, float, dict]] = None, + passed_threshold: EvaluationThreshold | float | dict[str, Any] | None = None, # pyright: ignore[reportExplicitAny] num_runs: int = 1, - max_dataset_rows: Optional[int] = None, - mcp_config_path: Optional[str] = None, + max_dataset_rows: int | None = None, + mcp_config_path: str | None = None, max_concurrent_rollouts: int = 8, max_concurrent_evaluations: int = 64, - server_script_path: Optional[str] = None, + server_script_path: str | None = None, steps: int = 30, mode: EvaluationTestMode = "pointwise", combine_datasets: bool = True, - logger: Optional[DatasetLogger] = None, - exception_handler_config: Optional[ExceptionHandlerConfig] = None, + logger: DatasetLogger | None = None, + exception_handler_config: ExceptionHandlerConfig | None = None, ) -> Callable[ [TestFunction], TestFunction, @@ -343,6 +337,10 @@ def evaluation_test( # noqa: C901 num_runs = parse_ep_num_runs(num_runs) max_concurrent_rollouts = parse_ep_max_concurrent_rollouts(max_concurrent_rollouts) max_dataset_rows = parse_ep_max_rows(max_dataset_rows) + if completion_params is None: + completion_params = [None] + if rollout_processor is None: + rollout_processor = NoOpRolloutProcessor() completion_params = parse_ep_completion_params(completion_params) original_completion_params = completion_params passed_threshold = parse_ep_passed_threshold(passed_threshold) From 320246192a62082f5423e728691d84ef888ae129 Mon Sep 17 00:00:00 2001 From: Dylan Huang Date: Thu, 28 Aug 2025 14:55:25 -0700 Subject: [PATCH 05/18] part 2 --- .vscode/settings.json | 6 +- eval_protocol/models.py | 12 +- eval_protocol/pytest/evaluation_test.py | 174 +++++---------------- eval_protocol/pytest/execution.py | 31 ++++ eval_protocol/pytest/parameterize.py | 67 ++++++++ eval_protocol/pytest/types.py | 35 +++-- eval_protocol/pytest/utils.py | 107 +++++++------ eval_protocol/pytest/validate_signature.py | 50 ++++++ 8 files changed, 282 insertions(+), 200 deletions(-) create mode 100644 eval_protocol/pytest/execution.py create mode 100644 eval_protocol/pytest/parameterize.py create mode 100644 eval_protocol/pytest/validate_signature.py diff --git a/.vscode/settings.json b/.vscode/settings.json index 75bd4bd3..13b13c52 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,5 +6,9 @@ "python.defaultInterpreterPath": "./.venv/bin/python", "python.testing.cwd": "${workspaceFolder}", "cursorpyright.analysis.diagnosticMode": "openFilesOnly", - "editor.defaultFormatter": "charliermarsh.ruff" + "editor.defaultFormatter": "charliermarsh.ruff", + "editor.formatOnSave": true, + "[python]": { + "editor.defaultFormatter": "charliermarsh.ruff" + } } diff --git a/eval_protocol/models.py b/eval_protocol/models.py index 29ee4f57..97eb9041 100644 --- a/eval_protocol/models.py +++ b/eval_protocol/models.py @@ -439,11 +439,19 @@ class EvaluationThreshold(BaseModel): success: float = Field( ..., description="Minimum success rate threshold (fraction of total score, 0.0 to 1.0)", ge=0.0, le=1.0 ) - standard_error: Optional[float] = Field( - None, description="Maximum standard error threshold (fraction of total score, 0.0 to 1.0)", ge=0.0, le=1.0 + standard_error: float | None = Field( + default=None, + description="Maximum standard error threshold (fraction of total score, 0.0 to 1.0)", + ge=0.0, + le=1.0, ) +class EvaluationThresholdDict(TypedDict): + success: float + standard_error: float | None + + class EvalMetadata(BaseModel): """Metadata about the evaluation that was run.""" diff --git a/eval_protocol/pytest/evaluation_test.py b/eval_protocol/pytest/evaluation_test.py index 9dcaa321..54093fde 100644 --- a/eval_protocol/pytest/evaluation_test.py +++ b/eval_protocol/pytest/evaluation_test.py @@ -19,10 +19,13 @@ EvalMetadata, EvaluationRow, EvaluationThreshold, + EvaluationThresholdDict, InputMetadata, Message, Status, ) +from eval_protocol.pytest.parameterize import pytest_parametrize +from eval_protocol.pytest.validate_signature import validate_signature from eval_protocol.pytest.default_dataset_adapter import default_dataset_adapter from eval_protocol.pytest.default_mcp_gym_rollout_processor import MCPGymRolloutProcessor from eval_protocol.pytest.default_no_op_rollout_processor import NoOpRolloutProcessor @@ -38,6 +41,8 @@ RolloutProcessorInputParam, TestFunction, ) + + from eval_protocol.pytest.utils import ( AggregationMethod, aggregate, @@ -237,15 +242,15 @@ def postprocess( def evaluation_test( *, completion_params: list[CompletionParams | None] | None = None, - input_messages: list[InputMessagesParam] | None = None, + input_messages: list[InputMessagesParam | None] | None = None, input_dataset: list[DatasetPathParam] | None = None, input_rows: list[EvaluationRow] | None = None, dataset_adapter: Callable[[list[dict[str, Any]]], Dataset] = default_dataset_adapter, # pyright: ignore[reportExplicitAny] rollout_processor: RolloutProcessor | None = None, - evaluation_test_kwargs: list[EvaluationInputParam] | None = None, + evaluation_test_kwargs: list[EvaluationInputParam | None] | None = None, rollout_processor_kwargs: RolloutProcessorInputParam | None = None, aggregation_method: AggregationMethod = "mean", - passed_threshold: EvaluationThreshold | float | dict[str, Any] | None = None, # pyright: ignore[reportExplicitAny] + passed_threshold: EvaluationThreshold | float | EvaluationThresholdDict | None = None, num_runs: int = 1, max_dataset_rows: int | None = None, mcp_config_path: str | None = None, @@ -257,10 +262,7 @@ def evaluation_test( combine_datasets: bool = True, logger: DatasetLogger | None = None, exception_handler_config: ExceptionHandlerConfig | None = None, -) -> Callable[ - [TestFunction], - TestFunction, -]: +) -> Callable[[TestFunction], TestFunction]: """Decorator to create pytest-based evaluation tests. Here are some key concepts to understand the terminology in EP: @@ -328,6 +330,10 @@ def evaluation_test( exception_handler_config: Configuration for exception handling and backoff retry logic. If not provided, a default configuration will be used with common retryable exceptions. """ + if completion_params is None: + completion_params = [None] + if rollout_processor is None: + rollout_processor = NoOpRolloutProcessor() active_logger: DatasetLogger = logger if logger else default_logger @@ -337,148 +343,40 @@ def evaluation_test( num_runs = parse_ep_num_runs(num_runs) max_concurrent_rollouts = parse_ep_max_concurrent_rollouts(max_concurrent_rollouts) max_dataset_rows = parse_ep_max_rows(max_dataset_rows) - if completion_params is None: - completion_params = [None] - if rollout_processor is None: - rollout_processor = NoOpRolloutProcessor() completion_params = parse_ep_completion_params(completion_params) original_completion_params = completion_params passed_threshold = parse_ep_passed_threshold(passed_threshold) def decorator( test_func: TestFunction, - ): - if passed_threshold is not None: - if isinstance(passed_threshold, float): - threshold = EvaluationThreshold(success=passed_threshold) - else: - threshold = EvaluationThreshold(**passed_threshold) - else: - threshold = None - + ) -> TestFunction: sig = inspect.signature(test_func) - - # For pointwise/groupwise mode, we expect a different signature - # we expect single row to be passed in as the original row - if mode == "pointwise": - # Pointwise mode: function should accept messages and other row-level params - if "row" not in sig.parameters: - raise ValueError("In pointwise mode, your eval function must have a parameter named 'row'") - - # validate that "Row" is of type EvaluationRow - if sig.parameters["row"].annotation is not EvaluationRow: - raise ValueError("In pointwise mode, the 'row' parameter must be of type EvaluationRow") - - # validate that the function has a return type of EvaluationRow - if sig.return_annotation is not EvaluationRow: - raise ValueError("In pointwise mode, your eval function must return an EvaluationRow instance") - - # additional check for groupwise evaluation - elif mode == "groupwise": - if "rows" not in sig.parameters: - raise ValueError("In groupwise mode, your eval function must have a parameter named 'rows'") - - # validate that "Rows" is of type List[EvaluationRow] - if sig.parameters["rows"].annotation is not List[EvaluationRow]: - raise ValueError("In groupwise mode, the 'rows' parameter must be of type List[EvaluationRow") - - # validate that the function has a return type of List[EvaluationRow] - if sig.return_annotation is not List[EvaluationRow]: - raise ValueError("In groupwise mode, your eval function must return a list of EvaluationRow instances") - if len(completion_params) < 2: - raise ValueError("In groupwise mode, you must provide at least 2 completion parameters") - else: - # all mode: function should accept input_dataset and model - if "rows" not in sig.parameters: - raise ValueError("In all mode, your eval function must have a parameter named 'rows'") - - # validate that "Rows" is of type List[EvaluationRow] - if sig.parameters["rows"].annotation is not List[EvaluationRow]: - raise ValueError("In all mode, the 'rows' parameter must be of type List[EvaluationRow") - - # validate that the function has a return type of List[EvaluationRow] - if sig.return_annotation is not List[EvaluationRow]: - raise ValueError("In all mode, your eval function must return a list of EvaluationRow instances") - - async def execute_with_params( - test_func: TestFunction, - processed_row: EvaluationRow | None = None, - processed_dataset: List[EvaluationRow] | None = None, - evaluation_test_kwargs: Optional[EvaluationInputParam] = None, - ): - kwargs = {} - if processed_dataset is not None: - kwargs["rows"] = processed_dataset - if processed_row is not None: - kwargs["row"] = processed_row - if evaluation_test_kwargs is not None: - if "row" in evaluation_test_kwargs: - raise ValueError("'row' is a reserved parameter for the evaluation function") - if "rows" in evaluation_test_kwargs: - raise ValueError("'rows' is a reserved parameter for the evaluation function") - kwargs.update(evaluation_test_kwargs) - - # Handle both sync and async test functions - if asyncio.iscoroutinefunction(test_func): - return await test_func(**kwargs) - else: - return test_func(**kwargs) + validate_signature(sig, mode, completion_params) # Calculate all possible combinations of parameters - if mode == "groupwise": - combinations = generate_parameter_combinations( - input_dataset, - completion_params, - input_messages, - input_rows, - evaluation_test_kwargs, - max_dataset_rows, - combine_datasets, - ) - else: - combinations = generate_parameter_combinations( - input_dataset, - completion_params, - input_messages, - input_rows, - evaluation_test_kwargs, - max_dataset_rows, - combine_datasets, - ) + combinations = generate_parameter_combinations( + input_dataset, + completion_params, + input_messages, + input_rows, + evaluation_test_kwargs, + max_dataset_rows, + combine_datasets, + ) if len(combinations) == 0: raise ValueError( "No combinations of parameters were found. Please provide at least a model and one of input_dataset, input_messages, or input_rows." ) # Create parameter tuples for pytest.mark.parametrize - param_tuples = [] - for combo in combinations: - dataset, cp, messages, rows, etk = combo - param_tuple = [] - if input_dataset is not None: - param_tuple.append(dataset) - if completion_params is not None: - param_tuple.append(cp) - if input_messages is not None: - param_tuple.append(messages) - if input_rows is not None: - param_tuple.append(rows) - if evaluation_test_kwargs is not None: - param_tuple.append(etk) - param_tuples.append(tuple(param_tuple)) - - # For all mode, preserve the original parameter names - test_param_names = [] - if input_dataset is not None: - test_param_names.append("dataset_path") - if completion_params is not None: - test_param_names.append("completion_params") - if input_messages is not None: - test_param_names.append("input_messages") - if input_rows is not None: - test_param_names.append("input_rows") - if evaluation_test_kwargs is not None: - test_param_names.append("evaluation_test_kwargs") + pytest_parametrize_args = pytest_parametrize( + combinations, + input_dataset, + completion_params, + input_messages, + input_rows, + evaluation_test_kwargs, + ) # Create wrapper function with exact signature that pytest expects def create_wrapper_with_signature() -> Callable: @@ -613,7 +511,7 @@ async def _execute_eval_with_semaphore(**inner_kwargs): # NOTE: we will still evaluate errored rows (give users control over this) # i.e., they can choose to give EvaluateResult.score = 0 for errored rows in their test_func if "row" in inner_kwargs: - result = await execute_with_params( + result = await execute_pytest( test_func, processed_row=inner_kwargs["row"], evaluation_test_kwargs=kwargs.get("evaluation_test_kwargs") or {}, @@ -624,7 +522,7 @@ async def _execute_eval_with_semaphore(**inner_kwargs): ) return result if "rows" in inner_kwargs: - results = await execute_with_params( + results = await execute_pytest( test_func, processed_dataset=inner_kwargs["rows"], evaluation_test_kwargs=kwargs.get("evaluation_test_kwargs") or {}, @@ -696,7 +594,7 @@ async def _collect_result(config, lst): input_dataset.append(row) # NOTE: we will still evaluate errored rows (give users control over this) # i.e., they can choose to give EvaluateResult.score = 0 for errored rows in their test_func - results = await execute_with_params( + results = await execute_pytest( test_func, processed_dataset=input_dataset, evaluation_test_kwargs=kwargs.get("evaluation_test_kwargs") or {}, @@ -795,7 +693,7 @@ async def _collect_result(config, lst): # Create the pytest wrapper pytest_wrapper = create_wrapper_with_signature() - pytest_wrapper = pytest.mark.parametrize(test_param_names, param_tuples)(pytest_wrapper) + pytest_wrapper = pytest.mark.parametrize(**pytest_parametrize_args)(pytest_wrapper) pytest_wrapper = pytest.mark.asyncio(pytest_wrapper) def create_dual_mode_wrapper() -> Callable: diff --git a/eval_protocol/pytest/execution.py b/eval_protocol/pytest/execution.py new file mode 100644 index 00000000..5d7ba658 --- /dev/null +++ b/eval_protocol/pytest/execution.py @@ -0,0 +1,31 @@ +import asyncio +from collections.abc import Awaitable +from eval_protocol.models import EvaluationRow +from eval_protocol.pytest.types import EvaluationInputParam, TestFunction + + +async def execute_pytest( + test_func: TestFunction, + processed_row: EvaluationRow | None = None, + processed_dataset: list[EvaluationRow] | None = None, + evaluation_test_kwargs: EvaluationInputParam | None = None, +) -> EvaluationRow | list[EvaluationRow]: + if evaluation_test_kwargs is not None: + if "row" in evaluation_test_kwargs: + raise ValueError("'row' is a reserved parameter for the evaluation function") + if "rows" in evaluation_test_kwargs: + raise ValueError("'rows' is a reserved parameter for the evaluation function") + + # Handle both sync and async test functions + if asyncio.iscoroutinefunction(test_func): + if processed_row is not None: + return await test_func(processed_row) + if processed_dataset is not None: + return await test_func(processed_dataset) + return await test_func() + else: + if processed_row is not None: + row = test_func(processed_row) + if processed_dataset is not None: + return test_func(processed_dataset) + return test_func() diff --git a/eval_protocol/pytest/parameterize.py b/eval_protocol/pytest/parameterize.py new file mode 100644 index 00000000..4b3ffd51 --- /dev/null +++ b/eval_protocol/pytest/parameterize.py @@ -0,0 +1,67 @@ +from typing import TypedDict +from collections.abc import Sequence, Iterable + +from _pytest.mark import ParameterSet + +from eval_protocol.models import CompletionParams, EvaluationRow +from eval_protocol.pytest.types import DatasetPathParam, EvaluationInputParam, InputMessagesParam +from eval_protocol.pytest.utils import CombinationTuple + + +class PytestParametrizeArgs(TypedDict): + argnames: str | Sequence[str] + argvalues: Iterable[ParameterSet | Sequence[object] | object] + + +def pytest_parametrize( + combinations: list[CombinationTuple], + input_dataset: list[DatasetPathParam] | None, + completion_params: list[CompletionParams | None] | None, + input_messages: list[InputMessagesParam | None] | None, + input_rows: list[EvaluationRow] | None, + evaluation_test_kwargs: list[EvaluationInputParam | None] | None, +) -> PytestParametrizeArgs: + """ + This function dynamically generates pytest.mark.parametrize arguments for a given + set of combinations. This is the magic that allows developers to pass in their + inputs in a single decorator and generate all combinations of experiments + without having to create their own fixtures and confirming to eval-protocol's + API. + """ + + # Create parameter tuples for pytest.mark.parametrize + argnames: list[str] = [] + if input_dataset is not None: + argnames.append("dataset_path") + if completion_params is not None: + argnames.append("completion_params") + if input_messages is not None: + argnames.append("input_messages") + if input_rows is not None: + argnames.append("input_rows") + if evaluation_test_kwargs is not None: + argnames.append("evaluation_test_kwargs") + + argvalues: list[ParameterSet | Sequence[object] | object] = [] + param_tuples: list[tuple[object, ...]] = [] + for combo in combinations: + dataset, cp, messages, rows, etk = combo + param_tuple: list[object] = [] + if input_dataset is not None: + param_tuple.append(dataset) + if completion_params is not None: + param_tuple.append(cp) + if input_messages is not None: + param_tuple.append(messages) + if input_rows is not None: + param_tuple.append(rows) + if evaluation_test_kwargs is not None: + param_tuple.append(etk) + # do validation that the length of argnames is the same as the length of param_tuple + if len(argnames) != len(param_tuple): + raise ValueError( + f"The length of argnames ({len(argnames)}) is not the same as the length of param_tuple ({len(param_tuple)})" + ) + param_tuples.append(tuple(param_tuple)) + + return PytestParametrizeArgs(argnames=argnames, argvalues=argvalues) diff --git a/eval_protocol/pytest/types.py b/eval_protocol/pytest/types.py index ff34e6df..fc262a34 100644 --- a/eval_protocol/pytest/types.py +++ b/eval_protocol/pytest/types.py @@ -2,9 +2,8 @@ Parameter types """ -import asyncio from dataclasses import dataclass, field -from typing import Any, Callable, Dict, List, Literal, Optional +from typing import Any, Callable, Literal from eval_protocol.dataset_logger import default_logger from eval_protocol.dataset_logger.dataset_logger import DatasetLogger @@ -14,11 +13,11 @@ ModelParam = str # gpt-4o, gpt-4o-mini, accounts/fireworks/models/llama-3.1-8b-instruct DatasetPathParam = str -InputMessagesParam = List[Message] -EvaluationInputParam = Dict[str, Any] -RolloutProcessorInputParam = Dict[str, Any] +InputMessagesParam = list[Message] +EvaluationInputParam = dict[str, Any] # pyright: ignore[reportExplicitAny] +RolloutProcessorInputParam = dict[str, Any] # pyright: ignore[reportExplicitAny] -Dataset = List[EvaluationRow] +Dataset = list[EvaluationRow] EvaluationTestMode = Literal["pointwise", "groupwise", "all"] """ @@ -30,7 +29,19 @@ """ Test function types """ -TestFunction = Callable +# Type variable for the decorated function +from collections.abc import Awaitable + +# TestFunction can be either: +# 1. an async/sync function that accepts EvaluationRow and returns EvaluationRow +# 2. an async/sync function that accepts list[EvaluationRow] and returns list[EvaluationRow] +TestFunction = ( + Callable[[EvaluationRow], EvaluationRow] + | Callable[[EvaluationRow], Awaitable[EvaluationRow]] + | Callable[[list[EvaluationRow]], list[EvaluationRow]] + | Callable[[list[EvaluationRow]], Awaitable[list[EvaluationRow]]] +) + """ Rollout processor types @@ -41,13 +52,13 @@ class RolloutProcessorConfig: completion_params: CompletionParams # input parameters for inference mcp_config_path: str - server_script_path: Optional[str] = ( + server_script_path: str | None = ( None # TODO: change from server_script_path to mcp_config_path for agent rollout processor ) max_concurrent_rollouts: int = 8 # maximum number of concurrent rollouts steps: int = 30 # max number of rollout steps logger: DatasetLogger = default_logger # logger to use during rollout for mid-rollout logs - kwargs: Dict[str, Any] = field(default_factory=dict) # any additional kwargs to pass to the rollout processor - exception_handler_config: Optional[ExceptionHandlerConfig] = ( - None # configuration for exception handling with backoff - ) + kwargs: dict[str, Any] = field( # pyright: ignore[reportExplicitAny] + default_factory=dict + ) # any additional kwargs to pass to the rollout processor + exception_handler_config: ExceptionHandlerConfig | None = None # configuration for exception handling with backoff diff --git a/eval_protocol/pytest/utils.py b/eval_protocol/pytest/utils.py index f4bbaebe..51113dfb 100644 --- a/eval_protocol/pytest/utils.py +++ b/eval_protocol/pytest/utils.py @@ -6,7 +6,7 @@ from typing import Any, Callable, Dict, List, Literal, Optional, Union from eval_protocol.dataset_logger.dataset_logger import DatasetLogger -from eval_protocol.models import EvalMetadata, EvaluationRow, Status +from eval_protocol.models import EvalMetadata, EvaluationRow, EvaluationThreshold, EvaluationThresholdDict, Status from eval_protocol.pytest.rollout_processor import RolloutProcessor from eval_protocol.pytest.types import ( CompletionParams, @@ -141,7 +141,7 @@ def log_eval_status_and_rows( logger.log(r) -def parse_ep_max_rows(default_value: Optional[int]) -> Optional[int]: +def parse_ep_max_rows(default_value: int | None) -> int | None: """Read EP_MAX_DATASET_ROWS env override as int or None. Assumes the environment variable was already validated by plugin.py. @@ -171,42 +171,49 @@ def parse_ep_max_concurrent_rollouts(default_value: int) -> int: return int(raw) if raw is not None else default_value -def parse_ep_completion_params(completion_params: List[CompletionParams]) -> List[CompletionParams]: +def parse_ep_completion_params( + completion_params: list[CompletionParams | None] | None, +) -> list[CompletionParams | None]: """Apply EP_INPUT_PARAMS_JSON overrides to completion_params. Reads the environment variable set by plugin.py and applies deep merge to each completion param. """ + if completion_params is None: + return [] try: _env_override = os.getenv("EP_INPUT_PARAMS_JSON") if _env_override: - override_obj = json.loads(_env_override) + override_obj = json.loads(_env_override) # pyright: ignore[reportAny] if isinstance(override_obj, dict): # Apply override to each completion_params item - return [deep_update_dict(dict(cp), override_obj) for cp in completion_params] + return [deep_update_dict(dict(cp), override_obj) for cp in completion_params if cp is not None] except Exception: pass return completion_params -def parse_ep_passed_threshold(default_value: Optional[Union[float, dict]]) -> Optional[Union[float, dict]]: +def parse_ep_passed_threshold( + default_value: float | EvaluationThresholdDict | EvaluationThreshold | None, +) -> EvaluationThreshold | None: """Read EP_PASSED_THRESHOLD env override as float or dict. Assumes the environment variable was already validated by plugin.py. Supports both float values (e.g., "0.8") and JSON dict format (e.g., '{"success":0.8}'). """ raw = os.getenv("EP_PASSED_THRESHOLD") - if raw is None: + if raw is not None: + try: + success_value = float(raw) + return EvaluationThreshold(success=success_value) + except ValueError: + raise ValueError(f"EP_PASSED_THRESHOLD env var exists but can't be parsed: {raw}") + if isinstance(default_value, float): + return EvaluationThreshold(success=default_value) + if isinstance(default_value, dict): + return EvaluationThreshold(**default_value) + if isinstance(default_value, EvaluationThreshold): return default_value - - try: - return float(raw) - except ValueError: - pass - - try: - return json.loads(raw) - except (json.JSONDecodeError, TypeError, ValueError) as e: - raise ValueError(f"EP_PASSED_THRESHOLD env var exists but can't be parsed: {raw}") from e + return None def deep_update_dict(base: dict, override: dict) -> dict: @@ -219,15 +226,24 @@ def deep_update_dict(base: dict, override: dict) -> dict: return base +CombinationTuple = tuple[ + list[DatasetPathParam] | None, + CompletionParams | None, + InputMessagesParam | None, + list[EvaluationRow] | None, + EvaluationInputParam | None, +] + + def generate_parameter_combinations( - input_dataset: Optional[List[DatasetPathParam]], - completion_params: List[CompletionParams], - input_messages: Optional[List[InputMessagesParam]], - input_rows: Optional[List[EvaluationRow]], - evaluation_test_kwargs: Optional[List[EvaluationInputParam]], - max_dataset_rows: Optional[int], + input_dataset: list[DatasetPathParam] | None, + completion_params: list[CompletionParams | None], + input_messages: list[InputMessagesParam | None] | None, + input_rows: list[EvaluationRow] | None, + evaluation_test_kwargs: list[EvaluationInputParam | None] | None, + max_dataset_rows: int | None, combine_datasets: bool, -) -> List[tuple]: +) -> list[CombinationTuple]: """ Generate all combinations of parameters for pytest parameterization. @@ -243,54 +259,51 @@ def generate_parameter_combinations( Returns: List of parameter tuples for pytest.mark.parametrize """ - combinations = [] - # Handle optional parameters with defaults # Optionally combine multiple dataset paths into one logical dataset, # or parameterize to run one dataset per test invocation. + datasets: list[list[DatasetPathParam] | None] = [] if input_dataset is not None: if combine_datasets: - datasets: List[Optional[List[DatasetPathParam]]] = [input_dataset] # type: ignore + datasets = [input_dataset] else: # Fan out: one dataset path per parameterization - if isinstance(input_dataset, list): # type: ignore - datasets = [[p] for p in input_dataset] # type: ignore + if input_dataset: + datasets = [[p] for p in input_dataset] else: - datasets = [[input_dataset]] # type: ignore - else: - datasets = [None] + datasets = [None] - cps: List[Optional[CompletionParams]] = completion_params if completion_params is not None else [None] # type: ignore + cps: list[CompletionParams | None] = completion_params # Apply EP_MAX_DATASET_ROWS to input_messages, but do NOT parameterize over # each row. Instead, pass the entire sliced list through in a single test run # so summaries aggregate all rows together (AIME-style behavior). - if input_messages is not None and isinstance(input_messages, list): + messages: list[InputMessagesParam | None] = [None] + if input_messages is not None: effective_max_rows = parse_ep_max_rows(max_dataset_rows) if effective_max_rows is not None: - sliced_messages = input_messages[:effective_max_rows] # type: ignore + sliced_messages: list[InputMessagesParam | None] = input_messages[:effective_max_rows] else: - sliced_messages = input_messages # type: ignore + sliced_messages = input_messages # Wrap as a single parameter payload - messages = [sliced_messages] # type: ignore - else: - messages = [None] # type: ignore + messages = sliced_messages + rows: list[list[EvaluationRow] | None] = [None] # Handle input_rows - similar to input_messages, apply max_dataset_rows if specified - if input_rows is not None and isinstance(input_rows, list): + if input_rows is not None: effective_max_rows = parse_ep_max_rows(max_dataset_rows) if effective_max_rows is not None: - sliced_rows = input_rows[:effective_max_rows] # type: ignore + sliced_rows = input_rows[:effective_max_rows] else: - sliced_rows = input_rows # type: ignore + sliced_rows = input_rows # Wrap as a single parameter payload - rows = [sliced_rows] # type: ignore - else: - rows = [None] # type: ignore + rows = [sliced_rows] - kwargs: List[Optional[EvaluationInputParam]] = ( + kwargs: list[EvaluationInputParam | None] = ( evaluation_test_kwargs if evaluation_test_kwargs is not None else [None] - ) # type: ignore + ) + + combinations: list[CombinationTuple] = [] # Generate all combinations for ds in datasets: diff --git a/eval_protocol/pytest/validate_signature.py b/eval_protocol/pytest/validate_signature.py new file mode 100644 index 00000000..02e2e708 --- /dev/null +++ b/eval_protocol/pytest/validate_signature.py @@ -0,0 +1,50 @@ +from inspect import Signature + +from eval_protocol.models import CompletionParams, EvaluationRow +from eval_protocol.pytest.types import EvaluationTestMode + + +def validate_signature( + signature: Signature, mode: EvaluationTestMode, completion_params: list[CompletionParams | None] | None +) -> None: + # For pointwise/groupwise mode, we expect a different signature + # we expect single row to be passed in as the original row + if mode == "pointwise": + # Pointwise mode: function should accept messages and other row-level params + if "row" not in signature.parameters: + raise ValueError("In pointwise mode, your eval function must have a parameter named 'row'") + + # validate that "Row" is of type EvaluationRow + if signature.parameters["row"].annotation is not EvaluationRow: # pyright: ignore[reportAny] + raise ValueError("In pointwise mode, the 'row' parameter must be of type EvaluationRow") + + # validate that the function has a return type of EvaluationRow + if signature.return_annotation is not EvaluationRow: # pyright: ignore[reportAny] + raise ValueError("In pointwise mode, your eval function must return an EvaluationRow instance") + + # additional check for groupwise evaluation + elif mode == "groupwise": + if "rows" not in signature.parameters: + raise ValueError("In groupwise mode, your eval function must have a parameter named 'rows'") + + # validate that "Rows" is of type List[EvaluationRow] + if signature.parameters["rows"].annotation is not list[EvaluationRow]: # pyright: ignore[reportAny] + raise ValueError("In groupwise mode, the 'rows' parameter must be of type List[EvaluationRow") + + # validate that the function has a return type of List[EvaluationRow] + if signature.return_annotation is not list[EvaluationRow]: # pyright: ignore[reportAny] + raise ValueError("In groupwise mode, your eval function must return a list of EvaluationRow instances") + if completion_params is not None and len(completion_params) < 2: + raise ValueError("In groupwise mode, you must provide at least 2 completion parameters") + else: + # all mode: function should accept input_dataset and model + if "rows" not in signature.parameters: + raise ValueError("In all mode, your eval function must have a parameter named 'rows'") + + # validate that "Rows" is of type List[EvaluationRow] + if signature.parameters["rows"].annotation is not list[EvaluationRow]: # pyright: ignore[reportAny] + raise ValueError("In all mode, the 'rows' parameter must be of type List[EvaluationRow") + + # validate that the function has a return type of List[EvaluationRow] + if signature.return_annotation is not list[EvaluationRow]: # pyright: ignore[reportAny] + raise ValueError("In all mode, your eval function must return a list of EvaluationRow instances") From 97072d4f364eec3d4d868c0bb3605e10c0ccdada Mon Sep 17 00:00:00 2001 From: Dylan Huang Date: Thu, 28 Aug 2025 15:37:27 -0700 Subject: [PATCH 06/18] part 3 --- eval_protocol/pytest/evaluation_test.py | 257 +----------------- eval_protocol/pytest/handle_persist_flow.py | 202 ++++++++++++++ eval_protocol/pytest/store_experiment_link.py | 41 +++ pyproject.toml | 1 + 4 files changed, 255 insertions(+), 246 deletions(-) create mode 100644 eval_protocol/pytest/handle_persist_flow.py create mode 100644 eval_protocol/pytest/store_experiment_link.py diff --git a/eval_protocol/pytest/evaluation_test.py b/eval_protocol/pytest/evaluation_test.py index a7428d7a..8d15bd8c 100644 --- a/eval_protocol/pytest/evaluation_test.py +++ b/eval_protocol/pytest/evaluation_test.py @@ -1,16 +1,13 @@ import asyncio -import configparser import functools import inspect import json import math import os import pathlib -import requests import statistics import time from collections import defaultdict -from pathlib import Path from typing import Any, Callable import pytest @@ -29,6 +26,7 @@ Message, Status, ) +from eval_protocol.pytest.handle_persist_flow import handle_persist_flow from eval_protocol.pytest.parameterize import pytest_parametrize from eval_protocol.pytest.validate_signature import validate_signature from eval_protocol.pytest.default_dataset_adapter import default_dataset_adapter @@ -67,42 +65,6 @@ from ..common_utils import load_jsonl -from pytest import StashKey -from typing_extensions import Literal - - -EXPERIMENT_LINKS_STASH_KEY = StashKey[list]() - - -def _store_experiment_link(experiment_id: str, job_link: str, status: Literal["success", "failure"]): - """Store experiment link in pytest session stash.""" - try: - import sys - - # Walk up the call stack to find the pytest session - session = None - frame = sys._getframe() - while frame: - if "session" in frame.f_locals and hasattr(frame.f_locals["session"], "stash"): - session = frame.f_locals["session"] - break - frame = frame.f_back - - if session is not None: - global EXPERIMENT_LINKS_STASH_KEY - - if EXPERIMENT_LINKS_STASH_KEY not in session.stash: - session.stash[EXPERIMENT_LINKS_STASH_KEY] = [] - - session.stash[EXPERIMENT_LINKS_STASH_KEY].append( - {"experiment_id": experiment_id, "job_link": job_link, "status": status} - ) - else: - pass - - except Exception as e: - pass - def postprocess( all_results: list[list[EvaluationRow]], @@ -254,193 +216,7 @@ def postprocess( # Do not fail evaluation if summary writing fails pass - try: - # Default is to save and upload experiment JSONL files, unless explicitly disabled - should_save_and_upload = os.getenv("EP_NO_UPLOAD") != "1" - - if should_save_and_upload: - current_run_rows = [item for sublist in all_results for item in sublist] - if current_run_rows: - experiments: Dict[str, List[EvaluationRow]] = defaultdict(list) - for row in current_run_rows: - if row.execution_metadata and row.execution_metadata.experiment_id: - experiments[row.execution_metadata.experiment_id].append(row) - - exp_dir = pathlib.Path("experiment_results") - exp_dir.mkdir(parents=True, exist_ok=True) - - # Create one JSONL file per experiment_id - for experiment_id, exp_rows in experiments.items(): - if not experiment_id or not exp_rows: - continue - - # Generate dataset name (sanitize for Fireworks API compatibility) - # API requires: lowercase a-z, 0-9, and hyphen (-) only - safe_experiment_id = re.sub(r"[^a-zA-Z0-9-]", "-", experiment_id).lower() - safe_test_func_name = re.sub(r"[^a-zA-Z0-9-]", "-", test_func_name).lower() - dataset_name = f"{safe_test_func_name}-{safe_experiment_id}" - - if len(dataset_name) > 63: - dataset_name = dataset_name[:63] - - exp_file = exp_dir / f"{experiment_id}.jsonl" - with open(exp_file, "w", encoding="utf-8") as f: - for row in exp_rows: - row_data = row.model_dump(exclude_none=True, mode="json") - - if row.evaluation_result: - row_data["evals"] = {"score": row.evaluation_result.score} - - row_data["eval_details"] = { - "score": row.evaluation_result.score, - "is_score_valid": row.evaluation_result.is_score_valid, - "reason": row.evaluation_result.reason or "", - "metrics": { - name: metric.model_dump() if metric else {} - for name, metric in (row.evaluation_result.metrics or {}).items() - }, - } - else: - # Default values if no evaluation result - row_data["evals"] = {"score": 0} - row_data["eval_details"] = { - "score": 0, - "is_score_valid": True, - "reason": "No evaluation result", - "metrics": {}, - } - - json.dump(row_data, f, ensure_ascii=False) - f.write("\n") - - def get_auth_value(key): - """Get auth value from config file or environment.""" - try: - config_path = Path.home() / ".fireworks" / "auth.ini" - if config_path.exists(): - config = configparser.ConfigParser() - config.read(config_path) - for section in ["DEFAULT", "auth"]: - if config.has_section(section) and config.has_option(section, key): - return config.get(section, key) - except Exception: - pass - return os.getenv(key) - - fireworks_api_key = get_auth_value("FIREWORKS_API_KEY") - fireworks_account_id = get_auth_value("FIREWORKS_ACCOUNT_ID") - - if not fireworks_api_key and not fireworks_account_id: - _store_experiment_link( - experiment_id, - "No Fireworks API key AND account ID found", - "failure", - ) - continue - elif not fireworks_api_key: - _store_experiment_link( - experiment_id, - "No Fireworks API key found", - "failure", - ) - continue - elif not fireworks_account_id: - _store_experiment_link( - experiment_id, - "No Fireworks account ID found", - "failure", - ) - continue - - headers = {"Authorization": f"Bearer {fireworks_api_key}", "Content-Type": "application/json"} - - # Make dataset first - dataset_url = f"https://api.fireworks.ai/v1/accounts/{fireworks_account_id}/datasets" - - dataset_payload = { - "dataset": { - "displayName": dataset_name, - "evalProtocol": {}, - "format": "FORMAT_UNSPECIFIED", - "exampleCount": f"{len(exp_rows)}", - }, - "datasetId": dataset_name, - } - - dataset_response = requests.post(dataset_url, json=dataset_payload, headers=headers) - - # Skip if dataset creation failed - if dataset_response.status_code not in [200, 201]: - _store_experiment_link( - experiment_id, - f"Dataset creation failed: {dataset_response.status_code} {dataset_response.text}", - "failure", - ) - continue - - dataset_data = dataset_response.json() - dataset_id = dataset_data.get("datasetId", dataset_name) - - # Upload the JSONL file content - upload_url = ( - f"https://api.fireworks.ai/v1/accounts/{fireworks_account_id}/datasets/{dataset_id}:upload" - ) - upload_headers = {"Authorization": f"Bearer {fireworks_api_key}"} - - with open(exp_file, "rb") as f: - files = {"file": f} - upload_response = requests.post(upload_url, files=files, headers=upload_headers) - - # Skip if upload failed - if upload_response.status_code not in [200, 201]: - _store_experiment_link( - experiment_id, - f"File upload failed: {upload_response.status_code} {upload_response.text}", - "failure", - ) - continue - - # Create evaluation job (optional - don't skip experiment if this fails) - eval_job_url = f"https://api.fireworks.ai/v1/accounts/{fireworks_account_id}/evaluationJobs" - # Truncate job ID to fit 63 character limit - job_id_base = f"{dataset_name}-job" - if len(job_id_base) > 63: - # Keep the "-job" suffix and truncate the dataset_name part - max_dataset_name_len = 63 - 4 # 4 = len("-job") - truncated_dataset_name = dataset_name[:max_dataset_name_len] - job_id_base = f"{truncated_dataset_name}-job" - - eval_job_payload = { - "evaluationJobId": job_id_base, - "evaluationJob": { - "evaluator": f"accounts/{fireworks_account_id}/evaluators/dummy", - "inputDataset": f"accounts/{fireworks_account_id}/datasets/dummy", - "outputDataset": f"accounts/{fireworks_account_id}/datasets/{dataset_id}", - }, - } - - eval_response = requests.post(eval_job_url, json=eval_job_payload, headers=headers) - - if eval_response.status_code in [200, 201]: - eval_job_data = eval_response.json() - job_id = eval_job_data.get("evaluationJobId", job_id_base) - - _store_experiment_link( - experiment_id, - f"https://app.fireworks.ai/dashboard/evaluation-jobs/{job_id}", - "success", - ) - else: - _store_experiment_link( - experiment_id, - f"Job creation failed: {eval_response.status_code} {eval_response.text}", - "failure", - ) - - except Exception as e: - # Do not fail evaluation if experiment JSONL writing fails - print(f"Warning: Failed to persist results: {e}") - pass + handle_persist_flow(all_results, test_func_name) # Check threshold after logging if threshold is not None and not passed: @@ -566,26 +342,15 @@ def decorator( validate_signature(sig, mode, completion_params) # Calculate all possible combinations of parameters - if mode == "groupwise": - combinations = generate_parameter_combinations( - input_dataset, - completion_params, - input_messages, - input_rows, - evaluation_test_kwargs, - max_dataset_rows, - combine_datasets, - ) - else: - combinations = generate_parameter_combinations( - input_dataset, - completion_params, - input_messages, - input_rows, - evaluation_test_kwargs, - max_dataset_rows, - combine_datasets, - ) + combinations = generate_parameter_combinations( + input_dataset, + completion_params, + input_messages, + input_rows, + evaluation_test_kwargs, + max_dataset_rows, + combine_datasets, + ) if len(combinations) == 0: raise ValueError( "No combinations of parameters were found. Please provide at least a model and one of input_dataset, input_messages, or input_rows." diff --git a/eval_protocol/pytest/handle_persist_flow.py b/eval_protocol/pytest/handle_persist_flow.py new file mode 100644 index 00000000..58d989f1 --- /dev/null +++ b/eval_protocol/pytest/handle_persist_flow.py @@ -0,0 +1,202 @@ +from collections import defaultdict +import configparser +import json +import os +from pathlib import Path +import pathlib +import re +from typing import Any + +from eval_protocol.models import EvaluationRow +from eval_protocol.pytest.store_experiment_link import store_experiment_link +import requests + + +def handle_persist_flow(all_results: list[list[EvaluationRow]], test_func_name: str): + try: + # Default is to save and upload experiment JSONL files, unless explicitly disabled + should_save_and_upload = os.getenv("EP_NO_UPLOAD") != "1" + + if should_save_and_upload: + current_run_rows = [item for sublist in all_results for item in sublist] + if current_run_rows: + experiments: dict[str, list[EvaluationRow]] = defaultdict(list) + for row in current_run_rows: + if row.execution_metadata and row.execution_metadata.experiment_id: + experiments[row.execution_metadata.experiment_id].append(row) + + exp_dir = pathlib.Path("experiment_results") + exp_dir.mkdir(parents=True, exist_ok=True) + + # Create one JSONL file per experiment_id + for experiment_id, exp_rows in experiments.items(): + if not experiment_id or not exp_rows: + continue + + # Generate dataset name (sanitize for Fireworks API compatibility) + # API requires: lowercase a-z, 0-9, and hyphen (-) only + safe_experiment_id = re.sub(r"[^a-zA-Z0-9-]", "-", experiment_id).lower() + safe_test_func_name = re.sub(r"[^a-zA-Z0-9-]", "-", test_func_name).lower() + dataset_name = f"{safe_test_func_name}-{safe_experiment_id}" + + if len(dataset_name) > 63: + dataset_name = dataset_name[:63] + + exp_file = exp_dir / f"{experiment_id}.jsonl" + with open(exp_file, "w", encoding="utf-8") as f: + for row in exp_rows: + row_data = row.model_dump(exclude_none=True, mode="json") + + if row.evaluation_result: + row_data["evals"] = {"score": row.evaluation_result.score} + + row_data["eval_details"] = { + "score": row.evaluation_result.score, + "is_score_valid": row.evaluation_result.is_score_valid, + "reason": row.evaluation_result.reason or "", + "metrics": { + name: metric.model_dump() if metric else {} + for name, metric in (row.evaluation_result.metrics or {}).items() + }, + } + else: + # Default values if no evaluation result + row_data["evals"] = {"score": 0} + row_data["eval_details"] = { + "score": 0, + "is_score_valid": True, + "reason": "No evaluation result", + "metrics": {}, + } + + json.dump(row_data, f, ensure_ascii=False) + f.write("\n") + + def get_auth_value(key: str) -> str | None: + """Get auth value from config file or environment.""" + try: + config_path = Path.home() / ".fireworks" / "auth.ini" + if config_path.exists(): + config = configparser.ConfigParser() # noqa: F821 + config.read(config_path) + for section in ["DEFAULT", "auth"]: + if config.has_section(section) and config.has_option(section, key): + return config.get(section, key) + except Exception: + pass + return os.getenv(key) + + fireworks_api_key = get_auth_value("FIREWORKS_API_KEY") + fireworks_account_id = get_auth_value("FIREWORKS_ACCOUNT_ID") + + if not fireworks_api_key and not fireworks_account_id: + store_experiment_link( + experiment_id, + "No Fireworks API key AND account ID found", + "failure", + ) + continue + elif not fireworks_api_key: + store_experiment_link( + experiment_id, + "No Fireworks API key found", + "failure", + ) + continue + elif not fireworks_account_id: + store_experiment_link( + experiment_id, + "No Fireworks account ID found", + "failure", + ) + continue + + headers = {"Authorization": f"Bearer {fireworks_api_key}", "Content-Type": "application/json"} + + # Make dataset first + dataset_url = f"https://api.fireworks.ai/v1/accounts/{fireworks_account_id}/datasets" + + dataset_payload = { # pyright: ignore[reportUnknownVariableType] + "dataset": { + "displayName": dataset_name, + "evalProtocol": {}, + "format": "FORMAT_UNSPECIFIED", + "exampleCount": f"{len(exp_rows)}", + }, + "datasetId": dataset_name, + } + + dataset_response = requests.post(dataset_url, json=dataset_payload, headers=headers) # pyright: ignore[reportUnknownArgumentType] + + # Skip if dataset creation failed + if dataset_response.status_code not in [200, 201]: + store_experiment_link( + experiment_id, + f"Dataset creation failed: {dataset_response.status_code} {dataset_response.text}", + "failure", + ) + continue + + dataset_data: dict[str, Any] = dataset_response.json() # pyright: ignore[reportAny, reportExplicitAny] + dataset_id = dataset_data.get("datasetId", dataset_name) # pyright: ignore[reportAny] + + # Upload the JSONL file content + upload_url = ( + f"https://api.fireworks.ai/v1/accounts/{fireworks_account_id}/datasets/{dataset_id}:upload" + ) + upload_headers = {"Authorization": f"Bearer {fireworks_api_key}"} + + with open(exp_file, "rb") as f: + files = {"file": f} + upload_response = requests.post(upload_url, files=files, headers=upload_headers) + + # Skip if upload failed + if upload_response.status_code not in [200, 201]: + store_experiment_link( + experiment_id, + f"File upload failed: {upload_response.status_code} {upload_response.text}", + "failure", + ) + continue + + # Create evaluation job (optional - don't skip experiment if this fails) + eval_job_url = f"https://api.fireworks.ai/v1/accounts/{fireworks_account_id}/evaluationJobs" + # Truncate job ID to fit 63 character limit + job_id_base = f"{dataset_name}-job" + if len(job_id_base) > 63: + # Keep the "-job" suffix and truncate the dataset_name part + max_dataset_name_len = 63 - 4 # 4 = len("-job") + truncated_dataset_name = dataset_name[:max_dataset_name_len] + job_id_base = f"{truncated_dataset_name}-job" + + eval_job_payload = { + "evaluationJobId": job_id_base, + "evaluationJob": { + "evaluator": f"accounts/{fireworks_account_id}/evaluators/dummy", + "inputDataset": f"accounts/{fireworks_account_id}/datasets/dummy", + "outputDataset": f"accounts/{fireworks_account_id}/datasets/{dataset_id}", + }, + } + + eval_response = requests.post(eval_job_url, json=eval_job_payload, headers=headers) + + if eval_response.status_code in [200, 201]: + eval_job_data = eval_response.json() # pyright: ignore[reportAny] + job_id = eval_job_data.get("evaluationJobId", job_id_base) # pyright: ignore[reportAny] + + store_experiment_link( + experiment_id, + f"https://app.fireworks.ai/dashboard/evaluation-jobs/{job_id}", + "success", + ) + else: + store_experiment_link( + experiment_id, + f"Job creation failed: {eval_response.status_code} {eval_response.text}", + "failure", + ) + + except Exception as e: + # Do not fail evaluation if experiment JSONL writing fails + print(f"Warning: Failed to persist results: {e}") + pass diff --git a/eval_protocol/pytest/store_experiment_link.py b/eval_protocol/pytest/store_experiment_link.py new file mode 100644 index 00000000..a2896cd9 --- /dev/null +++ b/eval_protocol/pytest/store_experiment_link.py @@ -0,0 +1,41 @@ +from typing import Literal, TypedDict +from pytest import StashKey + + +class ExperimentLink(TypedDict): + experiment_id: str + job_link: str + status: Literal["success", "failure"] + + +EXPERIMENT_LINKS_STASH_KEY = StashKey[list[ExperimentLink]]() + + +def store_experiment_link(experiment_id: str, job_link: str, status: Literal["success", "failure"]): + """Store experiment link in pytest session stash.""" + try: + import sys + + # Walk up the call stack to find the pytest session + session = None + frame = sys._getframe() # pyright: ignore[reportPrivateUsage] + while frame: + if "session" in frame.f_locals and hasattr(frame.f_locals["session"], "stash"): # pyright: ignore[reportAny] + session = frame.f_locals["session"] # pyright: ignore[reportAny] + break + frame = frame.f_back + + if session is not None: + global EXPERIMENT_LINKS_STASH_KEY + + if EXPERIMENT_LINKS_STASH_KEY not in session.stash: # pyright: ignore[reportAny] + session.stash[EXPERIMENT_LINKS_STASH_KEY] = [] # pyright: ignore[reportAny] + + session.stash[EXPERIMENT_LINKS_STASH_KEY].append( # pyright: ignore[reportAny] + {"experiment_id": experiment_id, "job_link": job_link, "status": status} + ) + else: + pass + + except Exception as e: # pyright: ignore[reportUnusedVariable] + pass diff --git a/pyproject.toml b/pyproject.toml index c612c7bf..c92f528f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -210,3 +210,4 @@ include = ["eval_protocol", "examples", "tests"] exclude = ["vite-app", "vendor"] # Ignore diagnostics for vendored generator code ignore = ["versioneer.py"] +reportUnusedCallResult = "none" From c74aef2dac0a9d43dd2a6dfabe8fdba2b11146cd Mon Sep 17 00:00:00 2001 From: Dylan Huang Date: Thu, 28 Aug 2025 21:29:47 -0700 Subject: [PATCH 07/18] use basedpyright for pre-commit --- .pre-commit-config.yaml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 441a2de7..8e7f7cc4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,8 +22,7 @@ repos: - id: ruff-format - id: ruff args: ["--fix"] - -- repo: https://github.com/RobertCraigie/pyright-python - rev: v1.1.403 +- repo: https://github.com/DetachHead/basedpyright-pre-commit-mirror + rev: 1.31.3 hooks: - - id: pyright + - id: basedpyright From f5a1d7bfa2f33b83ac8c1112adacbaabbe754cc5 Mon Sep 17 00:00:00 2001 From: Dylan Huang Date: Thu, 28 Aug 2025 21:43:36 -0700 Subject: [PATCH 08/18] evaluation_test type checks pass --- .../pytest/default_dataset_adapter.py | 7 +- eval_protocol/pytest/dual_mode_wrapper.py | 78 ++++ eval_protocol/pytest/evaluation_test.py | 435 +++++------------- .../pytest/evaluation_test_postprocess.py | 174 +++++++ eval_protocol/pytest/execution.py | 20 +- .../pytest/generate_parameter_combinations.py | 122 +++++ eval_protocol/pytest/parameterize.py | 52 ++- eval_protocol/pytest/types.py | 8 +- eval_protocol/pytest/utils.py | 240 ++-------- eval_protocol/pytest/validate_signature.py | 3 +- tests/chinook/test_pydantic_chinook.py | 10 +- tests/pytest/test_pytest_input_rows.py | 2 +- 12 files changed, 590 insertions(+), 561 deletions(-) create mode 100644 eval_protocol/pytest/dual_mode_wrapper.py create mode 100644 eval_protocol/pytest/evaluation_test_postprocess.py create mode 100644 eval_protocol/pytest/generate_parameter_combinations.py diff --git a/eval_protocol/pytest/default_dataset_adapter.py b/eval_protocol/pytest/default_dataset_adapter.py index 7c4a7d73..23c792b9 100644 --- a/eval_protocol/pytest/default_dataset_adapter.py +++ b/eval_protocol/pytest/default_dataset_adapter.py @@ -1,10 +1,9 @@ -from typing import Any, Dict, List - +from typing import Any from eval_protocol.models import EvaluationRow -def default_dataset_adapter(rows: List[Dict[str, Any]]) -> List[EvaluationRow]: +def default_dataset_adapter(rows: list[dict[str, Any]]) -> list[EvaluationRow]: # pyright: ignore[reportExplicitAny] """ Default dataset adapter that simply returns the rows as is. """ - return [EvaluationRow(**row) for row in rows] + return [EvaluationRow(**row) for row in rows] # pyright: ignore[reportAny] diff --git a/eval_protocol/pytest/dual_mode_wrapper.py b/eval_protocol/pytest/dual_mode_wrapper.py new file mode 100644 index 00000000..3f971b42 --- /dev/null +++ b/eval_protocol/pytest/dual_mode_wrapper.py @@ -0,0 +1,78 @@ +import asyncio +from collections.abc import Callable +import functools + +from eval_protocol.models import EvaluationRow +from eval_protocol.pytest.types import EvaluationTestMode, TestFunction + + +def create_dual_mode_wrapper( # pyright: ignore[reportUnknownParameterType] + test_func: TestFunction, + mode: EvaluationTestMode, + max_concurrent_rollouts: int, + max_concurrent_evaluations: int, + pytest_wrapper: Callable[[], None], +): + """ + Creates a wrapper that supports both pytest parameterized execution and direct function calls. + + This wrapper enables the decorated evaluation test function to be used in two ways: + 1. As a pytest test (via pytest.mark.parametrize) with full parameterization + 2. As a direct function call with EvaluationRow data for programmatic use + + The wrapper automatically detects the calling pattern and routes to the appropriate + execution path, ensuring consistent behavior regardless of how the function is invoked. + + Returns: + A callable that can handle both pytest test execution and direct function calls + """ + + # Check if the test function is async + is_async = asyncio.iscoroutinefunction(test_func) + + async def call_test_func(**call_kwargs): # pyright: ignore[reportUnknownParameterType, reportMissingParameterType] + """Helper to call test_func with proper async/sync handling""" + if is_async: + return await test_func(**call_kwargs) # pyright: ignore[reportUnknownVariableType, reportGeneralTypeIssues, reportCallIssue] + else: + return test_func(**call_kwargs) # pyright: ignore[reportUnknownVariableType, reportCallIssue] + + async def dual_mode_wrapper(*args, **kwargs): # pyright: ignore[reportUnknownParameterType, reportMissingParameterType] + # Check if this is a direct call with the expected signature + if mode == "pointwise": + # For pointwise mode, check if called with a single row argument + if len(args) == 1 and isinstance(args[0], EvaluationRow) and not kwargs: # pyright: ignore[reportUnknownArgumentType] + return await call_test_func(row=args[0]) # pyright: ignore[reportUnknownVariableType] + else: + # For batch mode, check if called with rows argument + if ( + len(args) == 1 # pyright: ignore[reportUnknownArgumentType] + and isinstance(args[0], list) + and all(isinstance(r, EvaluationRow) for r in args[0]) # pyright: ignore[reportUnknownVariableType] + and not kwargs + ): + return await call_test_func(rows=args[0]) # pyright: ignore[reportUnknownVariableType] + # Also check if called with keyword argument 'rows' + if ( + len(args) == 0 # pyright: ignore[reportUnknownArgumentType] + and "rows" in kwargs + and isinstance(kwargs["rows"], list) + and all(isinstance(r, EvaluationRow) for r in kwargs["rows"]) # pyright: ignore[reportUnknownVariableType] + ): + return await call_test_func(**kwargs) # pyright: ignore[reportUnknownVariableType, reportUnknownArgumentType] + + # If not a direct call, use the pytest wrapper + return await pytest_wrapper(*args, **kwargs) # pyright: ignore[reportUnknownVariableType, reportGeneralTypeIssues] + + dual_mode_wrapper._origin_func = test_func # pyright: ignore[reportFunctionMemberAccess] + dual_mode_wrapper._metainfo = { # pyright: ignore[reportFunctionMemberAccess] + "mode": mode, + "max_rollout_concurrency": max_concurrent_rollouts, + "max_evaluation_concurrency": max_concurrent_evaluations, + } + + # Copy all attributes from the pytest wrapper to our dual mode wrapper + + functools.update_wrapper(dual_mode_wrapper, pytest_wrapper) # pyright: ignore[reportUnknownArgumentType] + + return dual_mode_wrapper # pyright: ignore[reportUnknownVariableType] diff --git a/eval_protocol/pytest/evaluation_test.py b/eval_protocol/pytest/evaluation_test.py index 8d15bd8c..8d32ed2c 100644 --- a/eval_protocol/pytest/evaluation_test.py +++ b/eval_protocol/pytest/evaluation_test.py @@ -1,18 +1,13 @@ import asyncio -import functools import inspect -import json -import math import os -import pathlib -import statistics -import time from collections import defaultdict from typing import Any, Callable +from typing_extensions import Unpack +from collections.abc import Sequence import pytest - from eval_protocol.dataset_logger import default_logger from eval_protocol.dataset_logger.dataset_logger import DatasetLogger from eval_protocol.human_id import generate_id, num_combinations @@ -22,12 +17,16 @@ EvaluationRow, EvaluationThreshold, EvaluationThresholdDict, - InputMetadata, - Message, Status, ) -from eval_protocol.pytest.handle_persist_flow import handle_persist_flow -from eval_protocol.pytest.parameterize import pytest_parametrize +from eval_protocol.pytest.dual_mode_wrapper import create_dual_mode_wrapper +from eval_protocol.pytest.evaluation_test_postprocess import postprocess +from eval_protocol.pytest.execution import execute_pytest +from eval_protocol.pytest.generate_parameter_combinations import ( + ParameterizedTestKwargs, + generate_parameter_combinations, +) +from eval_protocol.pytest.parameterize import pytest_parametrize, create_dynamically_parameterized_wrapper from eval_protocol.pytest.validate_signature import validate_signature from eval_protocol.pytest.default_dataset_adapter import default_dataset_adapter from eval_protocol.pytest.default_mcp_gym_rollout_processor import MCPGymRolloutProcessor @@ -48,10 +47,6 @@ from eval_protocol.pytest.utils import ( AggregationMethod, - aggregate, - create_dynamically_parameterized_wrapper, - extract_effort_tag, - generate_parameter_combinations, log_eval_status_and_rows, parse_ep_completion_params, parse_ep_max_concurrent_rollouts, @@ -59,183 +54,20 @@ parse_ep_num_runs, parse_ep_passed_threshold, rollout_processor_with_retry, - sanitize_filename, ) -from eval_protocol.stats.confidence_intervals import compute_fixed_set_mu_ci from ..common_utils import load_jsonl -def postprocess( - all_results: list[list[EvaluationRow]], - aggregation_method: AggregationMethod, - threshold: EvaluationThreshold | None, - active_logger: DatasetLogger, - mode: EvaluationTestMode, - completion_params: CompletionParams, - test_func_name: str, - num_runs: int, -): - scores = [ - sum([r.evaluation_result.score for r in result if r.evaluation_result]) / len(result) for result in all_results - ] - agg_score = aggregate(scores, aggregation_method) - - # Compute 95% confidence interval for the fixed-set mean μ (by-question, using repeats) - ci_low: float | None = None - ci_high: float | None = None - standard_error: float | None = None - if aggregation_method == "mean": - try: - result_ci = compute_fixed_set_mu_ci([item for sublist in all_results for item in sublist]) - _, mu_ci_low, mu_ci_high, se = result_ci - if mu_ci_low is not None and mu_ci_high is not None and se is not None: - ci_low = float(mu_ci_low) - ci_high = float(mu_ci_high) - standard_error = float(se) - # Keep agg_score as-is (mean over scores). For equal repeats per question these match. - except Exception: - ci_low = None - ci_high = None - standard_error = None - - # Determine if the evaluation passed based on threshold - passed = None - - if threshold is not None: - success_passed, standard_error_passed = True, True - - success_passed = agg_score >= threshold.success - - if threshold.standard_error is not None and standard_error is not None: - standard_error_passed = standard_error <= threshold.standard_error - - passed = success_passed and standard_error_passed - - # Update eval metadata passed field for all results - for result in all_results: - for r in result: - if r.eval_metadata is not None: - r.eval_metadata.passed = passed - if r.evaluation_result is not None: - r.evaluation_result.agg_score = agg_score - r.evaluation_result.standard_error = standard_error - active_logger.log(r) - - # Optional: print and/or persist a summary artifact for CI - try: - should_print = os.getenv("EP_PRINT_SUMMARY") == "1" - summary_path = os.getenv("EP_SUMMARY_JSON") - suite_name = test_func_name - model_used = completion_params["model"] # pyright: ignore[reportAny] - total_rows = len([item for sublist in all_results for item in sublist]) - summary_obj = { - "suite": suite_name, - "model": model_used, - "agg_score": float(agg_score), - "num_runs": num_runs, - "rows": total_rows, - } - if ci_low is not None and ci_high is not None and standard_error is not None: - summary_obj["agg_ci_low"] = ci_low - summary_obj["agg_ci_high"] = ci_high - summary_obj["standard_error"] = standard_error - - # Aggregate per-metric mean and 95% CI when available - metrics_summary: dict[str, dict[str, float]] = {} - - metric_scores: dict[str, list[float]] = defaultdict(list) - for r in [item for sublist in all_results for item in sublist]: - if r.evaluation_result and r.evaluation_result.metrics: - for m_name, m_res in r.evaluation_result.metrics.items(): - if getattr(m_res, "score", None) is not None: - metric_scores[m_name].append(m_res.score) - for m_name, vals in metric_scores.items(): - if len(vals) == 0: - continue - m_mean = sum(vals) / len(vals) - m_low = None - m_high = None - if len(vals) >= 2: - try: - m_std = statistics.stdev(vals) - m_se = m_std / math.sqrt(len(vals)) - m_margin = 1.96 * m_se - m_low = max(0.0, m_mean - m_margin) - m_high = min(1.0, m_mean + m_margin) - except Exception: - m_low = None - m_high = None - entry: dict[str, float] = {"mean": float(m_mean)} - if m_low is not None and m_high is not None: - entry["ci_low"] = float(m_low) - entry["ci_high"] = float(m_high) - metrics_summary[m_name] = entry - if metrics_summary: - summary_obj["metrics_agg"] = metrics_summary - if should_print: - if ci_low is not None and ci_high is not None and standard_error is not None: - print( - f"EP Summary | suite={suite_name} model={model_used} agg={summary_obj['agg_score']:.3f} se={summary_obj['standard_error']:.3f} ci95=[{ci_low:.3f},{ci_high:.3f}] runs={num_runs} rows={total_rows}" - ) - else: - print( - f"EP Summary | suite={suite_name} model={model_used} agg={summary_obj['agg_score']:.3f} runs={num_runs} rows={total_rows}" - ) - # As per project convention, avoid printing per-metric CI lines to reduce noise - if summary_path: - if not isinstance(model_used, str): - raise ValueError(f"Model used is not a string: {model_used}") - model_slug = sanitize_filename(model_used) - effort_tag = extract_effort_tag(completion_params) or "" - effort_suffix = f"__effort-{sanitize_filename(effort_tag)}" if effort_tag else "" - base_name = f"{suite_name}__{model_slug}{effort_suffix}__{mode}__runs{num_runs}.json" - - p = pathlib.Path(summary_path) - summary_obj["timestamp"] = int(time.time()) - - # When a directory is provided (or a path without .json), write per-combination files inside it - if p.suffix.lower() != ".json" or summary_path.endswith("/") or p.is_dir(): - out_dir = p - out_dir.mkdir(parents=True, exist_ok=True) - out_file = out_dir / base_name - else: - # A file path was provided - # If multiple parameterizations exist, write side-by-side files with suffixes based on base name - parent = p.parent - parent.mkdir(parents=True, exist_ok=True) - # If we detected an effort tag, fan out to separate files; otherwise write to the exact file - if effort_tag: - out_file = parent / f"{p.stem}__{sanitize_filename(effort_tag)}{p.suffix}" - else: - out_file = p - - with open(out_file, "w", encoding="utf-8") as f: - json.dump(summary_obj, f) - except Exception: - # Do not fail evaluation if summary writing fails - pass - - handle_persist_flow(all_results, test_func_name) - - # Check threshold after logging - if threshold is not None and not passed: - assert agg_score >= threshold.success, f"Aggregated score {agg_score:.3f} below threshold {threshold.success}" - if threshold.standard_error is not None and standard_error is not None: - assert standard_error <= threshold.standard_error, ( - f"Standard error {standard_error:.3f} above threshold {threshold.standard_error}" - ) - - def evaluation_test( *, - completion_params: list[CompletionParams | None] | None = None, - input_messages: list[InputMessagesParam | None] | None = None, + completion_params: Sequence[CompletionParams | None] | None = None, + input_messages: Sequence[InputMessagesParam | None] | None = None, input_dataset: list[DatasetPathParam] | None = None, - input_rows: list[EvaluationRow] | None = None, + input_rows: Sequence[list[EvaluationRow]] | None = None, dataset_adapter: Callable[[list[dict[str, Any]]], Dataset] = default_dataset_adapter, # pyright: ignore[reportExplicitAny] rollout_processor: RolloutProcessor | None = None, - evaluation_test_kwargs: list[EvaluationInputParam | None] | None = None, + evaluation_test_kwargs: Sequence[EvaluationInputParam | None] | None = None, rollout_processor_kwargs: RolloutProcessorInputParam | None = None, aggregation_method: AggregationMethod = "mean", passed_threshold: EvaluationThreshold | float | EvaluationThresholdDict | None = None, @@ -367,35 +199,32 @@ def decorator( ) # Create wrapper function with exact signature that pytest expects - def create_wrapper_with_signature() -> Callable: + def create_wrapper_with_signature() -> Callable[[], None]: # Create the function body that will be used invocation_id = generate_id() - async def wrapper_body(**kwargs): + async def wrapper_body(**kwargs: Unpack[ParameterizedTestKwargs]) -> None: eval_metadata = None - all_results: List[List[EvaluationRow]] = [[] for _ in range(num_runs)] + all_results: list[list[EvaluationRow]] = [[] for _ in range(num_runs)] experiment_id = generate_id() - def _log_eval_error(status: Status, rows: Optional[List[EvaluationRow]] | None, passed: bool) -> None: + def _log_eval_error(status: Status, rows: list[EvaluationRow] | None, passed: bool) -> None: log_eval_status_and_rows(eval_metadata, rows, status, passed, active_logger) try: # Handle dataset loading - data: List[EvaluationRow] = [] + data: list[EvaluationRow] = [] # Track all rows processed in the current run for error logging - processed_rows_in_run: List[EvaluationRow] = [] + processed_rows_in_run: list[EvaluationRow] = [] if "dataset_path" in kwargs and kwargs["dataset_path"] is not None: - ds_arg = kwargs["dataset_path"] + ds_arg: list[str] = kwargs["dataset_path"] # Support either a single path or a list of paths; if a list is provided, # concatenate the rows from each file in order. - if isinstance(ds_arg, list): - data_jsonl = [] - for p in ds_arg: - data_jsonl.extend(load_jsonl(p)) - else: - data_jsonl = load_jsonl(ds_arg) + data_jsonl: list[dict[str, object]] = [] + for p in ds_arg: + data_jsonl.extend(load_jsonl(p)) # Apply override for max rows if present if max_dataset_rows is not None: data_jsonl = data_jsonl[:max_dataset_rows] @@ -403,12 +232,7 @@ def _log_eval_error(status: Status, rows: Optional[List[EvaluationRow]] | None, elif "input_messages" in kwargs and kwargs["input_messages"] is not None: # Support either a single row (List[Message]) or many rows (List[List[Message]]) im = kwargs["input_messages"] - if isinstance(im, list) and len(im) > 0 and isinstance(im[0], Message): - # Single row of Message objects - data = [EvaluationRow(messages=im)] - else: - # Multiple rows: list of List[Message] - data = [EvaluationRow(messages=m) for m in im] + data = [EvaluationRow(messages=im)] elif "input_rows" in kwargs and kwargs["input_rows"] is not None: # Use pre-constructed EvaluationRow objects directly data = kwargs["input_rows"] @@ -438,13 +262,13 @@ def _log_eval_error(status: Status, rows: Optional[List[EvaluationRow]] | None, status=Status.eval_running(), num_runs=num_runs, aggregation_method=aggregation_method, - passed_threshold=threshold, + passed_threshold=passed_threshold, passed=None, ) for row in data: - if row.input_metadata is None: - row.input_metadata = InputMetadata() - row.input_metadata.completion_params = completion_params + row.input_metadata.completion_params = ( + completion_params if completion_params is not None else {} + ) # Add mode to session_data if row.input_metadata.session_data is None: row.input_metadata.session_data = {} @@ -460,7 +284,7 @@ def _log_eval_error(status: Status, rows: Optional[List[EvaluationRow]] | None, # Prepare rollout processor config once; we will generate fresh outputs per run config = RolloutProcessorConfig( - completion_params=completion_params, + completion_params=completion_params if completion_params is not None else {}, mcp_config_path=mcp_config_path or "", max_concurrent_rollouts=max_concurrent_rollouts, server_script_path=server_script_path, @@ -494,51 +318,57 @@ async def execute_run(i: int, config: RolloutProcessorConfig): # prepare parallel eval helper function semaphore = asyncio.Semaphore(max_concurrent_evaluations) - async def _execute_eval_with_semaphore(**inner_kwargs): + async def _execute_pointwise_eval_with_semaphore( + row: EvaluationRow, + ) -> EvaluationRow: async with semaphore: - # NOTE: we will still evaluate errored rows (give users control over this) - # i.e., they can choose to give EvaluateResult.score = 0 for errored rows in their test_func - if "row" in inner_kwargs: - result = await execute_pytest( - test_func, - processed_row=inner_kwargs["row"], - evaluation_test_kwargs=kwargs.get("evaluation_test_kwargs") or {}, + result = await execute_pytest( + test_func, + processed_row=row, + evaluation_test_kwargs=kwargs.get("evaluation_test_kwargs") or {}, + ) + if not isinstance(result, EvaluationRow): + raise ValueError( + f"Test function {test_func.__name__} did not return an EvaluationRow instance. You must return an EvaluationRow instance from your test function decorated with @evaluation_test." ) - if result is None or not isinstance(result, EvaluationRow): - raise ValueError( - f"Test function {test_func.__name__} did not return an EvaluationRow instance. You must return an EvaluationRow instance from your test function decorated with @evaluation_test." - ) - return result - if "rows" in inner_kwargs: - results = await execute_pytest( - test_func, - processed_dataset=inner_kwargs["rows"], - evaluation_test_kwargs=kwargs.get("evaluation_test_kwargs") or {}, + return result + + async def _execute_groupwise_eval_with_semaphore( + rows: list[EvaluationRow], + ) -> list[EvaluationRow]: + async with semaphore: + results = await execute_pytest( + test_func, + processed_dataset=rows, + evaluation_test_kwargs=kwargs.get("evaluation_test_kwargs") or {}, + ) + if not isinstance(results, list): + raise ValueError( + f"Test function {test_func.__name__} did not return a list of EvaluationRow instances. You must return a list of EvaluationRow instances from your test function decorated with @evaluation_test." ) - if results is None or not isinstance(results, list): - raise ValueError( - f"Test function {test_func.__name__} did not return a list of EvaluationRow instances. You must return a list of EvaluationRow instances from your test function decorated with @evaluation_test." - ) - return results + return results if mode == "pointwise": # Pointwise mode, rollouts will return as they complete so we can pipeline evaluation_test execution - tasks = [] + pointwise_tasks: list[asyncio.Task[EvaluationRow]] = [] # Use wrapper that handles retry logic internally async for row in rollout_processor_with_retry(rollout_processor, fresh_dataset, config): - tasks.append(asyncio.create_task(_execute_eval_with_semaphore(row=row))) - - results = await asyncio.gather(*tasks) + pointwise_tasks.append( + asyncio.create_task(_execute_pointwise_eval_with_semaphore(row=row)) + ) + results = await asyncio.gather(*pointwise_tasks) all_results[i] = results elif mode == "groupwise": # rollout all the completion_params for the same row at once, and then send the output to the test_func - row_groups = defaultdict(list) # key: row_id, value: list of rollout_result - tasks: List[asyncio.Task[List[EvaluationRow]]] = [] + row_groups = defaultdict( # pyright: ignore[reportUnknownVariableType] + list + ) # key: row_id, value: list of rollout_result + tasks: list[asyncio.Task[list[EvaluationRow]]] = [] # completion_groups = [] for idx, cp in enumerate(original_completion_params): config = RolloutProcessorConfig( - completion_params=cp, + completion_params=cp if cp is not None else {}, mcp_config_path=mcp_config_path or "", max_concurrent_rollouts=max_concurrent_rollouts, server_script_path=server_script_path, @@ -548,11 +378,11 @@ async def _execute_eval_with_semaphore(**inner_kwargs): ) lst = [] - async def _collect_result(config, lst): + async def _collect_result(config, lst): # pyright: ignore[reportUnknownParameterType, reportMissingParameterType] result = [] - async for row in rollout_processor_with_retry(rollout_processor, lst, config): - result.append(row) - return result + async for row in rollout_processor_with_retry(rollout_processor, lst, config): # pyright: ignore[reportUnknownArgumentType] + result.append(row) # pyright: ignore[reportUnknownMemberType] + return result # pyright: ignore[reportUnknownVariableType] for ori_row in fresh_dataset: copied_row = ori_row.model_copy(deep=True) @@ -560,34 +390,34 @@ async def _collect_result(config, lst): copied_row.execution_metadata.rollout_id = ( str(ori_row.execution_metadata.rollout_id) + "_" + str(idx) ) - copied_row.input_metadata.completion_params = cp - lst.append(copied_row) - tasks.append(asyncio.create_task(_collect_result(config, lst))) + copied_row.input_metadata.completion_params = cp if cp is not None else {} + lst.append(copied_row) # pyright: ignore[reportUnknownMemberType] + tasks.append(asyncio.create_task(_collect_result(config, lst))) # pyright: ignore[reportUnknownArgumentType] rollout_results = await asyncio.gather(*tasks) for result in rollout_results: for row in result: - row_groups[row.input_metadata.row_id].append(row) + row_groups[row.input_metadata.row_id].append(row) # pyright: ignore[reportUnknownMemberType] tasks = [] - for row_id, rows in row_groups.items(): - tasks.append(asyncio.create_task(_execute_eval_with_semaphore(rows=rows))) + for _, rows in row_groups.items(): # pyright: ignore[reportUnknownVariableType] + tasks.append(asyncio.create_task(_execute_groupwise_eval_with_semaphore(rows=rows))) # pyright: ignore[reportUnknownArgumentType] results = [] for task in tasks: res = await task - results.extend(res) + results.extend(res) # pyright: ignore[reportUnknownMemberType] all_results[i] = results else: # Batch mode: collect all results first, then evaluate (no pipelining) input_dataset = [] async for row in rollout_processor_with_retry(rollout_processor, fresh_dataset, config): - input_dataset.append(row) + input_dataset.append(row) # pyright: ignore[reportUnknownMemberType] # NOTE: we will still evaluate errored rows (give users control over this) # i.e., they can choose to give EvaluateResult.score = 0 for errored rows in their test_func results = await execute_pytest( test_func, - processed_dataset=input_dataset, + processed_dataset=input_dataset, # pyright: ignore[reportUnknownArgumentType] evaluation_test_kwargs=kwargs.get("evaluation_test_kwargs") or {}, ) - if results is None: + if results is None: # pyright: ignore[reportUnnecessaryComparison] raise ValueError( f"Test function {test_func.__name__} did not return an EvaluationRow instance. You must return an EvaluationRow instance from your test function decorated with @evaluation_test." ) @@ -599,7 +429,7 @@ async def _collect_result(config, lst): raise ValueError( f"Test function {test_func.__name__} returned an empty list. You must return a non-empty list of EvaluationRow instances from your test function decorated with @evaluation_test." ) - if not all(isinstance(r, EvaluationRow) for r in results): + if not all(isinstance(r, EvaluationRow) for r in results): # pyright: ignore[reportUnnecessaryIsInstance] raise ValueError( f"Test function {test_func.__name__} returned a list containing non-EvaluationRow instances. You must return a list of EvaluationRow instances from your test function decorated with @evaluation_test." ) @@ -626,27 +456,27 @@ async def _collect_result(config, lst): # For other processors, create all tasks at once and run in parallel tasks = [] for i in range(num_runs): - tasks.append(asyncio.create_task(execute_run(i, config))) - await asyncio.gather(*tasks) + tasks.append(asyncio.create_task(execute_run(i, config))) # pyright: ignore[reportUnknownMemberType] + await asyncio.gather(*tasks) # pyright: ignore[reportUnknownArgumentType] # for groupwise mode, the result contains eval otuput from multiple completion_params, we need to differentiate them # rollout_id is used to differentiate the result from different completion_params if mode == "groupwise": - results_by_group = [ + results_by_group = [ # pyright: ignore[reportUnknownVariableType] [[] for _ in range(num_runs)] for _ in range(len(original_completion_params)) ] for i_run, result in enumerate(all_results): for r in result: - completion_param_idx = int(r.execution_metadata.rollout_id.split("_")[1]) - results_by_group[completion_param_idx][i_run].append(r) - for rollout_id, result in enumerate(results_by_group): + completion_param_idx = int(r.execution_metadata.rollout_id.split("_")[1]) # pyright: ignore[reportOptionalMemberAccess] + results_by_group[completion_param_idx][i_run].append(r) # pyright: ignore[reportUnknownMemberType] + for rollout_id, result in enumerate(results_by_group): # pyright: ignore[reportUnknownVariableType, reportUnknownArgumentType] postprocess( - result, + result, # pyright: ignore[reportUnknownArgumentType] aggregation_method, - threshold, + passed_threshold, active_logger, mode, - original_completion_params[rollout_id], + original_completion_params[rollout_id], # pyright: ignore[reportArgumentType] test_func.__name__, num_runs, ) @@ -654,10 +484,10 @@ async def _collect_result(config, lst): postprocess( all_results, aggregation_method, - threshold, + passed_threshold, active_logger, mode, - completion_params, + completion_params, # pyright: ignore[reportArgumentType] test_func.__name__, num_runs, ) @@ -665,93 +495,34 @@ async def _collect_result(config, lst): except AssertionError: _log_eval_error( Status.eval_finished(), - processed_rows_in_run if "processed_rows_in_run" in locals() else None, + locals().get("processed_rows_in_run", None), passed=False, ) raise except Exception as e: _log_eval_error( Status.error(str(e)), - processed_rows_in_run if "processed_rows_in_run" in locals() else None, + locals().get("processed_rows_in_run", None), passed=False, ) raise - return create_dynamically_parameterized_wrapper(test_func, wrapper_body, test_param_names) + return create_dynamically_parameterized_wrapper( + test_func, + wrapper_body, + pytest_parametrize_args["argnames"], + ) # Create the pytest wrapper pytest_wrapper = create_wrapper_with_signature() pytest_wrapper = pytest.mark.parametrize(**pytest_parametrize_args)(pytest_wrapper) pytest_wrapper = pytest.mark.asyncio(pytest_wrapper) - def create_dual_mode_wrapper() -> Callable: - """ - Creates a wrapper that supports both pytest parameterized execution and direct function calls. - - This wrapper enables the decorated evaluation test function to be used in two ways: - 1. As a pytest test (via pytest.mark.parametrize) with full parameterization - 2. As a direct function call with EvaluationRow data for programmatic use - - The wrapper automatically detects the calling pattern and routes to the appropriate - execution path, ensuring consistent behavior regardless of how the function is invoked. - - Returns: - A callable that can handle both pytest test execution and direct function calls - """ - - # Check if the test function is async - is_async = asyncio.iscoroutinefunction(test_func) - - async def call_test_func(**call_kwargs): - """Helper to call test_func with proper async/sync handling""" - if is_async: - return await test_func(**call_kwargs) - else: - return test_func(**call_kwargs) - - async def dual_mode_wrapper(*args, **kwargs): - # Check if this is a direct call with the expected signature - if mode == "pointwise": - # For pointwise mode, check if called with a single row argument - if len(args) == 1 and isinstance(args[0], EvaluationRow) and not kwargs: - return await call_test_func(row=args[0]) - else: - # For batch mode, check if called with rows argument - if ( - len(args) == 1 - and isinstance(args[0], list) - and all(isinstance(r, EvaluationRow) for r in args[0]) - and not kwargs - ): - return await call_test_func(rows=args[0]) - # Also check if called with keyword argument 'rows' - if ( - len(args) == 0 - and "rows" in kwargs - and isinstance(kwargs["rows"], list) - and all(isinstance(r, EvaluationRow) for r in kwargs["rows"]) - ): - return await call_test_func(**kwargs) - - # If not a direct call, use the pytest wrapper - return await pytest_wrapper(*args, **kwargs) - - dual_mode_wrapper._origin_func = test_func - dual_mode_wrapper._metainfo = { - "mode": mode, - "max_rollout_concurrency": max_concurrent_rollouts, - "max_evaluation_concurrency": max_concurrent_evaluations, - } - - # Copy all attributes from the pytest wrapper to our dual mode wrapper - - functools.update_wrapper(dual_mode_wrapper, pytest_wrapper) - - return dual_mode_wrapper - # Create the dual mode wrapper - dual_mode_wrapper = create_dual_mode_wrapper() + dual_mode_wrapper = create_dual_mode_wrapper( # pyright: ignore[reportUnknownVariableType] + test_func, mode, max_concurrent_rollouts, max_concurrent_evaluations, pytest_wrapper + ) - return dual_mode_wrapper + return dual_mode_wrapper # pyright: ignore[reportReturnType, reportUnknownVariableType] return decorator diff --git a/eval_protocol/pytest/evaluation_test_postprocess.py b/eval_protocol/pytest/evaluation_test_postprocess.py new file mode 100644 index 00000000..25970e8f --- /dev/null +++ b/eval_protocol/pytest/evaluation_test_postprocess.py @@ -0,0 +1,174 @@ +from collections import defaultdict +import json +import math +import os +import pathlib +import statistics +import time +from eval_protocol.dataset_logger.dataset_logger import DatasetLogger +from eval_protocol.models import CompletionParams, EvaluationRow, EvaluationThreshold +from eval_protocol.pytest.handle_persist_flow import handle_persist_flow +from eval_protocol.pytest.types import EvaluationTestMode +from eval_protocol.pytest.utils import AggregationMethod, aggregate, extract_effort_tag, sanitize_filename # pyright: ignore[reportUnknownVariableType] +from eval_protocol.stats.confidence_intervals import compute_fixed_set_mu_ci + + +def postprocess( + all_results: list[list[EvaluationRow]], + aggregation_method: AggregationMethod, + threshold: EvaluationThreshold | None, + active_logger: DatasetLogger, + mode: EvaluationTestMode, + completion_params: CompletionParams, + test_func_name: str, + num_runs: int, +): + scores = [ + sum([r.evaluation_result.score for r in result if r.evaluation_result]) / len(result) for result in all_results + ] + agg_score = aggregate(scores, aggregation_method) + + # Compute 95% confidence interval for the fixed-set mean μ (by-question, using repeats) + ci_low: float | None = None + ci_high: float | None = None + standard_error: float | None = None + if aggregation_method == "mean": + try: + result_ci = compute_fixed_set_mu_ci([item for sublist in all_results for item in sublist]) + _, mu_ci_low, mu_ci_high, se = result_ci + if mu_ci_low is not None and mu_ci_high is not None and se is not None: + ci_low = float(mu_ci_low) + ci_high = float(mu_ci_high) + standard_error = float(se) + # Keep agg_score as-is (mean over scores). For equal repeats per question these match. + except Exception: + ci_low = None + ci_high = None + standard_error = None + + # Determine if the evaluation passed based on threshold + passed = None + + if threshold is not None: + success_passed, standard_error_passed = True, True + + success_passed = agg_score >= threshold.success + + if threshold.standard_error is not None and standard_error is not None: + standard_error_passed = standard_error <= threshold.standard_error + + passed = success_passed and standard_error_passed + + # Update eval metadata passed field for all results + for result in all_results: + for r in result: + if r.eval_metadata is not None: + r.eval_metadata.passed = passed + if r.evaluation_result is not None: + r.evaluation_result.agg_score = agg_score + r.evaluation_result.standard_error = standard_error + active_logger.log(r) + + # Optional: print and/or persist a summary artifact for CI + try: + should_print = os.getenv("EP_PRINT_SUMMARY") == "1" + summary_path = os.getenv("EP_SUMMARY_JSON") + suite_name = test_func_name + model_used = completion_params["model"] # pyright: ignore[reportAny] + total_rows = len([item for sublist in all_results for item in sublist]) + summary_obj = { + "suite": suite_name, + "model": model_used, + "agg_score": float(agg_score), + "num_runs": num_runs, + "rows": total_rows, + } + if ci_low is not None and ci_high is not None and standard_error is not None: + summary_obj["agg_ci_low"] = ci_low + summary_obj["agg_ci_high"] = ci_high + summary_obj["standard_error"] = standard_error + + # Aggregate per-metric mean and 95% CI when available + metrics_summary: dict[str, dict[str, float]] = {} + + metric_scores: dict[str, list[float]] = defaultdict(list) + for r in [item for sublist in all_results for item in sublist]: + if r.evaluation_result and r.evaluation_result.metrics: + for m_name, m_res in r.evaluation_result.metrics.items(): + if getattr(m_res, "score", None) is not None: + metric_scores[m_name].append(m_res.score) + for m_name, vals in metric_scores.items(): + if len(vals) == 0: + continue + m_mean = sum(vals) / len(vals) + m_low = None + m_high = None + if len(vals) >= 2: + try: + m_std = statistics.stdev(vals) + m_se = m_std / math.sqrt(len(vals)) + m_margin = 1.96 * m_se + m_low = max(0.0, m_mean - m_margin) + m_high = min(1.0, m_mean + m_margin) + except Exception: + m_low = None + m_high = None + entry: dict[str, float] = {"mean": float(m_mean)} + if m_low is not None and m_high is not None: + entry["ci_low"] = float(m_low) + entry["ci_high"] = float(m_high) + metrics_summary[m_name] = entry + if metrics_summary: + summary_obj["metrics_agg"] = metrics_summary + if should_print: + if ci_low is not None and ci_high is not None and standard_error is not None: + print( + f"EP Summary | suite={suite_name} model={model_used} agg={summary_obj['agg_score']:.3f} se={summary_obj['standard_error']:.3f} ci95=[{ci_low:.3f},{ci_high:.3f}] runs={num_runs} rows={total_rows}" + ) + else: + print( + f"EP Summary | suite={suite_name} model={model_used} agg={summary_obj['agg_score']:.3f} runs={num_runs} rows={total_rows}" + ) + # As per project convention, avoid printing per-metric CI lines to reduce noise + if summary_path: + if not isinstance(model_used, str): + raise ValueError(f"Model used is not a string: {model_used}") + model_slug = sanitize_filename(model_used) + effort_tag = extract_effort_tag(completion_params) or "" + effort_suffix = f"__effort-{sanitize_filename(effort_tag)}" if effort_tag else "" + base_name = f"{suite_name}__{model_slug}{effort_suffix}__{mode}__runs{num_runs}.json" + + p = pathlib.Path(summary_path) + summary_obj["timestamp"] = int(time.time()) + + # When a directory is provided (or a path without .json), write per-combination files inside it + if p.suffix.lower() != ".json" or summary_path.endswith("/") or p.is_dir(): + out_dir = p + out_dir.mkdir(parents=True, exist_ok=True) + out_file = out_dir / base_name + else: + # A file path was provided + # If multiple parameterizations exist, write side-by-side files with suffixes based on base name + parent = p.parent + parent.mkdir(parents=True, exist_ok=True) + # If we detected an effort tag, fan out to separate files; otherwise write to the exact file + if effort_tag: + out_file = parent / f"{p.stem}__{sanitize_filename(effort_tag)}{p.suffix}" + else: + out_file = p + + with open(out_file, "w", encoding="utf-8") as f: + json.dump(summary_obj, f) + except Exception: + # Do not fail evaluation if summary writing fails + pass + + handle_persist_flow(all_results, test_func_name) + + # Check threshold after logging + if threshold is not None and not passed: + assert agg_score >= threshold.success, f"Aggregated score {agg_score:.3f} below threshold {threshold.success}" + if threshold.standard_error is not None and standard_error is not None: + assert standard_error <= threshold.standard_error, ( + f"Standard error {standard_error:.3f} above threshold {threshold.standard_error}" + ) diff --git a/eval_protocol/pytest/execution.py b/eval_protocol/pytest/execution.py index 5d7ba658..40ff3d31 100644 --- a/eval_protocol/pytest/execution.py +++ b/eval_protocol/pytest/execution.py @@ -1,15 +1,19 @@ import asyncio -from collections.abc import Awaitable +from collections.abc import Awaitable, Callable +from typing import cast from eval_protocol.models import EvaluationRow -from eval_protocol.pytest.types import EvaluationInputParam, TestFunction +from eval_protocol.pytest.types import Dataset, EvaluationInputParam, TestFunction async def execute_pytest( test_func: TestFunction, processed_row: EvaluationRow | None = None, - processed_dataset: list[EvaluationRow] | None = None, + processed_dataset: Dataset | None = None, evaluation_test_kwargs: EvaluationInputParam | None = None, -) -> EvaluationRow | list[EvaluationRow]: +) -> EvaluationRow | Dataset: + """ + Generic function that handles both sync and async test functions. + """ if evaluation_test_kwargs is not None: if "row" in evaluation_test_kwargs: raise ValueError("'row' is a reserved parameter for the evaluation function") @@ -19,13 +23,19 @@ async def execute_pytest( # Handle both sync and async test functions if asyncio.iscoroutinefunction(test_func): if processed_row is not None: + test_func = cast(Callable[[EvaluationRow], Awaitable[EvaluationRow]], test_func) return await test_func(processed_row) if processed_dataset is not None: + test_func = cast(Callable[[list[EvaluationRow]], Awaitable[list[EvaluationRow]]], test_func) return await test_func(processed_dataset) + test_func = cast(Callable[[], Awaitable[EvaluationRow]], test_func) return await test_func() else: if processed_row is not None: - row = test_func(processed_row) + test_func = cast(Callable[[EvaluationRow], EvaluationRow], test_func) + return test_func(processed_row) if processed_dataset is not None: + test_func = cast(Callable[[Dataset], Dataset], test_func) return test_func(processed_dataset) + test_func = cast(Callable[[], EvaluationRow], test_func) return test_func() diff --git a/eval_protocol/pytest/generate_parameter_combinations.py b/eval_protocol/pytest/generate_parameter_combinations.py new file mode 100644 index 00000000..53ee7a78 --- /dev/null +++ b/eval_protocol/pytest/generate_parameter_combinations.py @@ -0,0 +1,122 @@ +from typing import TypedDict +from eval_protocol.models import CompletionParams, EvaluationRow +from eval_protocol.pytest.types import Dataset, DatasetPathParam, EvaluationInputParam, InputMessagesParam +from eval_protocol.pytest.utils import parse_ep_max_rows +from collections.abc import Sequence + + +InputDatasetKwarg = list[DatasetPathParam] | None +""" +Either a single dataset path or a list of dataset paths depending on if +combine_datasets is True or False. If True, then you would expect to see a list +of dataset paths. If False, then you would expect to see a list with a single +dataset path. +""" + +CompletionParamsKwarg = CompletionParams | None +""" +Either a single completion params object or None. +""" + +InputMessagesKwarg = InputMessagesParam | None +InputRowsKwarg = Dataset | None +EvaluationTestKwargs = EvaluationInputParam | None + +CombinationTuple = tuple[ + InputDatasetKwarg, + CompletionParamsKwarg, + InputMessagesKwarg, + InputRowsKwarg, + EvaluationTestKwargs, +] + + +class ParameterizedTestKwargs(TypedDict): + """ + These are the type of parameters that can be passed to the generated pytest + function. Every experiment is a unique combination of these parameters. + """ + + dataset_path: InputDatasetKwarg + completion_params: CompletionParamsKwarg + input_messages: InputMessagesKwarg + input_rows: InputRowsKwarg + evaluation_test_kwargs: EvaluationTestKwargs + + +def generate_parameter_combinations( + input_dataset: list[DatasetPathParam] | None, + completion_params: Sequence[CompletionParams | None], + input_messages: Sequence[InputMessagesParam | None] | None, + input_rows: Sequence[list[EvaluationRow] | None] | None, + evaluation_test_kwargs: Sequence[EvaluationInputParam | None] | None, + max_dataset_rows: int | None, + combine_datasets: bool, +) -> list[CombinationTuple]: + """ + Generate all combinations of parameters for pytest parameterization. + + Args: + input_dataset: Dataset paths to use + completion_params: Completion parameters to test + input_messages: Input messages to use + input_rows: Pre-constructed EvaluationRow objects to use + evaluation_test_kwargs: Additional kwargs for evaluation tests + max_dataset_rows: Maximum number of dataset rows to process + combine_datasets: Whether to combine multiple datasets into one test + + Returns: + List of parameter tuples for pytest.mark.parametrize + """ + # Optionally combine multiple dataset paths into one logical dataset, + # or parameterize to run one dataset per test invocation. + datasets: Sequence[list[DatasetPathParam] | None] = [None] + if input_dataset is not None: + if combine_datasets: + datasets = [input_dataset] + else: + # Fan out: one dataset path per parameterization + datasets = [[p] for p in input_dataset] + + cps: Sequence[CompletionParams | None] = completion_params + + # Apply EP_MAX_DATASET_ROWS to input_messages, but do NOT parameterize over + # each row. Instead, pass the entire sliced list through in a single test run + # so summaries aggregate all rows together (AIME-style behavior). + messages: Sequence[InputMessagesParam | None] = [None] + if input_messages is not None: + effective_max_rows = parse_ep_max_rows(max_dataset_rows) + if effective_max_rows is not None: + sliced_messages: Sequence[InputMessagesParam | None] = input_messages[:effective_max_rows] + else: + sliced_messages = input_messages + # Wrap as a single parameter payload + messages = sliced_messages + + # Handle input_rows - similar to input_messages, apply max_dataset_rows if specified + if input_rows is not None: + effective_max_rows = parse_ep_max_rows(max_dataset_rows) + if effective_max_rows is not None: + input_rows = [row[:effective_max_rows] for row in input_rows if row is not None] + else: + input_rows = [None] + + if evaluation_test_kwargs is None: + evaluation_test_kwargs = [None] + + combinations: list[CombinationTuple] = [] + + # Generate all combinations + for ds in datasets: + for cp in cps: + for im in messages: + for ir in input_rows: + for etk in evaluation_test_kwargs: + # if no dataset, no messages, and no rows, raise an error + if ds is None and im is None and ir is None: + raise ValueError( + "No dataset, messages, or rows provided. Please provide at least one of input_dataset, input_messages, or input_rows." + ) + combinations.append((ds, cp, im, ir, etk)) + + return combinations diff --git a/eval_protocol/pytest/parameterize.py b/eval_protocol/pytest/parameterize.py index 4b3ffd51..f4a91c30 100644 --- a/eval_protocol/pytest/parameterize.py +++ b/eval_protocol/pytest/parameterize.py @@ -1,25 +1,26 @@ +import inspect from typing import TypedDict -from collections.abc import Sequence, Iterable +from collections.abc import Callable, Sequence, Iterable, Awaitable from _pytest.mark import ParameterSet from eval_protocol.models import CompletionParams, EvaluationRow -from eval_protocol.pytest.types import DatasetPathParam, EvaluationInputParam, InputMessagesParam -from eval_protocol.pytest.utils import CombinationTuple +from eval_protocol.pytest.generate_parameter_combinations import CombinationTuple +from eval_protocol.pytest.types import DatasetPathParam, EvaluationInputParam, InputMessagesParam, TestFunction class PytestParametrizeArgs(TypedDict): - argnames: str | Sequence[str] + argnames: Sequence[str] argvalues: Iterable[ParameterSet | Sequence[object] | object] def pytest_parametrize( combinations: list[CombinationTuple], input_dataset: list[DatasetPathParam] | None, - completion_params: list[CompletionParams | None] | None, - input_messages: list[InputMessagesParam | None] | None, - input_rows: list[EvaluationRow] | None, - evaluation_test_kwargs: list[EvaluationInputParam | None] | None, + completion_params: Sequence[CompletionParams | None] | None, + input_messages: Sequence[InputMessagesParam | None] | None, + input_rows: Sequence[list[EvaluationRow]] | None, + evaluation_test_kwargs: Sequence[EvaluationInputParam | None] | None, ) -> PytestParametrizeArgs: """ This function dynamically generates pytest.mark.parametrize arguments for a given @@ -65,3 +66,38 @@ def pytest_parametrize( param_tuples.append(tuple(param_tuple)) return PytestParametrizeArgs(argnames=argnames, argvalues=argvalues) + + +def create_dynamically_parameterized_wrapper( + test_func: TestFunction, wrapper_body: Callable[..., Awaitable[None]], test_param_names: Sequence[str] +) -> Callable[..., None]: + """ + Creates a wrapper function with dynamic parameters for pytest parameterization. + + This function takes a test function and creates a wrapper that: + 1. Preserves the original function's metadata using functools.wraps + 2. Creates a new function signature with the specified parameter names that maps to pytest.mark.parametrize decorator + 3. Returns a callable that can be used with pytest.mark.parametrize + + The function signature is dynamically created to match the parameter names expected by + pytest.mark.parametrize, ensuring that pytest can properly map the test parameters + to the function arguments. + + Args: + test_func: The original test function to wrap + wrapper_body: The function body that contains the actual test logic + test_param_names: List of parameter names for the dynamic signature + + Returns: + A wrapper function with the specified parameter signature that calls wrapper_body + """ + from functools import wraps + + @wraps(test_func) # pyright: ignore[reportArgumentType] + async def wrapper(**kwargs) -> None: # pyright: ignore[reportUnknownParameterType, reportMissingParameterType] + return await wrapper_body(**kwargs) + + parameters = [inspect.Parameter(name, inspect.Parameter.POSITIONAL_OR_KEYWORD) for name in test_param_names] + wrapper.__signature__ = inspect.Signature(parameters) # pyright: ignore[reportAttributeAccessIssue] + + return wrapper # pyright: ignore[reportUnknownVariableType, reportReturnType] diff --git a/eval_protocol/pytest/types.py b/eval_protocol/pytest/types.py index fc262a34..6b52ae33 100644 --- a/eval_protocol/pytest/types.py +++ b/eval_protocol/pytest/types.py @@ -36,10 +36,16 @@ # 1. an async/sync function that accepts EvaluationRow and returns EvaluationRow # 2. an async/sync function that accepts list[EvaluationRow] and returns list[EvaluationRow] TestFunction = ( - Callable[[EvaluationRow], EvaluationRow] + Callable[[], EvaluationRow] + | Callable[[], Awaitable[EvaluationRow]] + | Callable[[], Dataset] + | Callable[[], Awaitable[Dataset]] + | Callable[[EvaluationRow], EvaluationRow] | Callable[[EvaluationRow], Awaitable[EvaluationRow]] | Callable[[list[EvaluationRow]], list[EvaluationRow]] | Callable[[list[EvaluationRow]], Awaitable[list[EvaluationRow]]] + | Callable[[Dataset], Dataset] + | Callable[[Dataset], Awaitable[Dataset]] ) diff --git a/eval_protocol/pytest/utils.py b/eval_protocol/pytest/utils.py index 51113dfb..a25d17d7 100644 --- a/eval_protocol/pytest/utils.py +++ b/eval_protocol/pytest/utils.py @@ -1,73 +1,33 @@ import asyncio -import inspect +from collections.abc import Sequence import os import re from dataclasses import replace -from typing import Any, Callable, Dict, List, Literal, Optional, Union +from typing import Any, Literal from eval_protocol.dataset_logger.dataset_logger import DatasetLogger -from eval_protocol.models import EvalMetadata, EvaluationRow, EvaluationThreshold, EvaluationThresholdDict, Status +from eval_protocol.models import ( + EvalMetadata, + EvaluationRow, + EvaluationThreshold, + EvaluationThresholdDict, + Status, + CompletionParams, +) from eval_protocol.pytest.rollout_processor import RolloutProcessor from eval_protocol.pytest.types import ( - CompletionParams, - DatasetPathParam, - EvaluationInputParam, - InputMessagesParam, RolloutProcessorConfig, ) -from eval_protocol.pytest.exception_config import ExceptionHandlerConfig, get_default_exception_handler_config +from eval_protocol.pytest.exception_config import get_default_exception_handler_config import logging import json -def execute_function(func: Callable, **kwargs) -> Any: - """ - Execute a function with proper async handling. - - This is a pure function that handles both async and non-async function execution - with proper event loop management for async functions. - - Args: - func: The function to execute - **kwargs: Arguments to pass to the function - - Returns: - The result of the function execution - """ - is_async = asyncio.iscoroutinefunction(func) - if is_async: - # Handle async functions with proper event loop management - try: - loop = asyncio.get_event_loop() - if loop.is_running(): - # Event loop is already running, create a task and wait for it - task = loop.create_task(func(**kwargs)) - # Use asyncio.wait to avoid run_until_complete on running loop - import concurrent.futures - - with concurrent.futures.ThreadPoolExecutor() as executor: - future = executor.submit(asyncio.run, func(**kwargs)) - results = future.result() - elif not loop.is_closed(): - # Use existing loop that's not running - task = loop.create_task(func(**kwargs)) - results = loop.run_until_complete(task) - else: - # Loop is closed, create a new one - results = asyncio.run(func(**kwargs)) - except RuntimeError: - # No event loop or other issues, create a new one - results = asyncio.run(func(**kwargs)) - else: - results = func(**kwargs) - return results - - AggregationMethod = Literal["mean", "max", "min"] -def aggregate(scores: List[float], method: AggregationMethod) -> float: +def aggregate(scores: list[float], method: AggregationMethod) -> float: if not scores: return 0.0 if method == "mean": @@ -76,45 +36,12 @@ def aggregate(scores: List[float], method: AggregationMethod) -> float: return max(scores) if method == "min": return min(scores) - raise ValueError(f"Unknown aggregation method: {method}") - - -def create_dynamically_parameterized_wrapper(test_func, wrapper_body, test_param_names): - """ - Creates a wrapper function with dynamic parameters for pytest parameterization. - - This function takes a test function and creates a wrapper that: - 1. Preserves the original function's metadata using functools.wraps - 2. Creates a new function signature with the specified parameter names that maps to pytest.mark.parametrize decorator - 3. Returns a callable that can be used with pytest.mark.parametrize - - The function signature is dynamically created to match the parameter names expected by - pytest.mark.parametrize, ensuring that pytest can properly map the test parameters - to the function arguments. - - Args: - test_func: The original test function to wrap - wrapper_body: The function body that contains the actual test logic - test_param_names: List of parameter names for the dynamic signature - - Returns: - A wrapper function with the specified parameter signature that calls wrapper_body - """ - from functools import wraps - - @wraps(test_func) - async def wrapper(**kwargs): - return await wrapper_body(**kwargs) - - parameters = [inspect.Parameter(name, inspect.Parameter.POSITIONAL_OR_KEYWORD) for name in test_param_names] - wrapper.__signature__ = inspect.Signature(parameters) - - return wrapper + raise ValueError(f"Unknown aggregation method: {method}") # pyright: ignore[reportUnreachable] def log_eval_status_and_rows( - eval_metadata: Optional[EvalMetadata], - rows: Optional[List[EvaluationRow]] | None, + eval_metadata: EvalMetadata | None, + rows: list[EvaluationRow] | None, status: Status, passed: bool, logger: DatasetLogger, @@ -130,7 +57,7 @@ def log_eval_status_and_rows( eval_metadata.status = status eval_metadata.passed = passed - rows_to_log: List[EvaluationRow] = rows or [] + rows_to_log: list[EvaluationRow] = rows or [] if not rows_to_log: error_row = EvaluationRow(messages=[], eval_metadata=eval_metadata, evaluation_result=None) logger.log(error_row) @@ -172,8 +99,8 @@ def parse_ep_max_concurrent_rollouts(default_value: int) -> int: def parse_ep_completion_params( - completion_params: list[CompletionParams | None] | None, -) -> list[CompletionParams | None]: + completion_params: Sequence[CompletionParams | None] | None, +) -> Sequence[CompletionParams | None]: """Apply EP_INPUT_PARAMS_JSON overrides to completion_params. Reads the environment variable set by plugin.py and applies deep merge to each completion param. @@ -186,7 +113,7 @@ def parse_ep_completion_params( override_obj = json.loads(_env_override) # pyright: ignore[reportAny] if isinstance(override_obj, dict): # Apply override to each completion_params item - return [deep_update_dict(dict(cp), override_obj) for cp in completion_params if cp is not None] + return [deep_update_dict(dict(cp), override_obj) for cp in completion_params if cp is not None] # pyright: ignore[reportUnknownArgumentType] except Exception: pass return completion_params @@ -216,114 +143,19 @@ def parse_ep_passed_threshold( return None -def deep_update_dict(base: dict, override: dict) -> dict: +def deep_update_dict(base: dict[str, Any], override: dict[str, Any]) -> dict[str, Any]: # pyright: ignore[reportExplicitAny] """Recursively update nested dictionaries in-place and return base.""" - for key, value in override.items(): + for key, value in override.items(): # pyright: ignore[reportAny] if isinstance(value, dict) and isinstance(base.get(key), dict): - deep_update_dict(base[key], value) + deep_update_dict(base[key], value) # pyright: ignore[reportAny, reportUnknownArgumentType] else: base[key] = value return base -CombinationTuple = tuple[ - list[DatasetPathParam] | None, - CompletionParams | None, - InputMessagesParam | None, - list[EvaluationRow] | None, - EvaluationInputParam | None, -] - - -def generate_parameter_combinations( - input_dataset: list[DatasetPathParam] | None, - completion_params: list[CompletionParams | None], - input_messages: list[InputMessagesParam | None] | None, - input_rows: list[EvaluationRow] | None, - evaluation_test_kwargs: list[EvaluationInputParam | None] | None, - max_dataset_rows: int | None, - combine_datasets: bool, -) -> list[CombinationTuple]: - """ - Generate all combinations of parameters for pytest parameterization. - - Args: - input_dataset: Dataset paths to use - completion_params: Completion parameters to test - input_messages: Input messages to use - input_rows: Pre-constructed EvaluationRow objects to use - evaluation_test_kwargs: Additional kwargs for evaluation tests - max_dataset_rows: Maximum number of dataset rows to process - combine_datasets: Whether to combine multiple datasets into one test - - Returns: - List of parameter tuples for pytest.mark.parametrize - """ - # Handle optional parameters with defaults - # Optionally combine multiple dataset paths into one logical dataset, - # or parameterize to run one dataset per test invocation. - datasets: list[list[DatasetPathParam] | None] = [] - if input_dataset is not None: - if combine_datasets: - datasets = [input_dataset] - else: - # Fan out: one dataset path per parameterization - if input_dataset: - datasets = [[p] for p in input_dataset] - else: - datasets = [None] - - cps: list[CompletionParams | None] = completion_params - - # Apply EP_MAX_DATASET_ROWS to input_messages, but do NOT parameterize over - # each row. Instead, pass the entire sliced list through in a single test run - # so summaries aggregate all rows together (AIME-style behavior). - messages: list[InputMessagesParam | None] = [None] - if input_messages is not None: - effective_max_rows = parse_ep_max_rows(max_dataset_rows) - if effective_max_rows is not None: - sliced_messages: list[InputMessagesParam | None] = input_messages[:effective_max_rows] - else: - sliced_messages = input_messages - # Wrap as a single parameter payload - messages = sliced_messages - - rows: list[list[EvaluationRow] | None] = [None] - # Handle input_rows - similar to input_messages, apply max_dataset_rows if specified - if input_rows is not None: - effective_max_rows = parse_ep_max_rows(max_dataset_rows) - if effective_max_rows is not None: - sliced_rows = input_rows[:effective_max_rows] - else: - sliced_rows = input_rows - # Wrap as a single parameter payload - rows = [sliced_rows] - - kwargs: list[EvaluationInputParam | None] = ( - evaluation_test_kwargs if evaluation_test_kwargs is not None else [None] - ) - - combinations: list[CombinationTuple] = [] - - # Generate all combinations - for ds in datasets: - for cp in cps: - for im in messages: - for ir in rows: - for etk in kwargs: - # if no dataset, no messages, and no rows, raise an error - if ds is None and im is None and ir is None: - raise ValueError( - "No dataset, messages, or rows provided. Please provide at least one of input_dataset, input_messages, or input_rows." - ) - combinations.append((ds, cp, im, ir, etk)) - - return combinations - - async def rollout_processor_with_retry( rollout_processor: RolloutProcessor, - fresh_dataset: List[EvaluationRow], + fresh_dataset: list[EvaluationRow], config: RolloutProcessorConfig, ): """ @@ -354,21 +186,21 @@ async def rollout_processor_with_retry( raise e # Create a single backoff-decorated retry function that can be reused - @exception_config.get_backoff_decorator() + @exception_config.get_backoff_decorator() # pyright: ignore[reportUntypedFunctionDecorator] async def execute_row_with_backoff_retry(row: EvaluationRow): """Execute rollout for a single row with backoff retry.""" retry_config = replace(config, kwargs={**(config.kwargs or {}), "start_server": False}) retry_tasks = rollout_processor([row], retry_config) return await retry_tasks[0] - async def execute_row_with_backoff(task: asyncio.Task, row: EvaluationRow) -> EvaluationRow: + async def execute_row_with_backoff(task: asyncio.Task, row: EvaluationRow) -> EvaluationRow: # pyright: ignore[reportMissingTypeArgument, reportUnknownParameterType] """Execute a single row task with backoff retry.""" try: # Try original task first - result = await task + result = await task # pyright: ignore[reportUnknownVariableType] result.rollout_status = Status.rollout_finished() - return result + return result # pyright: ignore[reportUnknownVariableType] except Exception as e: # NOTE: we perform these checks because we don't put the backoff decorator on initial batch call. we don't want to retry whole batch if anything fails. # Check if this exception should be retried @@ -395,7 +227,7 @@ async def execute_row_with_backoff(task: asyncio.Task, row: EvaluationRow) -> Ev row.rollout_status = Status.rollout_error(repr(e)) return row - async def execute_row_with_backoff_and_log(task: asyncio.Task, row: EvaluationRow) -> EvaluationRow: + async def execute_row_with_backoff_and_log(task: asyncio.Task, row: EvaluationRow) -> EvaluationRow: # pyright: ignore[reportMissingTypeArgument, reportUnknownParameterType] """Execute a single row task with backoff retry and logging.""" result = await execute_row_with_backoff(task, row) # Log the row after execution completes (success or failure) @@ -423,7 +255,7 @@ def sanitize_filename(text: str) -> str: return safe[:120] -def extract_effort_tag(params: dict) -> Optional[str]: +def extract_effort_tag(params: dict) -> str | None: # pyright: ignore[reportMissingTypeArgument, reportUnknownParameterType] """ Extract effort tag from completion parameters for use in file naming. @@ -434,17 +266,17 @@ def extract_effort_tag(params: dict) -> Optional[str]: Effort tag string if found, None otherwise """ try: - if not isinstance(params, dict): - return None + if not isinstance(params, dict): # pyright: ignore[reportUnnecessaryIsInstance] + return None # pyright: ignore[reportUnreachable] # Common locations if "extra_body" in params and isinstance(params["extra_body"], dict): - eb = params["extra_body"] - if isinstance(eb.get("reasoning"), dict) and "effort" in eb["reasoning"]: - return str(eb["reasoning"]["effort"]).lower() + eb = params["extra_body"] # pyright: ignore[reportUnknownVariableType] + if isinstance(eb.get("reasoning"), dict) and "effort" in eb["reasoning"]: # pyright: ignore[reportUnknownMemberType] + return str(eb["reasoning"]["effort"]).lower() # pyright: ignore[reportUnknownArgumentType] if "reasoning_effort" in eb: - return str(eb["reasoning_effort"]).lower() + return str(eb["reasoning_effort"]).lower() # pyright: ignore[reportUnknownArgumentType] if "reasoning" in params and isinstance(params["reasoning"], dict) and "effort" in params["reasoning"]: - return str(params["reasoning"]["effort"]).lower() + return str(params["reasoning"]["effort"]).lower() # pyright: ignore[reportUnknownArgumentType] except Exception: return None return None diff --git a/eval_protocol/pytest/validate_signature.py b/eval_protocol/pytest/validate_signature.py index 02e2e708..85e15909 100644 --- a/eval_protocol/pytest/validate_signature.py +++ b/eval_protocol/pytest/validate_signature.py @@ -1,3 +1,4 @@ +from collections.abc import Sequence from inspect import Signature from eval_protocol.models import CompletionParams, EvaluationRow @@ -5,7 +6,7 @@ def validate_signature( - signature: Signature, mode: EvaluationTestMode, completion_params: list[CompletionParams | None] | None + signature: Signature, mode: EvaluationTestMode, completion_params: Sequence[CompletionParams | None] | None ) -> None: # For pointwise/groupwise mode, we expect a different signature # we expect single row to be passed in as the original row diff --git a/tests/chinook/test_pydantic_chinook.py b/tests/chinook/test_pydantic_chinook.py index 9d4c128c..87c54a29 100644 --- a/tests/chinook/test_pydantic_chinook.py +++ b/tests/chinook/test_pydantic_chinook.py @@ -6,7 +6,7 @@ from eval_protocol.pytest import evaluation_test from eval_protocol.pytest.default_pydantic_ai_rollout_processor import PydanticAgentRolloutProcessor -from agent import setup_agent +from tests.chinook.agent import setup_agent from pydantic_ai.models.openai import OpenAIModel from tests.chinook.dataset import collect_dataset @@ -21,7 +21,7 @@ @pytest.mark.asyncio @evaluation_test( - input_messages=[Message(role="user", content="What is the total number of tracks in the database?")], + input_messages=[[Message(role="user", content="What is the total number of tracks in the database?")]], completion_params=[ { "model": { @@ -85,7 +85,7 @@ class Response(BaseModel): @pytest.mark.skip(reason="takes too long to run") @pytest.mark.asyncio @evaluation_test( - input_rows=collect_dataset(), + input_rows=[collect_dataset()], completion_params=[ { "model": { @@ -134,10 +134,10 @@ class Response(BaseModel): reason: str comparison_agent = Agent( + model=model, system_prompt=LLM_JUDGE_PROMPT, output_type=Response, - model=model, - result_retries=5, + output_retries=5, ) result = await comparison_agent.run( f"Expected answer: {row.ground_truth}\nResponse: {last_assistant_message.content}" diff --git a/tests/pytest/test_pytest_input_rows.py b/tests/pytest/test_pytest_input_rows.py index e382ee9e..79689783 100644 --- a/tests/pytest/test_pytest_input_rows.py +++ b/tests/pytest/test_pytest_input_rows.py @@ -4,7 +4,7 @@ @evaluation_test( - input_rows=[EvaluationRow(messages=[Message(role="user", content="What is the capital of France?")])], + input_rows=[[EvaluationRow(messages=[Message(role="user", content="What is the capital of France?")])]], completion_params=[{"model": "no-op"}], rollout_processor=NoOpRolloutProcessor(), mode="pointwise", From badc4d94c49a44848d32bbd1e197b50c5eaab7e8 Mon Sep 17 00:00:00 2001 From: Dylan Huang Date: Thu, 28 Aug 2025 21:45:01 -0700 Subject: [PATCH 09/18] fix input_messages usage --- tests/pytest/test_pydantic_multi_agent.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/pytest/test_pydantic_multi_agent.py b/tests/pytest/test_pydantic_multi_agent.py index 56338a63..05cdddd9 100644 --- a/tests/pytest/test_pydantic_multi_agent.py +++ b/tests/pytest/test_pydantic_multi_agent.py @@ -35,7 +35,7 @@ def setup_agent(joke_generation_model: Model, joke_selection_model: Model) -> Ag joke_generation_agent = Agent(joke_generation_model, output_type=list[str]) @joke_selection_agent.tool - async def joke_factory(ctx: RunContext[None], count: int) -> list[str]: + async def joke_factory(ctx: RunContext[None], count: int) -> list[str]: # pyright: ignore[reportUnusedFunction] r = await joke_generation_agent.run( f"Please generate {count} jokes.", usage=ctx.usage, @@ -47,7 +47,7 @@ async def joke_factory(ctx: RunContext[None], count: int) -> list[str]: @pytest.mark.asyncio @evaluation_test( - input_messages=[Message(role="user", content="Tell me a joke.")], + input_messages=[[Message(role="user", content="Tell me a joke.")]], completion_params=[ { "model": { From eae0959911d31358fced7e09ac5e498149cc86cd Mon Sep 17 00:00:00 2001 From: Dylan Huang Date: Thu, 28 Aug 2025 22:06:02 -0700 Subject: [PATCH 10/18] test_pydantic_multi_agent runs --- .gitignore | 2 ++ eval_protocol/pytest/parameterize.py | 3 +- eval_protocol/pytest/validate_signature.py | 32 ++++++++++++++++++---- tests/pytest/test_get_metadata.py | 13 ++++----- tests/pytest/test_pytest_async.py | 10 ++----- 5 files changed, 38 insertions(+), 22 deletions(-) diff --git a/.gitignore b/.gitignore index 9e8d9637..42d2b831 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +experiment_results/ + # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] diff --git a/eval_protocol/pytest/parameterize.py b/eval_protocol/pytest/parameterize.py index f4a91c30..5815abd4 100644 --- a/eval_protocol/pytest/parameterize.py +++ b/eval_protocol/pytest/parameterize.py @@ -44,7 +44,6 @@ def pytest_parametrize( argnames.append("evaluation_test_kwargs") argvalues: list[ParameterSet | Sequence[object] | object] = [] - param_tuples: list[tuple[object, ...]] = [] for combo in combinations: dataset, cp, messages, rows, etk = combo param_tuple: list[object] = [] @@ -63,7 +62,7 @@ def pytest_parametrize( raise ValueError( f"The length of argnames ({len(argnames)}) is not the same as the length of param_tuple ({len(param_tuple)})" ) - param_tuples.append(tuple(param_tuple)) + argvalues.append(tuple(param_tuple)) return PytestParametrizeArgs(argnames=argnames, argvalues=argvalues) diff --git a/eval_protocol/pytest/validate_signature.py b/eval_protocol/pytest/validate_signature.py index 85e15909..500de649 100644 --- a/eval_protocol/pytest/validate_signature.py +++ b/eval_protocol/pytest/validate_signature.py @@ -1,10 +1,26 @@ from collections.abc import Sequence from inspect import Signature +from typing import get_origin, get_args from eval_protocol.models import CompletionParams, EvaluationRow from eval_protocol.pytest.types import EvaluationTestMode +def _is_list_of_evaluation_row(annotation) -> bool: # pyright: ignore[reportUnknownParameterType, reportMissingParameterType] + """Check if annotation is list[EvaluationRow] or equivalent.""" + origin = get_origin(annotation) # pyright: ignore[reportUnknownArgumentType, reportAny] + if origin is not list: + return False + + args = get_args(annotation) + if len(args) != 1: + return False + + # Check if the single argument is EvaluationRow or equivalent + arg = args[0] # pyright: ignore[reportAny] + return arg is EvaluationRow or str(arg) == str(EvaluationRow) # pyright: ignore[reportAny] + + def validate_signature( signature: Signature, mode: EvaluationTestMode, completion_params: Sequence[CompletionParams | None] | None ) -> None: @@ -29,11 +45,13 @@ def validate_signature( raise ValueError("In groupwise mode, your eval function must have a parameter named 'rows'") # validate that "Rows" is of type List[EvaluationRow] - if signature.parameters["rows"].annotation is not list[EvaluationRow]: # pyright: ignore[reportAny] - raise ValueError("In groupwise mode, the 'rows' parameter must be of type List[EvaluationRow") + if not _is_list_of_evaluation_row(signature.parameters["rows"].annotation): # pyright: ignore[reportAny] + raise ValueError( + f"In groupwise mode, the 'rows' parameter must be of type List[EvaluationRow]. Got {str(signature.parameters['rows'].annotation)} instead" # pyright: ignore[reportAny] + ) # validate that the function has a return type of List[EvaluationRow] - if signature.return_annotation is not list[EvaluationRow]: # pyright: ignore[reportAny] + if not _is_list_of_evaluation_row(signature.return_annotation): # pyright: ignore[reportAny] raise ValueError("In groupwise mode, your eval function must return a list of EvaluationRow instances") if completion_params is not None and len(completion_params) < 2: raise ValueError("In groupwise mode, you must provide at least 2 completion parameters") @@ -43,9 +61,11 @@ def validate_signature( raise ValueError("In all mode, your eval function must have a parameter named 'rows'") # validate that "Rows" is of type List[EvaluationRow] - if signature.parameters["rows"].annotation is not list[EvaluationRow]: # pyright: ignore[reportAny] - raise ValueError("In all mode, the 'rows' parameter must be of type List[EvaluationRow") + if not _is_list_of_evaluation_row(signature.parameters["rows"].annotation): # pyright: ignore[reportAny] + raise ValueError( + f"In all mode, the 'rows' parameter must be of type list[EvaluationRow]. Got {str(signature.parameters['rows'].annotation)} instead" # pyright: ignore[reportAny] + ) # validate that the function has a return type of List[EvaluationRow] - if signature.return_annotation is not list[EvaluationRow]: # pyright: ignore[reportAny] + if not _is_list_of_evaluation_row(signature.return_annotation): # pyright: ignore[reportAny] raise ValueError("In all mode, your eval function must return a list of EvaluationRow instances") diff --git a/tests/pytest/test_get_metadata.py b/tests/pytest/test_get_metadata.py index 3917fb3b..e27064b2 100644 --- a/tests/pytest/test_get_metadata.py +++ b/tests/pytest/test_get_metadata.py @@ -1,5 +1,4 @@ import asyncio -from typing import Dict, List from eval_protocol.pytest import evaluation_test from eval_protocol.models import EvaluationRow, Message @@ -19,16 +18,16 @@ max_concurrent_rollouts=5, max_concurrent_evaluations=10, ) -def test_pytest_async(rows: List[EvaluationRow]) -> List[EvaluationRow]: +def test_pytest_async(rows: list[EvaluationRow]) -> list[EvaluationRow]: """Run math evaluation on sample dataset using pytest interface.""" return rows def test_pytest_func_metainfo(): assert hasattr(test_pytest_async, "_origin_func") - origin_func = test_pytest_async._origin_func - assert not asyncio.iscoroutinefunction(origin_func) + origin_func = test_pytest_async._origin_func # pyright: ignore[reportAny, reportFunctionMemberAccess] + assert not asyncio.iscoroutinefunction(origin_func) # pyright: ignore[reportAny] assert asyncio.iscoroutinefunction(test_pytest_async) - assert test_pytest_async._metainfo["mode"] == "groupwise" - assert test_pytest_async._metainfo["max_rollout_concurrency"] == 5 - assert test_pytest_async._metainfo["max_evaluation_concurrency"] == 10 + assert test_pytest_async._metainfo["mode"] == "groupwise" # pyright: ignore[reportAny, reportFunctionMemberAccess] + assert test_pytest_async._metainfo["max_rollout_concurrency"] == 5 # pyright: ignore[reportAny, reportFunctionMemberAccess] + assert test_pytest_async._metainfo["max_evaluation_concurrency"] == 10 # pyright: ignore[reportAny, reportFunctionMemberAccess] diff --git a/tests/pytest/test_pytest_async.py b/tests/pytest/test_pytest_async.py index 1acfe48d..6e42f186 100644 --- a/tests/pytest/test_pytest_async.py +++ b/tests/pytest/test_pytest_async.py @@ -1,11 +1,7 @@ -import asyncio -from typing import List - import pytest from eval_protocol.models import EvaluationRow, Message from eval_protocol.pytest import evaluation_test -from examples.math_example.main import evaluate as math_evaluate @evaluation_test( @@ -20,7 +16,7 @@ completion_params=[{"model": "accounts/fireworks/models/kimi-k2-instruct"}], mode="all", ) -async def test_pytest_async(rows: List[EvaluationRow]) -> List[EvaluationRow]: +async def test_pytest_async(rows: list[EvaluationRow]) -> list[EvaluationRow]: """Run math evaluation on sample dataset using pytest interface.""" return rows @@ -51,7 +47,7 @@ async def test_pytest_async_main(): ], ) ] - result = await test_pytest_async(rows) + result = await test_pytest_async(rows) # pyright: ignore[reportGeneralTypeIssues, reportUnknownVariableType, reportArgumentType, reportCallIssue] assert result == rows @@ -65,5 +61,5 @@ async def test_pytest_async_pointwise_main(): Message(role="user", content="What is the capital of France?"), ], ) - result = await test_pytest_async_pointwise(row) + result = await test_pytest_async_pointwise(row) # pyright: ignore[reportGeneralTypeIssues, reportArgumentType, reportUnknownVariableType, reportCallIssue] assert result == row From 0800c2249a660566de6ab735226af5aa9ef4a977 Mon Sep 17 00:00:00 2001 From: Dylan Huang Date: Thu, 28 Aug 2025 22:13:06 -0700 Subject: [PATCH 11/18] remove debugger --- vite-app/src/components/EvaluationRow.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/vite-app/src/components/EvaluationRow.tsx b/vite-app/src/components/EvaluationRow.tsx index 581c6fab..fb3f2161 100644 --- a/vite-app/src/components/EvaluationRow.tsx +++ b/vite-app/src/components/EvaluationRow.tsx @@ -164,7 +164,6 @@ const RowStatus = observer( const ExperimentId = observer( ({ experimentId: experimentId }: { experimentId?: string }) => { - debugger; if (!experimentId) { return null; } From 099bd48ea962f0ad515f33206f101a4a017cdf24 Mon Sep 17 00:00:00 2001 From: Dylan Huang Date: Thu, 28 Aug 2025 22:13:24 -0700 Subject: [PATCH 12/18] vite build --- vite-app/dist/assets/{index-CWShMUgl.js => index-CMzLJz8S.js} | 4 ++-- .../assets/{index-CWShMUgl.js.map => index-CMzLJz8S.js.map} | 2 +- vite-app/dist/index.html | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) rename vite-app/dist/assets/{index-CWShMUgl.js => index-CMzLJz8S.js} (99%) rename vite-app/dist/assets/{index-CWShMUgl.js.map => index-CMzLJz8S.js.map} (54%) diff --git a/vite-app/dist/assets/index-CWShMUgl.js b/vite-app/dist/assets/index-CMzLJz8S.js similarity index 99% rename from vite-app/dist/assets/index-CWShMUgl.js rename to vite-app/dist/assets/index-CMzLJz8S.js index 9a72ed07..a46b423b 100644 --- a/vite-app/dist/assets/index-CWShMUgl.js +++ b/vite-app/dist/assets/index-CMzLJz8S.js @@ -89,7 +89,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho } else { newResult[${H}] = ${E}.value; } - `)}m.write("payload.value = newResult;"),m.write("return payload;");const C=m.compile();return(U,E)=>C(p,U,E)};let i;const s=ph,o=!PU.jitless,u=o&&ML.value,h=t.catchall;let d;e._zod.parse=(p,m)=>{d??(d=A.value);const v=p.value;if(!s(v))return p.issues.push({expected:"object",code:"invalid_type",input:v,inst:e}),p;const w=[];if(o&&u&&m?.async===!1&&m.jitless!==!0)i||(i=n(t.shape)),p=i(p,m);else{p.value={};const E=d.shape;for(const H of d.keys){const D=E[H]._zod.run({value:v[H],issues:[]},m);D instanceof Promise?w.push(D.then(R=>Zu(R,p,H,v))):Zu(D,p,H,v)}}if(!h)return w.length?Promise.all(w).then(()=>p):p;const b=[],_=d.keySet,C=h._zod,U=C.def.type;for(const E of Object.keys(v)){if(_.has(E))continue;if(U==="never"){b.push(E);continue}const H=C.run({value:v[E],issues:[]},m);H instanceof Promise?w.push(H.then(F=>Zu(F,p,E,v))):Zu(H,p,E,v)}return b.length&&p.issues.push({code:"unrecognized_keys",keys:b,input:v,inst:e}),w.length?Promise.all(w).then(()=>p):p}});function CC(e,t,A,n){for(const s of e)if(s.issues.length===0)return t.value=s.value,t;const i=e.filter(s=>!zl(s));return i.length===1?(t.value=i[0].value,i[0]):(t.issues.push({code:"invalid_union",input:t.value,inst:A,errors:e.map(s=>s.issues.map(o=>Gr(o,n,jr())))}),t)}const rE=Z("$ZodUnion",(e,t)=>{le.init(e,t),re(e._zod,"optin",()=>t.options.some(i=>i._zod.optin==="optional")?"optional":void 0),re(e._zod,"optout",()=>t.options.some(i=>i._zod.optout==="optional")?"optional":void 0),re(e._zod,"values",()=>{if(t.options.every(i=>i._zod.values))return new Set(t.options.flatMap(i=>Array.from(i._zod.values)))}),re(e._zod,"pattern",()=>{if(t.options.every(i=>i._zod.pattern)){const i=t.options.map(s=>s._zod.pattern);return new RegExp(`^(${i.map(s=>iv(s.source)).join("|")})$`)}});const A=t.options.length===1,n=t.options[0]._zod.run;e._zod.parse=(i,s)=>{if(A)return n(i,s);let o=!1;const c=[];for(const u of t.options){const h=u._zod.run({value:i.value,issues:[]},s);if(h instanceof Promise)c.push(h),o=!0;else{if(h.issues.length===0)return h;c.push(h)}}return o?Promise.all(c).then(u=>CC(u,i,e,s)):CC(c,i,e,s)}}),BR=Z("$ZodDiscriminatedUnion",(e,t)=>{rE.init(e,t);const A=e._zod.parse;re(e._zod,"propValues",()=>{const i={};for(const s of t.options){const o=s._zod.propValues;if(!o||Object.keys(o).length===0)throw new Error(`Invalid discriminated union option at index "${t.options.indexOf(s)}"`);for(const[c,u]of Object.entries(o)){i[c]||(i[c]=new Set);for(const h of u)i[c].add(h)}}return i});const n=Av(()=>{const i=t.options,s=new Map;for(const o of i){const c=o._zod.propValues?.[t.discriminator];if(!c||c.size===0)throw new Error(`Invalid discriminated union option at index "${t.options.indexOf(o)}"`);for(const u of c){if(s.has(u))throw new Error(`Duplicate discriminator value "${String(u)}"`);s.set(u,o)}}return s});e._zod.parse=(i,s)=>{const o=i.value;if(!ph(o))return i.issues.push({code:"invalid_type",expected:"object",input:o,inst:e}),i;const c=n.value.get(o?.[t.discriminator]);return c?c._zod.run(i,s):t.unionFallback?A(i,s):(i.issues.push({code:"invalid_union",errors:[],note:"No matching discriminator",discriminator:t.discriminator,input:o,path:[t.discriminator],inst:e}),i)}}),mR=Z("$ZodIntersection",(e,t)=>{le.init(e,t),e._zod.parse=(A,n)=>{const i=A.value,s=t.left._zod.run({value:i,issues:[]},n),o=t.right._zod.run({value:i,issues:[]},n);return s instanceof Promise||o instanceof Promise?Promise.all([s,o]).then(([u,h])=>_C(A,u,h)):_C(A,s,o)}});function JB(e,t){if(e===t)return{valid:!0,data:e};if(e instanceof Date&&t instanceof Date&&+e==+t)return{valid:!0,data:e};if(Bh(e)&&Bh(t)){const A=Object.keys(t),n=Object.keys(e).filter(s=>A.indexOf(s)!==-1),i={...e,...t};for(const s of n){const o=JB(e[s],t[s]);if(!o.valid)return{valid:!1,mergeErrorPath:[s,...o.mergeErrorPath]};i[s]=o.data}return{valid:!0,data:i}}if(Array.isArray(e)&&Array.isArray(t)){if(e.length!==t.length)return{valid:!1,mergeErrorPath:[]};const A=[];for(let n=0;n{le.init(e,t),e._zod.parse=(A,n)=>{const i=A.value;if(!Bh(i))return A.issues.push({expected:"record",code:"invalid_type",input:i,inst:e}),A;const s=[];if(t.keyType._zod.values){const o=t.keyType._zod.values;A.value={};for(const u of o)if(typeof u=="string"||typeof u=="number"||typeof u=="symbol"){const h=t.valueType._zod.run({value:i[u],issues:[]},n);h instanceof Promise?s.push(h.then(d=>{d.issues.length&&A.issues.push(...to(u,d.issues)),A.value[u]=d.value})):(h.issues.length&&A.issues.push(...to(u,h.issues)),A.value[u]=h.value)}let c;for(const u in i)o.has(u)||(c=c??[],c.push(u));c&&c.length>0&&A.issues.push({code:"unrecognized_keys",input:i,inst:e,keys:c})}else{A.value={};for(const o of Reflect.ownKeys(i)){if(o==="__proto__")continue;const c=t.keyType._zod.run({value:o,issues:[]},n);if(c instanceof Promise)throw new Error("Async schemas not supported in object keys currently");if(c.issues.length){A.issues.push({code:"invalid_key",origin:"record",issues:c.issues.map(h=>Gr(h,n,jr())),input:o,path:[o],inst:e}),A.value[c.value]=c.value;continue}const u=t.valueType._zod.run({value:i[o],issues:[]},n);u instanceof Promise?s.push(u.then(h=>{h.issues.length&&A.issues.push(...to(o,h.issues)),A.value[c.value]=h.value})):(u.issues.length&&A.issues.push(...to(o,u.issues)),A.value[c.value]=u.value)}}return s.length?Promise.all(s).then(()=>A):A}}),wR=Z("$ZodEnum",(e,t)=>{le.init(e,t);const A=TL(t.entries),n=new Set(A);e._zod.values=n,e._zod.pattern=new RegExp(`^(${A.filter(i=>LL.has(typeof i)).map(i=>typeof i=="string"?lo(i):i.toString()).join("|")})$`),e._zod.parse=(i,s)=>{const o=i.value;return n.has(o)||i.issues.push({code:"invalid_value",values:A,input:o,inst:e}),i}}),bR=Z("$ZodLiteral",(e,t)=>{if(le.init(e,t),t.values.length===0)throw new Error("Cannot create literal schema with no valid values");e._zod.values=new Set(t.values),e._zod.pattern=new RegExp(`^(${t.values.map(A=>typeof A=="string"?lo(A):A?lo(A.toString()):String(A)).join("|")})$`),e._zod.parse=(A,n)=>{const i=A.value;return e._zod.values.has(i)||A.issues.push({code:"invalid_value",values:t.values,input:i,inst:e}),A}}),yR=Z("$ZodTransform",(e,t)=>{le.init(e,t),e._zod.parse=(A,n)=>{const i=t.transform(A.value,A);if(n.async)return(i instanceof Promise?i:Promise.resolve(i)).then(o=>(A.value=o,A));if(i instanceof Promise)throw new ic;return A.value=i,A}});function xC(e,t){return e.issues.length&&t===void 0?{issues:[],value:void 0}:e}const CR=Z("$ZodOptional",(e,t)=>{le.init(e,t),e._zod.optin="optional",e._zod.optout="optional",re(e._zod,"values",()=>t.innerType._zod.values?new Set([...t.innerType._zod.values,void 0]):void 0),re(e._zod,"pattern",()=>{const A=t.innerType._zod.pattern;return A?new RegExp(`^(${iv(A.source)})?$`):void 0}),e._zod.parse=(A,n)=>{if(t.innerType._zod.optin==="optional"){const i=t.innerType._zod.run(A,n);return i instanceof Promise?i.then(s=>xC(s,A.value)):xC(i,A.value)}return A.value===void 0?A:t.innerType._zod.run(A,n)}}),_R=Z("$ZodNullable",(e,t)=>{le.init(e,t),re(e._zod,"optin",()=>t.innerType._zod.optin),re(e._zod,"optout",()=>t.innerType._zod.optout),re(e._zod,"pattern",()=>{const A=t.innerType._zod.pattern;return A?new RegExp(`^(${iv(A.source)}|null)$`):void 0}),re(e._zod,"values",()=>t.innerType._zod.values?new Set([...t.innerType._zod.values,null]):void 0),e._zod.parse=(A,n)=>A.value===null?A:t.innerType._zod.run(A,n)}),xR=Z("$ZodDefault",(e,t)=>{le.init(e,t),e._zod.optin="optional",re(e._zod,"values",()=>t.innerType._zod.values),e._zod.parse=(A,n)=>{if(A.value===void 0)return A.value=t.defaultValue,A;const i=t.innerType._zod.run(A,n);return i instanceof Promise?i.then(s=>QC(s,t)):QC(i,t)}});function QC(e,t){return e.value===void 0&&(e.value=t.defaultValue),e}const QR=Z("$ZodPrefault",(e,t)=>{le.init(e,t),e._zod.optin="optional",re(e._zod,"values",()=>t.innerType._zod.values),e._zod.parse=(A,n)=>(A.value===void 0&&(A.value=t.defaultValue),t.innerType._zod.run(A,n))}),UR=Z("$ZodNonOptional",(e,t)=>{le.init(e,t),re(e._zod,"values",()=>{const A=t.innerType._zod.values;return A?new Set([...A].filter(n=>n!==void 0)):void 0}),e._zod.parse=(A,n)=>{const i=t.innerType._zod.run(A,n);return i instanceof Promise?i.then(s=>UC(s,e)):UC(i,e)}});function UC(e,t){return!e.issues.length&&e.value===void 0&&e.issues.push({code:"invalid_type",expected:"nonoptional",input:e.value,inst:t}),e}const ER=Z("$ZodCatch",(e,t)=>{le.init(e,t),re(e._zod,"optin",()=>t.innerType._zod.optin),re(e._zod,"optout",()=>t.innerType._zod.optout),re(e._zod,"values",()=>t.innerType._zod.values),e._zod.parse=(A,n)=>{const i=t.innerType._zod.run(A,n);return i instanceof Promise?i.then(s=>(A.value=s.value,s.issues.length&&(A.value=t.catchValue({...A,error:{issues:s.issues.map(o=>Gr(o,n,jr()))},input:A.value}),A.issues=[]),A)):(A.value=i.value,i.issues.length&&(A.value=t.catchValue({...A,error:{issues:i.issues.map(s=>Gr(s,n,jr()))},input:A.value}),A.issues=[]),A)}}),FR=Z("$ZodPipe",(e,t)=>{le.init(e,t),re(e._zod,"values",()=>t.in._zod.values),re(e._zod,"optin",()=>t.in._zod.optin),re(e._zod,"optout",()=>t.out._zod.optout),re(e._zod,"propValues",()=>t.in._zod.propValues),e._zod.parse=(A,n)=>{const i=t.in._zod.run(A,n);return i instanceof Promise?i.then(s=>EC(s,t,n)):EC(i,t,n)}});function EC(e,t,A){return e.issues.length?e:t.out._zod.run({value:e.value,issues:e.issues},A)}const SR=Z("$ZodReadonly",(e,t)=>{le.init(e,t),re(e._zod,"propValues",()=>t.innerType._zod.propValues),re(e._zod,"values",()=>t.innerType._zod.values),re(e._zod,"optin",()=>t.innerType._zod.optin),re(e._zod,"optout",()=>t.innerType._zod.optout),e._zod.parse=(A,n)=>{const i=t.innerType._zod.run(A,n);return i instanceof Promise?i.then(FC):FC(i)}});function FC(e){return e.value=Object.freeze(e.value),e}const HR=Z("$ZodCustom",(e,t)=>{NA.init(e,t),le.init(e,t),e._zod.parse=(A,n)=>A,e._zod.check=A=>{const n=A.value,i=t.fn(n);if(i instanceof Promise)return i.then(s=>SC(s,A,n,e));SC(i,A,n,e)}});function SC(e,t,A,n){if(!e){const i={code:"custom",input:A,inst:n,path:[...n._zod.def.path??[]],continue:!n._zod.def.abort};n._zod.def.params&&(i.params=n._zod.def.params),t.issues.push(rc(i))}}class OR{constructor(){this._map=new Map,this._idmap=new Map}add(t,...A){const n=A[0];if(this._map.set(t,n),n&&typeof n=="object"&&"id"in n){if(this._idmap.has(n.id))throw new Error(`ID ${n.id} already exists in the registry`);this._idmap.set(n.id,t)}return this}clear(){return this._map=new Map,this._idmap=new Map,this}remove(t){const A=this._map.get(t);return A&&typeof A=="object"&&"id"in A&&this._idmap.delete(A.id),this._map.delete(t),this}get(t){const A=t._zod.parent;if(A){const n={...this.get(A)??{}};delete n.id;const i={...n,...this._map.get(t)};return Object.keys(i).length?i:void 0}return this._map.get(t)}has(t){return this._map.has(t)}}function TR(){return new OR}const Yu=TR();function DR(e,t){return new e({type:"string",...mt(t)})}function MR(e,t){return new e({type:"string",format:"email",check:"string_format",abort:!1,...mt(t)})}function HC(e,t){return new e({type:"string",format:"guid",check:"string_format",abort:!1,...mt(t)})}function LR(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,...mt(t)})}function RR(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v4",...mt(t)})}function IR(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v6",...mt(t)})}function NR(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v7",...mt(t)})}function kR(e,t){return new e({type:"string",format:"url",check:"string_format",abort:!1,...mt(t)})}function KR(e,t){return new e({type:"string",format:"emoji",check:"string_format",abort:!1,...mt(t)})}function zR(e,t){return new e({type:"string",format:"nanoid",check:"string_format",abort:!1,...mt(t)})}function VR(e,t){return new e({type:"string",format:"cuid",check:"string_format",abort:!1,...mt(t)})}function PR(e,t){return new e({type:"string",format:"cuid2",check:"string_format",abort:!1,...mt(t)})}function jR(e,t){return new e({type:"string",format:"ulid",check:"string_format",abort:!1,...mt(t)})}function GR(e,t){return new e({type:"string",format:"xid",check:"string_format",abort:!1,...mt(t)})}function XR(e,t){return new e({type:"string",format:"ksuid",check:"string_format",abort:!1,...mt(t)})}function ZR(e,t){return new e({type:"string",format:"ipv4",check:"string_format",abort:!1,...mt(t)})}function YR(e,t){return new e({type:"string",format:"ipv6",check:"string_format",abort:!1,...mt(t)})}function WR(e,t){return new e({type:"string",format:"cidrv4",check:"string_format",abort:!1,...mt(t)})}function $R(e,t){return new e({type:"string",format:"cidrv6",check:"string_format",abort:!1,...mt(t)})}function JR(e,t){return new e({type:"string",format:"base64",check:"string_format",abort:!1,...mt(t)})}function qR(e,t){return new e({type:"string",format:"base64url",check:"string_format",abort:!1,...mt(t)})}function t2(e,t){return new e({type:"string",format:"e164",check:"string_format",abort:!1,...mt(t)})}function e2(e,t){return new e({type:"string",format:"jwt",check:"string_format",abort:!1,...mt(t)})}function A2(e,t){return new e({type:"string",format:"datetime",check:"string_format",offset:!1,local:!1,precision:null,...mt(t)})}function n2(e,t){return new e({type:"string",format:"date",check:"string_format",...mt(t)})}function i2(e,t){return new e({type:"string",format:"time",check:"string_format",precision:null,...mt(t)})}function r2(e,t){return new e({type:"string",format:"duration",check:"string_format",...mt(t)})}function s2(e,t){return new e({type:"number",checks:[],...mt(t)})}function a2(e,t){return new e({type:"number",check:"number_format",abort:!1,format:"safeint",...mt(t)})}function o2(e,t){return new e({type:"boolean",...mt(t)})}function l2(e){return new e({type:"any"})}function c2(e){return new e({type:"unknown"})}function u2(e,t){return new e({type:"never",...mt(t)})}function f2(e,t){return new e({type:"date",...mt(t)})}function OC(e,t){return new eE({check:"less_than",...mt(t),value:e,inclusive:!1})}function Zf(e,t){return new eE({check:"less_than",...mt(t),value:e,inclusive:!0})}function TC(e,t){return new AE({check:"greater_than",...mt(t),value:e,inclusive:!1})}function Yf(e,t){return new AE({check:"greater_than",...mt(t),value:e,inclusive:!0})}function DC(e,t){return new _4({check:"multiple_of",...mt(t),value:e})}function sE(e,t){return new Q4({check:"max_length",...mt(t),maximum:e})}function mh(e,t){return new U4({check:"min_length",...mt(t),minimum:e})}function aE(e,t){return new E4({check:"length_equals",...mt(t),length:e})}function h2(e,t){return new F4({check:"string_format",format:"regex",...mt(t),pattern:e})}function d2(e){return new S4({check:"string_format",format:"lowercase",...mt(e)})}function g2(e){return new H4({check:"string_format",format:"uppercase",...mt(e)})}function p2(e,t){return new O4({check:"string_format",format:"includes",...mt(t),includes:e})}function B2(e,t){return new T4({check:"string_format",format:"starts_with",...mt(t),prefix:e})}function m2(e,t){return new D4({check:"string_format",format:"ends_with",...mt(t),suffix:e})}function Uc(e){return new M4({check:"overwrite",tx:e})}function v2(e){return Uc(t=>t.normalize(e))}function w2(){return Uc(e=>e.trim())}function b2(){return Uc(e=>e.toLowerCase())}function y2(){return Uc(e=>e.toUpperCase())}function C2(e,t,A){return new e({type:"array",element:t,...mt(A)})}function _2(e,t,A){return new e({type:"custom",check:"custom",fn:t,...mt(A)})}function x2(e){const t=Q2(A=>(A.addIssue=n=>{if(typeof n=="string")A.issues.push(rc(n,A.value,t._zod.def));else{const i=n;i.fatal&&(i.continue=!1),i.code??(i.code="custom"),i.input??(i.input=A.value),i.inst??(i.inst=t),i.continue??(i.continue=!t._zod.def.abort),A.issues.push(rc(i))}},e(A.value,A)));return t}function Q2(e,t){const A=new NA({check:"custom",...mt(t)});return A._zod.check=e,A}const U2=Z("ZodISODateTime",(e,t)=>{Y4.init(e,t),Ce.init(e,t)});function E2(e){return A2(U2,e)}const F2=Z("ZodISODate",(e,t)=>{W4.init(e,t),Ce.init(e,t)});function S2(e){return n2(F2,e)}const H2=Z("ZodISOTime",(e,t)=>{$4.init(e,t),Ce.init(e,t)});function O2(e){return i2(H2,e)}const T2=Z("ZodISODuration",(e,t)=>{J4.init(e,t),Ce.init(e,t)});function D2(e){return r2(T2,e)}const M2=(e,t)=>{XU.init(e,t),e.name="ZodError",Object.defineProperties(e,{format:{value:A=>GL(e,A)},flatten:{value:A=>jL(e,A)},addIssue:{value:A=>{e.issues.push(A),e.message=JSON.stringify(e.issues,$B,2)}},addIssues:{value:A=>{e.issues.push(...A),e.message=JSON.stringify(e.issues,$B,2)}},isEmpty:{get(){return e.issues.length===0}}})},nd=Z("ZodError",M2,{Parent:Error}),L2=XL(nd),R2=ZL(nd),I2=YU(nd),N2=WU(nd),we=Z("ZodType",(e,t)=>(le.init(e,t),e.def=t,Object.defineProperty(e,"_def",{value:t}),e.check=(...A)=>e.clone({...t,checks:[...t.checks??[],...A.map(n=>typeof n=="function"?{_zod:{check:n,def:{check:"custom"},onattach:[]}}:n)]}),e.clone=(A,n)=>qs(e,A,n),e.brand=()=>e,e.register=(A,n)=>(A.add(e,n),e),e.parse=(A,n)=>L2(e,A,n,{callee:e.parse}),e.safeParse=(A,n)=>I2(e,A,n),e.parseAsync=async(A,n)=>R2(e,A,n,{callee:e.parseAsync}),e.safeParseAsync=async(A,n)=>N2(e,A,n),e.spa=e.safeParseAsync,e.refine=(A,n)=>e.check(TI(A,n)),e.superRefine=A=>e.check(DI(A)),e.overwrite=A=>e.check(Uc(A)),e.optional=()=>IC(e),e.nullable=()=>NC(e),e.nullish=()=>IC(NC(e)),e.nonoptional=A=>QI(e,A),e.array=()=>IA(e),e.or=A=>rd([e,A]),e.and=A=>BI(e,A),e.transform=A=>tm(e,uE(A)),e.default=A=>CI(e,A),e.prefault=A=>xI(e,A),e.catch=A=>EI(e,A),e.pipe=A=>tm(e,A),e.readonly=()=>HI(e),e.describe=A=>{const n=e.clone();return Yu.add(n,{description:A}),n},Object.defineProperty(e,"description",{get(){return Yu.get(e)?.description},configurable:!0}),e.meta=(...A)=>{if(A.length===0)return Yu.get(e);const n=e.clone();return Yu.add(n,A[0]),n},e.isOptional=()=>e.safeParse(void 0).success,e.isNullable=()=>e.safeParse(null).success,e)),oE=Z("_ZodString",(e,t)=>{sv.init(e,t),we.init(e,t);const A=e._zod.bag;e.format=A.format??null,e.minLength=A.minimum??null,e.maxLength=A.maximum??null,e.regex=(...n)=>e.check(h2(...n)),e.includes=(...n)=>e.check(p2(...n)),e.startsWith=(...n)=>e.check(B2(...n)),e.endsWith=(...n)=>e.check(m2(...n)),e.min=(...n)=>e.check(mh(...n)),e.max=(...n)=>e.check(sE(...n)),e.length=(...n)=>e.check(aE(...n)),e.nonempty=(...n)=>e.check(mh(1,...n)),e.lowercase=n=>e.check(d2(n)),e.uppercase=n=>e.check(g2(n)),e.trim=()=>e.check(w2()),e.normalize=(...n)=>e.check(v2(...n)),e.toLowerCase=()=>e.check(b2()),e.toUpperCase=()=>e.check(y2())}),k2=Z("ZodString",(e,t)=>{sv.init(e,t),oE.init(e,t),e.email=A=>e.check(MR(K2,A)),e.url=A=>e.check(kR(z2,A)),e.jwt=A=>e.check(e2(nI,A)),e.emoji=A=>e.check(KR(V2,A)),e.guid=A=>e.check(HC(MC,A)),e.uuid=A=>e.check(LR(Wu,A)),e.uuidv4=A=>e.check(RR(Wu,A)),e.uuidv6=A=>e.check(IR(Wu,A)),e.uuidv7=A=>e.check(NR(Wu,A)),e.nanoid=A=>e.check(zR(P2,A)),e.guid=A=>e.check(HC(MC,A)),e.cuid=A=>e.check(VR(j2,A)),e.cuid2=A=>e.check(PR(G2,A)),e.ulid=A=>e.check(jR(X2,A)),e.base64=A=>e.check(JR(tI,A)),e.base64url=A=>e.check(qR(eI,A)),e.xid=A=>e.check(GR(Z2,A)),e.ksuid=A=>e.check(XR(Y2,A)),e.ipv4=A=>e.check(ZR(W2,A)),e.ipv6=A=>e.check(YR($2,A)),e.cidrv4=A=>e.check(WR(J2,A)),e.cidrv6=A=>e.check($R(q2,A)),e.e164=A=>e.check(t2(AI,A)),e.datetime=A=>e.check(E2(A)),e.date=A=>e.check(S2(A)),e.time=A=>e.check(O2(A)),e.duration=A=>e.check(D2(A))});function gt(e){return DR(k2,e)}const Ce=Z("ZodStringFormat",(e,t)=>{ve.init(e,t),oE.init(e,t)}),K2=Z("ZodEmail",(e,t)=>{k4.init(e,t),Ce.init(e,t)}),MC=Z("ZodGUID",(e,t)=>{I4.init(e,t),Ce.init(e,t)}),Wu=Z("ZodUUID",(e,t)=>{N4.init(e,t),Ce.init(e,t)}),z2=Z("ZodURL",(e,t)=>{K4.init(e,t),Ce.init(e,t)}),V2=Z("ZodEmoji",(e,t)=>{z4.init(e,t),Ce.init(e,t)}),P2=Z("ZodNanoID",(e,t)=>{V4.init(e,t),Ce.init(e,t)}),j2=Z("ZodCUID",(e,t)=>{P4.init(e,t),Ce.init(e,t)}),G2=Z("ZodCUID2",(e,t)=>{j4.init(e,t),Ce.init(e,t)}),X2=Z("ZodULID",(e,t)=>{G4.init(e,t),Ce.init(e,t)}),Z2=Z("ZodXID",(e,t)=>{X4.init(e,t),Ce.init(e,t)}),Y2=Z("ZodKSUID",(e,t)=>{Z4.init(e,t),Ce.init(e,t)}),W2=Z("ZodIPv4",(e,t)=>{q4.init(e,t),Ce.init(e,t)}),$2=Z("ZodIPv6",(e,t)=>{tR.init(e,t),Ce.init(e,t)}),J2=Z("ZodCIDRv4",(e,t)=>{eR.init(e,t),Ce.init(e,t)}),q2=Z("ZodCIDRv6",(e,t)=>{AR.init(e,t),Ce.init(e,t)}),tI=Z("ZodBase64",(e,t)=>{nR.init(e,t),Ce.init(e,t)}),eI=Z("ZodBase64URL",(e,t)=>{rR.init(e,t),Ce.init(e,t)}),AI=Z("ZodE164",(e,t)=>{sR.init(e,t),Ce.init(e,t)}),nI=Z("ZodJWT",(e,t)=>{oR.init(e,t),Ce.init(e,t)}),lE=Z("ZodNumber",(e,t)=>{iE.init(e,t),we.init(e,t),e.gt=(n,i)=>e.check(TC(n,i)),e.gte=(n,i)=>e.check(Yf(n,i)),e.min=(n,i)=>e.check(Yf(n,i)),e.lt=(n,i)=>e.check(OC(n,i)),e.lte=(n,i)=>e.check(Zf(n,i)),e.max=(n,i)=>e.check(Zf(n,i)),e.int=n=>e.check(LC(n)),e.safe=n=>e.check(LC(n)),e.positive=n=>e.check(TC(0,n)),e.nonnegative=n=>e.check(Yf(0,n)),e.negative=n=>e.check(OC(0,n)),e.nonpositive=n=>e.check(Zf(0,n)),e.multipleOf=(n,i)=>e.check(DC(n,i)),e.step=(n,i)=>e.check(DC(n,i)),e.finite=()=>e;const A=e._zod.bag;e.minValue=Math.max(A.minimum??Number.NEGATIVE_INFINITY,A.exclusiveMinimum??Number.NEGATIVE_INFINITY)??null,e.maxValue=Math.min(A.maximum??Number.POSITIVE_INFINITY,A.exclusiveMaximum??Number.POSITIVE_INFINITY)??null,e.isInt=(A.format??"").includes("int")||Number.isSafeInteger(A.multipleOf??.5),e.isFinite=!0,e.format=A.format??null});function tA(e){return s2(lE,e)}const iI=Z("ZodNumberFormat",(e,t)=>{lR.init(e,t),lE.init(e,t)});function LC(e){return a2(iI,e)}const rI=Z("ZodBoolean",(e,t)=>{cR.init(e,t),we.init(e,t)});function id(e){return o2(rI,e)}const sI=Z("ZodAny",(e,t)=>{uR.init(e,t),we.init(e,t)});function wA(){return l2(sI)}const aI=Z("ZodUnknown",(e,t)=>{fR.init(e,t),we.init(e,t)});function RC(){return c2(aI)}const oI=Z("ZodNever",(e,t)=>{hR.init(e,t),we.init(e,t)});function lI(e){return u2(oI,e)}const cI=Z("ZodDate",(e,t)=>{dR.init(e,t),we.init(e,t),e.min=(n,i)=>e.check(Yf(n,i)),e.max=(n,i)=>e.check(Zf(n,i));const A=e._zod.bag;e.minDate=A.minimum?new Date(A.minimum):null,e.maxDate=A.maximum?new Date(A.maximum):null});function uI(e){return f2(cI,e)}const fI=Z("ZodArray",(e,t)=>{gR.init(e,t),we.init(e,t),e.element=t.element,e.min=(A,n)=>e.check(mh(A,n)),e.nonempty=A=>e.check(mh(1,A)),e.max=(A,n)=>e.check(sE(A,n)),e.length=(A,n)=>e.check(aE(A,n)),e.unwrap=()=>e.element});function IA(e,t){return C2(fI,e,t)}const hI=Z("ZodObject",(e,t)=>{pR.init(e,t),we.init(e,t),re(e,"shape",()=>t.shape),e.keyof=()=>av(Object.keys(e._zod.def.shape)),e.catchall=A=>e.clone({...e._zod.def,catchall:A}),e.passthrough=()=>e.clone({...e._zod.def,catchall:RC()}),e.loose=()=>e.clone({...e._zod.def,catchall:RC()}),e.strict=()=>e.clone({...e._zod.def,catchall:lI()}),e.strip=()=>e.clone({...e._zod.def,catchall:void 0}),e.extend=A=>KL(e,A),e.merge=A=>zL(e,A),e.pick=A=>NL(e,A),e.omit=A=>kL(e,A),e.partial=(...A)=>VL(fE,e,A[0]),e.required=(...A)=>PL(hE,e,A[0])});function fe(e,t){const A={type:"object",get shape(){return Js(this,"shape",{...e}),this.shape},...mt(t)};return new hI(A)}const cE=Z("ZodUnion",(e,t)=>{rE.init(e,t),we.init(e,t),e.options=t.options});function rd(e,t){return new cE({type:"union",options:e,...mt(t)})}const dI=Z("ZodDiscriminatedUnion",(e,t)=>{cE.init(e,t),BR.init(e,t)});function gI(e,t,A){return new dI({type:"union",options:t,discriminator:e,...mt(A)})}const pI=Z("ZodIntersection",(e,t)=>{mR.init(e,t),we.init(e,t)});function BI(e,t){return new pI({type:"intersection",left:e,right:t})}const mI=Z("ZodRecord",(e,t)=>{vR.init(e,t),we.init(e,t),e.keyType=t.keyType,e.valueType=t.valueType});function aA(e,t,A){return new mI({type:"record",keyType:e,valueType:t,...mt(A)})}const qB=Z("ZodEnum",(e,t)=>{wR.init(e,t),we.init(e,t),e.enum=t.entries,e.options=Object.values(t.entries);const A=new Set(Object.keys(t.entries));e.extract=(n,i)=>{const s={};for(const o of n)if(A.has(o))s[o]=t.entries[o];else throw new Error(`Key ${o} not found in enum`);return new qB({...t,checks:[],...mt(i),entries:s})},e.exclude=(n,i)=>{const s={...t.entries};for(const o of n)if(A.has(o))delete s[o];else throw new Error(`Key ${o} not found in enum`);return new qB({...t,checks:[],...mt(i),entries:s})}});function av(e,t){const A=Array.isArray(e)?Object.fromEntries(e.map(n=>[n,n])):e;return new qB({type:"enum",entries:A,...mt(t)})}const vI=Z("ZodLiteral",(e,t)=>{bR.init(e,t),we.init(e,t),e.values=new Set(t.values),Object.defineProperty(e,"value",{get(){if(t.values.length>1)throw new Error("This schema contains multiple valid literal values. Use `.values` instead.");return t.values[0]}})});function Ec(e,t){return new vI({type:"literal",values:Array.isArray(e)?e:[e],...mt(t)})}const wI=Z("ZodTransform",(e,t)=>{yR.init(e,t),we.init(e,t),e._zod.parse=(A,n)=>{A.addIssue=s=>{if(typeof s=="string")A.issues.push(rc(s,A.value,t));else{const o=s;o.fatal&&(o.continue=!1),o.code??(o.code="custom"),o.input??(o.input=A.value),o.inst??(o.inst=e),A.issues.push(rc(o))}};const i=t.transform(A.value,A);return i instanceof Promise?i.then(s=>(A.value=s,A)):(A.value=i,A)}});function uE(e){return new wI({type:"transform",transform:e})}const fE=Z("ZodOptional",(e,t)=>{CR.init(e,t),we.init(e,t),e.unwrap=()=>e._zod.def.innerType});function IC(e){return new fE({type:"optional",innerType:e})}const bI=Z("ZodNullable",(e,t)=>{_R.init(e,t),we.init(e,t),e.unwrap=()=>e._zod.def.innerType});function NC(e){return new bI({type:"nullable",innerType:e})}const yI=Z("ZodDefault",(e,t)=>{xR.init(e,t),we.init(e,t),e.unwrap=()=>e._zod.def.innerType,e.removeDefault=e.unwrap});function CI(e,t){return new yI({type:"default",innerType:e,get defaultValue(){return typeof t=="function"?t():t}})}const _I=Z("ZodPrefault",(e,t)=>{QR.init(e,t),we.init(e,t),e.unwrap=()=>e._zod.def.innerType});function xI(e,t){return new _I({type:"prefault",innerType:e,get defaultValue(){return typeof t=="function"?t():t}})}const hE=Z("ZodNonOptional",(e,t)=>{UR.init(e,t),we.init(e,t),e.unwrap=()=>e._zod.def.innerType});function QI(e,t){return new hE({type:"nonoptional",innerType:e,...mt(t)})}const UI=Z("ZodCatch",(e,t)=>{ER.init(e,t),we.init(e,t),e.unwrap=()=>e._zod.def.innerType,e.removeCatch=e.unwrap});function EI(e,t){return new UI({type:"catch",innerType:e,catchValue:typeof t=="function"?t:()=>t})}const FI=Z("ZodPipe",(e,t)=>{FR.init(e,t),we.init(e,t),e.in=t.in,e.out=t.out});function tm(e,t){return new FI({type:"pipe",in:e,out:t})}const SI=Z("ZodReadonly",(e,t)=>{SR.init(e,t),we.init(e,t),e.unwrap=()=>e._zod.def.innerType});function HI(e){return new SI({type:"readonly",innerType:e})}const OI=Z("ZodCustom",(e,t)=>{HR.init(e,t),we.init(e,t)});function TI(e,t={}){return _2(OI,e,t)}function DI(e){return x2(e)}function MI(e,t){return tm(uE(e),t)}const LI=fe({text:gt().describe("The text content."),type:Ec("text").default("text").describe("The type of the content part.")}),dE=fe({name:gt(),arguments:gt()}),RI=fe({id:gt(),type:Ec("function"),function:dE}),II=fe({role:gt().describe("assistant, user, system, tool"),content:rd([gt(),IA(LI)]).optional().default("").describe("The content of the message."),name:gt().optional(),tool_call_id:gt().optional(),tool_calls:IA(RI).optional(),function_call:dE.optional(),control_plane_step:aA(gt(),wA()).optional()}),NI=fe({is_score_valid:id().default(!0),score:tA().min(0).max(1),reason:gt()}),kI=fe({step_index:rd([tA(),gt()]).describe("User-defined index for the step (e.g., assistant message index, turn number). This is used by the system to map this output to the internal StepData."),base_reward:tA().describe("Base reward calculated by the user's reward function for this step."),terminated:id().default(!1).describe("Whether the environment signaled termination at this step."),control_plane_info:aA(gt(),wA()).optional().describe("Structured info from the environment's control plane."),metrics:aA(gt(),wA()).default({}).describe("Optional dictionary of custom metrics for this step."),reason:gt().optional().describe("Optional explanation for the step's base reward or metrics.")}),KI=fe({score:tA().describe("The overall evaluation score, typically between 0.0 and 1.0."),is_score_valid:id().default(!0).describe("Whether the overall score is valid."),reason:gt().optional().describe("Optional explanation for the overall score."),metrics:aA(gt(),NI).default({}).describe("Dictionary of component metrics for detailed breakdown."),step_outputs:IA(kI).optional().describe("For RL, a list of outputs for each conceptual step, providing base rewards."),error:gt().optional().describe("Optional error message if the evaluation itself encountered an issue."),trajectory_info:aA(gt(),wA()).optional().describe("Additional trajectory-level information (duration, steps, termination_reason, etc.)."),final_control_plane_info:aA(gt(),wA()).optional().describe("The final control plane state that led to termination."),agg_score:tA().optional().describe("The aggregated score of the evaluation across all runs."),standard_error:tA().optional().describe("The standard error of the evaluation across all runs.")}),zI=aA(gt(),wA());fe({reason:gt().describe("Short snake_case description of the error cause"),domain:gt().describe("Logical grouping for the error reason"),metadata:aA(gt(),wA()).default({}).describe("Additional dynamic information as context")});av(["OK","CANCELLED","UNKNOWN","INVALID_ARGUMENT","DEADLINE_EXCEEDED","NOT_FOUND","ALREADY_EXISTS","PERMISSION_DENIED","RESOURCE_EXHAUSTED","FAILED_PRECONDITION","ABORTED","OUT_OF_RANGE","UNIMPLEMENTED","INTERNAL","UNAVAILABLE","DATA_LOSS","UNAUTHENTICATED","FINISHED","RUNNING"]).describe("Common gRPC status codes as defined in google.rpc.Code");const VI={0:"OK",1:"CANCELLED",2:"UNKNOWN",3:"INVALID_ARGUMENT",4:"DEADLINE_EXCEEDED",5:"NOT_FOUND",6:"ALREADY_EXISTS",7:"PERMISSION_DENIED",8:"RESOURCE_EXHAUSTED",9:"FAILED_PRECONDITION",10:"ABORTED",11:"OUT_OF_RANGE",12:"UNIMPLEMENTED",13:"INTERNAL",14:"UNAVAILABLE",15:"DATA_LOSS",16:"UNAUTHENTICATED",100:"FINISHED",101:"RUNNING"},PI=e=>VI[e]||"UNKNOWN",gE=fe({code:tA().describe("The status code (numeric value from google.rpc.Code enum)"),message:gt().describe("Developer-facing, human-readable debug message in English"),details:IA(aA(gt(),wA())).default([]).describe("Additional error information, each packed in a google.protobuf.Any message format")}),jI=fe({success:tA().min(0).max(1).describe("Minimum success rate threshold (fraction of total score, 0.0 to 1.0)"),standard_error:tA().min(0).max(1).optional().describe("Maximum standard error threshold (fraction of total score, 0.0 to 1.0)")}),GI=fe({row_id:gt().optional().describe("Unique string to ID the row. If not provided, a stable hash will be generated based on the row's content. The hash removes fields that are not typically stable across processes such as created_at, execution_metadata, and pid."),completion_params:zI.describe("Completion endpoint parameters used"),dataset_info:aA(gt(),wA()).optional().describe("Dataset row details: seed, system_prompt, environment_context, etc"),session_data:aA(gt(),wA()).optional().describe("Session metadata like timestamp (input only, no duration/usage)")}).loose(),XI=fe({prompt_tokens:tA(),completion_tokens:tA(),total_tokens:tA()}),ZI=fe({name:gt().describe("Name of the evaluation"),description:gt().optional().describe("Description of the evaluation"),version:gt().describe("Version of the evaluation. Should be populated with a PEP 440 version string."),status:gE.optional().describe("Status of the evaluation"),num_runs:tA().int().describe("Number of times the evaluation was repeated"),aggregation_method:gt().describe("Method used to aggregate scores across runs"),passed_threshold:jI.optional().describe("Threshold configuration for test success"),passed:id().optional().describe("Whether the evaluation passed based on the threshold")}),YI=fe({invocation_id:gt().optional().describe("The ID of the invocation that this row belongs to."),experiment_id:gt().optional().describe("The ID of the experiment that this row belongs to."),rollout_id:gt().optional().describe("The ID of the rollout that this row belongs to."),run_id:gt().optional().describe("The ID of the run that this row belongs to.")}),em=fe({messages:IA(II).describe("List of messages in the conversation/trajectory."),tools:IA(aA(gt(),wA())).optional().describe("Available tools/functions that were provided to the agent."),input_metadata:GI.describe("Metadata related to the input (dataset info, model config, session data, etc.)."),rollout_status:gE.describe("The status of the rollout following AIP-193 standards."),execution_metadata:YI.optional().describe("Metadata about the execution of the evaluation."),ground_truth:gt().optional().describe("Optional ground truth reference for this evaluation."),evaluation_result:KI.optional().describe("The evaluation result for this row/trajectory."),usage:XI.optional().describe("Token usage statistics from LLM calls during execution."),created_at:MI(e=>typeof e=="string"?new Date(e):e,uI()).describe("The timestamp when the row was created. Accepts string and parses to Date."),eval_metadata:ZI.optional().describe("Metadata about the evaluation that was run."),pid:tA().optional().describe("The PID of the process that created the row. This is used by the evaluation watcher to detect stopped evaluations.")}),WI=fe({start_command:gt().describe("The command to start the server. The string '{port}' will be replaced with a dynamically allocated free port."),health_check_url:gt().describe("The URL to poll to check if the server is ready. The string '{port}' will be replaced with the allocated port.")}),$I=fe({final_state_query:gt().optional().describe("A query (e.g., SQL) to run on the final state of the resource."),expected_query_result_transform:gt().optional().describe("A Python lambda string (e.g., 'lambda x: x > 0') to transform and evaluate the query result to a boolean."),ground_truth_function_calls:IA(IA(gt())).optional().describe("Ground truth function calls for BFCL evaluation."),ground_truth_comparable_state:aA(gt(),wA()).optional().describe("Ground truth comparable state for BFCL evaluation.")});fe({name:gt().describe("Unique name for the task."),description:gt().optional().describe("A brief description of the task."),resource_type:gt().describe("The type of ForkableResource to use (e.g., 'SQLResource', 'PythonStateResource', 'FileSystemResource', 'DockerResource')."),base_resource_config:aA(gt(),wA()).default({}).describe("Configuration dictionary passed to the base resource's setup() method."),tools_module_path:gt().optional().describe("Optional Python import path to a module containing custom tool functions for this task."),reward_function_path:gt().describe("Python import path to the reward function (e.g., 'my_module.my_reward_func')."),goal_description:gt().optional().describe("A human-readable description of the agent's goal for this task."),evaluation_criteria:$I.optional().describe("Criteria used by the Orchestrator to determine if the primary goal was achieved."),initial_user_prompt:gt().optional().describe("The initial prompt or message to start the agent interaction. Deprecated if 'messages' field is used for multi-turn."),messages:IA(aA(gt(),wA())).optional().describe("A list of messages to start the conversation, can represent multiple user turns for sequential processing."),poc_max_turns:tA().int().min(1).default(3).describe("For PoC Orchestrator, the maximum number of interaction turns."),resource_server:WI.optional().describe("Configuration for a background server required for the task."),num_rollouts:tA().int().min(1).default(1).describe("Number of parallel rollouts to execute for this task definition."),dataset_path:gt().optional().describe("Path to dataset file (JSONL) containing experimental conditions for data-driven evaluation."),num_rollouts_per_sample:tA().int().min(1).default(1).describe("Number of rollouts to execute per sample from the dataset.")}).loose();const JI=fe({command:gt().describe("command to run the MCP server"),args:IA(gt()).default([]).describe("to pass to the command"),env:IA(gt()).default([]).describe("List of environment variables to verify exist in the environment")}),qI=fe({url:gt().describe("url to the MCP server")});fe({mcpServers:aA(gt(),rd([JI,qI]))});const tN=({color:e})=>Q.jsx("div",{className:`animate-spin w-1.5 h-1.5 rounded-full border border-current ${e} border-t-transparent`}),pE=({status:e,className:t="",showSpinner:A=!1})=>{const i=(o=>{switch(PI(o.code)){case"OK":return{dotColor:"bg-green-500",textColor:"text-green-700",text:"Connected"};case"CANCELLED":return{dotColor:"bg-red-500",textColor:"text-red-700",text:"Disconnected"};case"FINISHED":return{dotColor:"bg-green-500",textColor:"text-green-700",text:"finished"};case"RUNNING":return{dotColor:"bg-blue-500",textColor:"text-blue-700",text:"running"};case"INTERNAL":return{dotColor:"bg-red-500",textColor:"text-red-700",text:"error"};case"ABORTED":return{dotColor:"bg-yellow-500",textColor:"text-yellow-700",text:"stopped"};default:return{dotColor:"bg-gray-500",textColor:"text-gray-700",text:o.message}}})(e),s=A&&e.code===101;return Q.jsxs("div",{className:`inline-flex items-center gap-1.5 text-xs font-medium ${i.textColor} ${t}`,children:[s?Q.jsx(tN,{color:i.textColor}):Q.jsx("div",{className:`w-1.5 h-1.5 rounded-full ${i.dotColor}`}),i.text]})};function eN({children:e,className:t=""}){return Q.jsx("div",{className:`bg-white border border-gray-200 overflow-x-auto ${t}`,children:e})}function BE({children:e,className:t=""}){return Q.jsx("thead",{className:`bg-gray-50 border-b border-gray-200 ${t}`,children:e})}function mE({children:e,className:t=""}){return Q.jsx("tbody",{className:`divide-y divide-gray-200 ${t}`,children:e})}function Wf({children:e,className:t="",align:A="left",nowrap:n=!1}){const i={left:"text-left",center:"text-center",right:"text-right"};return Q.jsx("th",{className:`px-3 py-2 text-xs font-semibold text-gray-700 ${i[A]} ${n?"whitespace-nowrap":""} ${t}`,children:e})}function Hn({children:e,className:t="",align:A="left",nowrap:n=!1,sortField:i,currentSortField:s,currentSortDirection:o,onSort:c}){const u={left:"text-left",center:"text-center",right:"text-right"},d=s===i?o==="asc"?Q.jsx("svg",{className:"w-3 h-3 ml-1",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:Q.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 15l7-7 7 7"})}):Q.jsx("svg",{className:"w-3 h-3 ml-1",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:Q.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})}):Q.jsx("svg",{className:"w-3 h-3 ml-1 text-gray-400",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:Q.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4"})});return Q.jsx("th",{className:`px-3 py-2 text-xs font-semibold text-gray-700 cursor-pointer hover:bg-gray-100 transition-colors ${u[A]} ${n?"whitespace-nowrap":""} ${t}`,onClick:()=>c(i),style:{cursor:"pointer"},children:Q.jsxs("div",{className:"flex items-center",children:[e,d]})})}function kC({children:e,className:t="",gray:A=!1}){return Q.jsx("tr",{className:`${A?"bg-gray-50":""} ${t}`,children:e})}function AN({children:e,className:t="",onClick:A,interactive:n=!0}){const i=n?"hover:bg-gray-50 cursor-pointer":"";return Q.jsx("tr",{className:`text-sm ${i} ${t}`,onClick:A,children:e})}function We({children:e,className:t="",align:A="left",nowrap:n=!1,medium:i=!1,semibold:s=!1,colSpan:o}){const c={left:"text-left",center:"text-center",right:"text-right"},u=[];return i&&u.push("font-medium"),s&&u.push("font-semibold"),Q.jsx("td",{colSpan:o,className:`px-3 py-2 text-gray-900 ${c[A]} ${n?"whitespace-nowrap":""} ${u.join(" ")} ${t}`,children:e})}const nN=({children:e,data:t,position:A="top",className:n=""})=>{const i=`json-tooltip-${Math.random().toString(36).substr(2,9)}`,s=JSON.stringify(t,null,2);return Q.jsxs(Q.Fragment,{children:[Q.jsx("div",{"data-tooltip-id":i,className:`cursor-help ${n}`,children:e}),Q.jsx(zU,{id:i,place:A,className:"px-2 py-1 text-xs text-white bg-gray-800 rounded z-10 max-w-md",style:{fontSize:"0.75rem",lineHeight:"1rem",backgroundColor:"#1f2937",color:"white",borderRadius:"0.25rem",padding:"0.5rem",zIndex:10,userSelect:"text",pointerEvents:"auto"},delayShow:200,delayHide:300,clickable:!0,noArrow:!0,render:()=>Q.jsx("pre",{className:"whitespace-pre-wrap text-left text-xs",style:{userSelect:"text",pointerEvents:"auto",cursor:"text"},onMouseDown:o=>o.stopPropagation(),onClick:o=>o.stopPropagation(),onDoubleClick:o=>o.stopPropagation(),onContextMenu:o=>o.stopPropagation(),children:s})})]})},iN=Ae(({fieldPath:e,value:t,label:A})=>{const[n,i]=S.useState(!1),s=o=>{o.stopPropagation();const c={field:e,operator:"==",value:t,type:"text"},u=rt.filterConfig;let h;u.length===0?h=[{logic:"AND",filters:[c]}]:(h=[...u],h[0]={...h[0],filters:[...h[0].filters,c]}),rt.updateFilterConfig(h),i(!0),setTimeout(()=>i(!1),2e3)};return Q.jsx(VU,{content:n?"Filter Added!":`Add ${A} Filter`,position:"top",className:"text-gray-400 hover:text-gray-600 transition-colors",children:Q.jsx("div",{className:"flex items-center gap-1",children:Q.jsx("button",{className:"cursor-pointer",onClick:s,title:"Add filter for this value",children:n?Q.jsx("svg",{className:"w-3 h-3 text-green-600",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:Q.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 13l4 4L19 7"})}):Q.jsx("svg",{className:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:Q.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.207A1 1 0 013 6.5V4z"})})})})})}),rN=Ae(({rolloutId:e})=>{if(!e)throw new Error("Rollout ID is required");const t=rt.isRowExpanded(e);return Q.jsx("div",{className:"w-4 h-4 flex items-center justify-center",children:Q.jsx("svg",{className:`h-4 w-4 text-gray-500 transition-transform duration-200 ${t?"rotate-90":""}`,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:Q.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})})}),sN=Ae(({name:e})=>Q.jsx("span",{className:"text-gray-900 truncate block",children:e||"N/A"})),KC=Ae(({status:e,showSpinner:t})=>Q.jsx("div",{className:"whitespace-nowrap",children:Q.jsx(pE,{showSpinner:t,status:e||{code:2,message:"N/A",details:[]}})})),aN=Ae(({experimentId:e})=>{debugger;return e?Q.jsx("span",{className:"font-mono text-gray-900 whitespace-nowrap",children:e}):null}),oN=Ae(({runId:e})=>e?Q.jsx("span",{className:"font-mono text-gray-900 whitespace-nowrap",children:e}):null),lN=Ae(({rowId:e})=>e?Q.jsx("span",{className:"font-mono text-gray-900 whitespace-nowrap",children:e}):null),cN=Ae(({rolloutId:e})=>e?Q.jsx("span",{className:"font-mono text-gray-900 whitespace-nowrap",children:e}):null),uN=Ae(({invocationId:e})=>e?Q.jsxs("span",{className:"font-mono text-gray-900 whitespace-nowrap flex items-center gap-1",children:[e,Q.jsx(iN,{fieldPath:"$.execution_metadata.invocation_id",value:e,label:"Invocation"})]}):null),fN=Ae(({model:e})=>{const t=e?typeof e=="string"?e:JSON.stringify(e):"N/A";return typeof e=="string"||!e?Q.jsx("span",{className:"text-gray-900 block",children:t}):Q.jsx(nN,{data:e,children:Q.jsx("span",{className:"text-gray-900 truncate block max-w-[200px] cursor-help",children:t})})}),hN=Ae(({score:e})=>{const t=e?e>=.8?"text-green-700":e>=.6?"text-yellow-700":"text-red-700":"text-gray-500";return Q.jsx("span",{className:`font-mono whitespace-nowrap ${t}`,children:e?.toFixed(3)||"N/A"})}),dN=Ae(({created_at:e})=>{const t=e instanceof Date?e:new Date(e);return Q.jsx("span",{className:"text-gray-600 whitespace-nowrap",children:t.toLocaleDateString()+" "+t.toLocaleTimeString()})}),gN=Ae(({data:e})=>Q.jsx(Jr,{title:"Eval Metadata",data:e,defaultExpanded:!0})),pN=Ae(({data:e})=>Q.jsx(Jr,{title:"Rollout Status",data:e,defaultExpanded:!0})),BN=Ae(({data:e})=>Q.jsx(Jr,{title:"Evaluation Result",data:e,defaultExpanded:!0})),mN=Ae(({data:e})=>Q.jsx(Jr,{title:"Ground Truth",data:e})),vN=Ae(({data:e})=>Q.jsx(Jr,{title:"Usage Stats",data:e})),wN=Ae(({data:e})=>Q.jsx(Jr,{title:"Input Metadata",data:e})),bN=Ae(({data:e})=>Q.jsx(Jr,{title:"IDs",data:{rollout_id:e.execution_metadata?.rollout_id,experiment_id:e.execution_metadata?.experiment_id,invocation_id:e.execution_metadata?.invocation_id,run_id:e.execution_metadata?.run_id}})),yN=Ae(({data:e})=>Q.jsx(Jr,{title:"Tools",data:e})),CN=Ae(({messages:e})=>Q.jsx(OL,{messages:e})),_N=Ae(({row:e,messages:t,eval_metadata:A,evaluation_result:n,ground_truth:i,usage:s,input_metadata:o,tools:c,rollout_status:u})=>Q.jsx("div",{className:"p-4 bg-gray-50",children:Q.jsxs("div",{className:"flex gap-3 w-fit",children:[Q.jsx("div",{className:"min-w-0",children:Q.jsx(CN,{messages:t})}),Q.jsxs("div",{className:"w-[500px] flex-shrink-0 space-y-3",children:[Q.jsx(gN,{data:A}),Q.jsx(BN,{data:n}),Q.jsx(pN,{data:u}),Q.jsx(bN,{data:e}),Q.jsx(mN,{data:i}),Q.jsx(vN,{data:s}),Q.jsx(wN,{data:o}),Q.jsx(yN,{data:c})]})]})})),xN=Ae(({row:e})=>{const t=e.execution_metadata?.rollout_id,A=rt.isRowExpanded(t),n=()=>rt.toggleRowExpansion(t);return Q.jsxs(Q.Fragment,{children:[Q.jsxs(AN,{onClick:n,children:[Q.jsx(We,{className:"w-8 py-3",children:Q.jsx(rN,{rolloutId:t})}),Q.jsx(We,{className:"py-3 text-xs",children:Q.jsx(sN,{name:e.eval_metadata?.name})}),Q.jsx(We,{className:"py-3 text-xs",children:Q.jsx(KC,{status:e.eval_metadata?.status,showSpinner:e.eval_metadata?.status?.code===101})}),Q.jsx(We,{className:"py-3 text-xs",children:Q.jsx(KC,{status:e.rollout_status,showSpinner:e.rollout_status?.code===101})}),Q.jsx(We,{className:"py-3 text-xs",children:Q.jsx(uN,{invocationId:e.execution_metadata?.invocation_id})}),Q.jsx(We,{className:"py-3 text-xs",children:Q.jsx(aN,{experimentId:e.execution_metadata?.experiment_id})}),Q.jsx(We,{className:"py-3 text-xs",children:Q.jsx(oN,{runId:e.execution_metadata?.run_id})}),Q.jsx(We,{className:"py-3 text-xs",children:Q.jsx(lN,{rowId:e.input_metadata?.row_id})}),Q.jsx(We,{className:"py-3 text-xs",children:Q.jsx(cN,{rolloutId:e.execution_metadata?.rollout_id})}),Q.jsx(We,{className:"py-3 text-xs",children:Q.jsx(fN,{model:e.input_metadata.completion_params.model})}),Q.jsx(We,{className:"py-3 text-xs",children:Q.jsx(hN,{score:e.evaluation_result?.score})}),Q.jsx(We,{className:"py-3 text-xs",children:Q.jsx(dN,{created_at:e.created_at})})]}),A&&Q.jsx("tr",{children:Q.jsx("td",{colSpan:9,className:"p-0",children:Q.jsx(_N,{row:e,messages:e.messages,eval_metadata:e.eval_metadata,evaluation_result:e.evaluation_result,ground_truth:e.ground_truth,usage:e.usage,input_metadata:e.input_metadata,tools:e.tools,rollout_status:e.rollout_status})})})]})}),ov=mA.forwardRef(({className:e="",size:t="sm",children:A,...n},i)=>Q.jsx("select",{ref:i,className:`${te.input.base} ${te.input.size[t]} ${e}`,style:{boxShadow:te.input.shadow},...n,children:A}));ov.displayName="Select";const Ds=mA.forwardRef(({options:e,value:t,onChange:A,placeholder:n="Select...",size:i="sm",className:s="",disabled:o=!1},c)=>{const[u,h]=S.useState(!1),[d,p]=S.useState(""),m=S.useMemo(()=>{const Y=d.toLowerCase();return Y?e.filter(ut=>ut.label.toLowerCase().includes(Y)||ut.value.toLowerCase().includes(Y)):e},[d,e]),[v,w]=S.useState("left"),[b,_]=S.useState(void 0),[C,U]=S.useState(-1),E=S.useRef(null),H=S.useRef(null);S.useEffect(()=>{U(-1)},[d,e]),S.useEffect(()=>{const Y=ut=>{E.current&&!E.current.contains(ut.target)&&(h(!1),p(""))};return document.addEventListener("mousedown",Y),()=>document.removeEventListener("mousedown",Y)},[]);const F=Y=>{A(Y),h(!1),p(""),U(-1)},D=Y=>{if(u)switch(Y.key){case"ArrowDown":Y.preventDefault(),U(ut=>utut>0?ut-1:m.length-1);break;case"Enter":Y.preventDefault(),C>=0&&m[C]&&F(m[C].value);break;case"Escape":h(!1),p(""),U(-1);break}},R=()=>{if(!E.current)return{side:"left",width:240};const Y=E.current.getBoundingClientRect(),ut=window.innerWidth,lt=16,Yt=Math.min(Y.width+240,600),An=ut-Y.left-lt,Pe=Y.right-lt,eA=Math.max(Y.width,Math.min(Yt,An)),EA=Math.max(Y.width,Math.min(Yt,Pe));if(eA>=EA&&eA>=Y.width)return{side:"left",width:eA};if(EA>eA&&EA>=Y.width)return{side:"right",width:EA};const FA=Math.max(Y.width,Math.min(Yt,ut-lt*2));return{side:Y.left{if(!o){if(!u){const Y=R();w(Y.side),_(Y.width)}h(!u),u||setTimeout(()=>H.current?.focus(),0)}},N=S.useMemo(()=>e.find(Y=>Y.value===t),[e,t]),J=S.useRef(null),[et,nt]=S.useState(0),[ot,ft]=S.useState(192),st=32,L=5,G=m.length,q=Math.max(1,Math.ceil(ot/st)),ct=Math.max(0,Math.floor(et/st)-L),T=Math.min(G,ct+q+L*2),j=ct*st,At=Math.max(0,(G-T)*st);S.useLayoutEffect(()=>{if(!u)return;const Y=J.current;if(!Y)return;const ut=()=>{ft(Y.clientHeight||192)};ut();const lt=new ResizeObserver(ut);return lt.observe(Y),()=>lt.disconnect()},[u]),S.useEffect(()=>{u&&J.current&&(J.current.scrollTop=0,nt(0))},[u,d]);const tt=Y=>{nt(Y.target.scrollTop)};return Q.jsxs("div",{ref:E,className:`relative ${s}`,children:[Q.jsxs("div",{ref:c,onClick:z,onKeyDown:Y=>{(Y.key==="Enter"||Y.key===" ")&&(Y.preventDefault(),z())},tabIndex:0,role:"combobox","aria-expanded":u,"aria-haspopup":"listbox",className:` + `)}m.write("payload.value = newResult;"),m.write("return payload;");const C=m.compile();return(U,E)=>C(p,U,E)};let i;const s=ph,o=!PU.jitless,u=o&&ML.value,h=t.catchall;let d;e._zod.parse=(p,m)=>{d??(d=A.value);const v=p.value;if(!s(v))return p.issues.push({expected:"object",code:"invalid_type",input:v,inst:e}),p;const w=[];if(o&&u&&m?.async===!1&&m.jitless!==!0)i||(i=n(t.shape)),p=i(p,m);else{p.value={};const E=d.shape;for(const H of d.keys){const D=E[H]._zod.run({value:v[H],issues:[]},m);D instanceof Promise?w.push(D.then(R=>Zu(R,p,H,v))):Zu(D,p,H,v)}}if(!h)return w.length?Promise.all(w).then(()=>p):p;const b=[],_=d.keySet,C=h._zod,U=C.def.type;for(const E of Object.keys(v)){if(_.has(E))continue;if(U==="never"){b.push(E);continue}const H=C.run({value:v[E],issues:[]},m);H instanceof Promise?w.push(H.then(F=>Zu(F,p,E,v))):Zu(H,p,E,v)}return b.length&&p.issues.push({code:"unrecognized_keys",keys:b,input:v,inst:e}),w.length?Promise.all(w).then(()=>p):p}});function CC(e,t,A,n){for(const s of e)if(s.issues.length===0)return t.value=s.value,t;const i=e.filter(s=>!zl(s));return i.length===1?(t.value=i[0].value,i[0]):(t.issues.push({code:"invalid_union",input:t.value,inst:A,errors:e.map(s=>s.issues.map(o=>Gr(o,n,jr())))}),t)}const rE=Z("$ZodUnion",(e,t)=>{le.init(e,t),re(e._zod,"optin",()=>t.options.some(i=>i._zod.optin==="optional")?"optional":void 0),re(e._zod,"optout",()=>t.options.some(i=>i._zod.optout==="optional")?"optional":void 0),re(e._zod,"values",()=>{if(t.options.every(i=>i._zod.values))return new Set(t.options.flatMap(i=>Array.from(i._zod.values)))}),re(e._zod,"pattern",()=>{if(t.options.every(i=>i._zod.pattern)){const i=t.options.map(s=>s._zod.pattern);return new RegExp(`^(${i.map(s=>iv(s.source)).join("|")})$`)}});const A=t.options.length===1,n=t.options[0]._zod.run;e._zod.parse=(i,s)=>{if(A)return n(i,s);let o=!1;const c=[];for(const u of t.options){const h=u._zod.run({value:i.value,issues:[]},s);if(h instanceof Promise)c.push(h),o=!0;else{if(h.issues.length===0)return h;c.push(h)}}return o?Promise.all(c).then(u=>CC(u,i,e,s)):CC(c,i,e,s)}}),BR=Z("$ZodDiscriminatedUnion",(e,t)=>{rE.init(e,t);const A=e._zod.parse;re(e._zod,"propValues",()=>{const i={};for(const s of t.options){const o=s._zod.propValues;if(!o||Object.keys(o).length===0)throw new Error(`Invalid discriminated union option at index "${t.options.indexOf(s)}"`);for(const[c,u]of Object.entries(o)){i[c]||(i[c]=new Set);for(const h of u)i[c].add(h)}}return i});const n=Av(()=>{const i=t.options,s=new Map;for(const o of i){const c=o._zod.propValues?.[t.discriminator];if(!c||c.size===0)throw new Error(`Invalid discriminated union option at index "${t.options.indexOf(o)}"`);for(const u of c){if(s.has(u))throw new Error(`Duplicate discriminator value "${String(u)}"`);s.set(u,o)}}return s});e._zod.parse=(i,s)=>{const o=i.value;if(!ph(o))return i.issues.push({code:"invalid_type",expected:"object",input:o,inst:e}),i;const c=n.value.get(o?.[t.discriminator]);return c?c._zod.run(i,s):t.unionFallback?A(i,s):(i.issues.push({code:"invalid_union",errors:[],note:"No matching discriminator",discriminator:t.discriminator,input:o,path:[t.discriminator],inst:e}),i)}}),mR=Z("$ZodIntersection",(e,t)=>{le.init(e,t),e._zod.parse=(A,n)=>{const i=A.value,s=t.left._zod.run({value:i,issues:[]},n),o=t.right._zod.run({value:i,issues:[]},n);return s instanceof Promise||o instanceof Promise?Promise.all([s,o]).then(([u,h])=>_C(A,u,h)):_C(A,s,o)}});function JB(e,t){if(e===t)return{valid:!0,data:e};if(e instanceof Date&&t instanceof Date&&+e==+t)return{valid:!0,data:e};if(Bh(e)&&Bh(t)){const A=Object.keys(t),n=Object.keys(e).filter(s=>A.indexOf(s)!==-1),i={...e,...t};for(const s of n){const o=JB(e[s],t[s]);if(!o.valid)return{valid:!1,mergeErrorPath:[s,...o.mergeErrorPath]};i[s]=o.data}return{valid:!0,data:i}}if(Array.isArray(e)&&Array.isArray(t)){if(e.length!==t.length)return{valid:!1,mergeErrorPath:[]};const A=[];for(let n=0;n{le.init(e,t),e._zod.parse=(A,n)=>{const i=A.value;if(!Bh(i))return A.issues.push({expected:"record",code:"invalid_type",input:i,inst:e}),A;const s=[];if(t.keyType._zod.values){const o=t.keyType._zod.values;A.value={};for(const u of o)if(typeof u=="string"||typeof u=="number"||typeof u=="symbol"){const h=t.valueType._zod.run({value:i[u],issues:[]},n);h instanceof Promise?s.push(h.then(d=>{d.issues.length&&A.issues.push(...to(u,d.issues)),A.value[u]=d.value})):(h.issues.length&&A.issues.push(...to(u,h.issues)),A.value[u]=h.value)}let c;for(const u in i)o.has(u)||(c=c??[],c.push(u));c&&c.length>0&&A.issues.push({code:"unrecognized_keys",input:i,inst:e,keys:c})}else{A.value={};for(const o of Reflect.ownKeys(i)){if(o==="__proto__")continue;const c=t.keyType._zod.run({value:o,issues:[]},n);if(c instanceof Promise)throw new Error("Async schemas not supported in object keys currently");if(c.issues.length){A.issues.push({code:"invalid_key",origin:"record",issues:c.issues.map(h=>Gr(h,n,jr())),input:o,path:[o],inst:e}),A.value[c.value]=c.value;continue}const u=t.valueType._zod.run({value:i[o],issues:[]},n);u instanceof Promise?s.push(u.then(h=>{h.issues.length&&A.issues.push(...to(o,h.issues)),A.value[c.value]=h.value})):(u.issues.length&&A.issues.push(...to(o,u.issues)),A.value[c.value]=u.value)}}return s.length?Promise.all(s).then(()=>A):A}}),wR=Z("$ZodEnum",(e,t)=>{le.init(e,t);const A=TL(t.entries),n=new Set(A);e._zod.values=n,e._zod.pattern=new RegExp(`^(${A.filter(i=>LL.has(typeof i)).map(i=>typeof i=="string"?lo(i):i.toString()).join("|")})$`),e._zod.parse=(i,s)=>{const o=i.value;return n.has(o)||i.issues.push({code:"invalid_value",values:A,input:o,inst:e}),i}}),bR=Z("$ZodLiteral",(e,t)=>{if(le.init(e,t),t.values.length===0)throw new Error("Cannot create literal schema with no valid values");e._zod.values=new Set(t.values),e._zod.pattern=new RegExp(`^(${t.values.map(A=>typeof A=="string"?lo(A):A?lo(A.toString()):String(A)).join("|")})$`),e._zod.parse=(A,n)=>{const i=A.value;return e._zod.values.has(i)||A.issues.push({code:"invalid_value",values:t.values,input:i,inst:e}),A}}),yR=Z("$ZodTransform",(e,t)=>{le.init(e,t),e._zod.parse=(A,n)=>{const i=t.transform(A.value,A);if(n.async)return(i instanceof Promise?i:Promise.resolve(i)).then(o=>(A.value=o,A));if(i instanceof Promise)throw new ic;return A.value=i,A}});function xC(e,t){return e.issues.length&&t===void 0?{issues:[],value:void 0}:e}const CR=Z("$ZodOptional",(e,t)=>{le.init(e,t),e._zod.optin="optional",e._zod.optout="optional",re(e._zod,"values",()=>t.innerType._zod.values?new Set([...t.innerType._zod.values,void 0]):void 0),re(e._zod,"pattern",()=>{const A=t.innerType._zod.pattern;return A?new RegExp(`^(${iv(A.source)})?$`):void 0}),e._zod.parse=(A,n)=>{if(t.innerType._zod.optin==="optional"){const i=t.innerType._zod.run(A,n);return i instanceof Promise?i.then(s=>xC(s,A.value)):xC(i,A.value)}return A.value===void 0?A:t.innerType._zod.run(A,n)}}),_R=Z("$ZodNullable",(e,t)=>{le.init(e,t),re(e._zod,"optin",()=>t.innerType._zod.optin),re(e._zod,"optout",()=>t.innerType._zod.optout),re(e._zod,"pattern",()=>{const A=t.innerType._zod.pattern;return A?new RegExp(`^(${iv(A.source)}|null)$`):void 0}),re(e._zod,"values",()=>t.innerType._zod.values?new Set([...t.innerType._zod.values,null]):void 0),e._zod.parse=(A,n)=>A.value===null?A:t.innerType._zod.run(A,n)}),xR=Z("$ZodDefault",(e,t)=>{le.init(e,t),e._zod.optin="optional",re(e._zod,"values",()=>t.innerType._zod.values),e._zod.parse=(A,n)=>{if(A.value===void 0)return A.value=t.defaultValue,A;const i=t.innerType._zod.run(A,n);return i instanceof Promise?i.then(s=>QC(s,t)):QC(i,t)}});function QC(e,t){return e.value===void 0&&(e.value=t.defaultValue),e}const QR=Z("$ZodPrefault",(e,t)=>{le.init(e,t),e._zod.optin="optional",re(e._zod,"values",()=>t.innerType._zod.values),e._zod.parse=(A,n)=>(A.value===void 0&&(A.value=t.defaultValue),t.innerType._zod.run(A,n))}),UR=Z("$ZodNonOptional",(e,t)=>{le.init(e,t),re(e._zod,"values",()=>{const A=t.innerType._zod.values;return A?new Set([...A].filter(n=>n!==void 0)):void 0}),e._zod.parse=(A,n)=>{const i=t.innerType._zod.run(A,n);return i instanceof Promise?i.then(s=>UC(s,e)):UC(i,e)}});function UC(e,t){return!e.issues.length&&e.value===void 0&&e.issues.push({code:"invalid_type",expected:"nonoptional",input:e.value,inst:t}),e}const ER=Z("$ZodCatch",(e,t)=>{le.init(e,t),re(e._zod,"optin",()=>t.innerType._zod.optin),re(e._zod,"optout",()=>t.innerType._zod.optout),re(e._zod,"values",()=>t.innerType._zod.values),e._zod.parse=(A,n)=>{const i=t.innerType._zod.run(A,n);return i instanceof Promise?i.then(s=>(A.value=s.value,s.issues.length&&(A.value=t.catchValue({...A,error:{issues:s.issues.map(o=>Gr(o,n,jr()))},input:A.value}),A.issues=[]),A)):(A.value=i.value,i.issues.length&&(A.value=t.catchValue({...A,error:{issues:i.issues.map(s=>Gr(s,n,jr()))},input:A.value}),A.issues=[]),A)}}),FR=Z("$ZodPipe",(e,t)=>{le.init(e,t),re(e._zod,"values",()=>t.in._zod.values),re(e._zod,"optin",()=>t.in._zod.optin),re(e._zod,"optout",()=>t.out._zod.optout),re(e._zod,"propValues",()=>t.in._zod.propValues),e._zod.parse=(A,n)=>{const i=t.in._zod.run(A,n);return i instanceof Promise?i.then(s=>EC(s,t,n)):EC(i,t,n)}});function EC(e,t,A){return e.issues.length?e:t.out._zod.run({value:e.value,issues:e.issues},A)}const SR=Z("$ZodReadonly",(e,t)=>{le.init(e,t),re(e._zod,"propValues",()=>t.innerType._zod.propValues),re(e._zod,"values",()=>t.innerType._zod.values),re(e._zod,"optin",()=>t.innerType._zod.optin),re(e._zod,"optout",()=>t.innerType._zod.optout),e._zod.parse=(A,n)=>{const i=t.innerType._zod.run(A,n);return i instanceof Promise?i.then(FC):FC(i)}});function FC(e){return e.value=Object.freeze(e.value),e}const HR=Z("$ZodCustom",(e,t)=>{NA.init(e,t),le.init(e,t),e._zod.parse=(A,n)=>A,e._zod.check=A=>{const n=A.value,i=t.fn(n);if(i instanceof Promise)return i.then(s=>SC(s,A,n,e));SC(i,A,n,e)}});function SC(e,t,A,n){if(!e){const i={code:"custom",input:A,inst:n,path:[...n._zod.def.path??[]],continue:!n._zod.def.abort};n._zod.def.params&&(i.params=n._zod.def.params),t.issues.push(rc(i))}}class OR{constructor(){this._map=new Map,this._idmap=new Map}add(t,...A){const n=A[0];if(this._map.set(t,n),n&&typeof n=="object"&&"id"in n){if(this._idmap.has(n.id))throw new Error(`ID ${n.id} already exists in the registry`);this._idmap.set(n.id,t)}return this}clear(){return this._map=new Map,this._idmap=new Map,this}remove(t){const A=this._map.get(t);return A&&typeof A=="object"&&"id"in A&&this._idmap.delete(A.id),this._map.delete(t),this}get(t){const A=t._zod.parent;if(A){const n={...this.get(A)??{}};delete n.id;const i={...n,...this._map.get(t)};return Object.keys(i).length?i:void 0}return this._map.get(t)}has(t){return this._map.has(t)}}function TR(){return new OR}const Yu=TR();function DR(e,t){return new e({type:"string",...mt(t)})}function MR(e,t){return new e({type:"string",format:"email",check:"string_format",abort:!1,...mt(t)})}function HC(e,t){return new e({type:"string",format:"guid",check:"string_format",abort:!1,...mt(t)})}function LR(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,...mt(t)})}function RR(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v4",...mt(t)})}function IR(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v6",...mt(t)})}function NR(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v7",...mt(t)})}function kR(e,t){return new e({type:"string",format:"url",check:"string_format",abort:!1,...mt(t)})}function KR(e,t){return new e({type:"string",format:"emoji",check:"string_format",abort:!1,...mt(t)})}function zR(e,t){return new e({type:"string",format:"nanoid",check:"string_format",abort:!1,...mt(t)})}function VR(e,t){return new e({type:"string",format:"cuid",check:"string_format",abort:!1,...mt(t)})}function PR(e,t){return new e({type:"string",format:"cuid2",check:"string_format",abort:!1,...mt(t)})}function jR(e,t){return new e({type:"string",format:"ulid",check:"string_format",abort:!1,...mt(t)})}function GR(e,t){return new e({type:"string",format:"xid",check:"string_format",abort:!1,...mt(t)})}function XR(e,t){return new e({type:"string",format:"ksuid",check:"string_format",abort:!1,...mt(t)})}function ZR(e,t){return new e({type:"string",format:"ipv4",check:"string_format",abort:!1,...mt(t)})}function YR(e,t){return new e({type:"string",format:"ipv6",check:"string_format",abort:!1,...mt(t)})}function WR(e,t){return new e({type:"string",format:"cidrv4",check:"string_format",abort:!1,...mt(t)})}function $R(e,t){return new e({type:"string",format:"cidrv6",check:"string_format",abort:!1,...mt(t)})}function JR(e,t){return new e({type:"string",format:"base64",check:"string_format",abort:!1,...mt(t)})}function qR(e,t){return new e({type:"string",format:"base64url",check:"string_format",abort:!1,...mt(t)})}function t2(e,t){return new e({type:"string",format:"e164",check:"string_format",abort:!1,...mt(t)})}function e2(e,t){return new e({type:"string",format:"jwt",check:"string_format",abort:!1,...mt(t)})}function A2(e,t){return new e({type:"string",format:"datetime",check:"string_format",offset:!1,local:!1,precision:null,...mt(t)})}function n2(e,t){return new e({type:"string",format:"date",check:"string_format",...mt(t)})}function i2(e,t){return new e({type:"string",format:"time",check:"string_format",precision:null,...mt(t)})}function r2(e,t){return new e({type:"string",format:"duration",check:"string_format",...mt(t)})}function s2(e,t){return new e({type:"number",checks:[],...mt(t)})}function a2(e,t){return new e({type:"number",check:"number_format",abort:!1,format:"safeint",...mt(t)})}function o2(e,t){return new e({type:"boolean",...mt(t)})}function l2(e){return new e({type:"any"})}function c2(e){return new e({type:"unknown"})}function u2(e,t){return new e({type:"never",...mt(t)})}function f2(e,t){return new e({type:"date",...mt(t)})}function OC(e,t){return new eE({check:"less_than",...mt(t),value:e,inclusive:!1})}function Zf(e,t){return new eE({check:"less_than",...mt(t),value:e,inclusive:!0})}function TC(e,t){return new AE({check:"greater_than",...mt(t),value:e,inclusive:!1})}function Yf(e,t){return new AE({check:"greater_than",...mt(t),value:e,inclusive:!0})}function DC(e,t){return new _4({check:"multiple_of",...mt(t),value:e})}function sE(e,t){return new Q4({check:"max_length",...mt(t),maximum:e})}function mh(e,t){return new U4({check:"min_length",...mt(t),minimum:e})}function aE(e,t){return new E4({check:"length_equals",...mt(t),length:e})}function h2(e,t){return new F4({check:"string_format",format:"regex",...mt(t),pattern:e})}function d2(e){return new S4({check:"string_format",format:"lowercase",...mt(e)})}function g2(e){return new H4({check:"string_format",format:"uppercase",...mt(e)})}function p2(e,t){return new O4({check:"string_format",format:"includes",...mt(t),includes:e})}function B2(e,t){return new T4({check:"string_format",format:"starts_with",...mt(t),prefix:e})}function m2(e,t){return new D4({check:"string_format",format:"ends_with",...mt(t),suffix:e})}function Uc(e){return new M4({check:"overwrite",tx:e})}function v2(e){return Uc(t=>t.normalize(e))}function w2(){return Uc(e=>e.trim())}function b2(){return Uc(e=>e.toLowerCase())}function y2(){return Uc(e=>e.toUpperCase())}function C2(e,t,A){return new e({type:"array",element:t,...mt(A)})}function _2(e,t,A){return new e({type:"custom",check:"custom",fn:t,...mt(A)})}function x2(e){const t=Q2(A=>(A.addIssue=n=>{if(typeof n=="string")A.issues.push(rc(n,A.value,t._zod.def));else{const i=n;i.fatal&&(i.continue=!1),i.code??(i.code="custom"),i.input??(i.input=A.value),i.inst??(i.inst=t),i.continue??(i.continue=!t._zod.def.abort),A.issues.push(rc(i))}},e(A.value,A)));return t}function Q2(e,t){const A=new NA({check:"custom",...mt(t)});return A._zod.check=e,A}const U2=Z("ZodISODateTime",(e,t)=>{Y4.init(e,t),Ce.init(e,t)});function E2(e){return A2(U2,e)}const F2=Z("ZodISODate",(e,t)=>{W4.init(e,t),Ce.init(e,t)});function S2(e){return n2(F2,e)}const H2=Z("ZodISOTime",(e,t)=>{$4.init(e,t),Ce.init(e,t)});function O2(e){return i2(H2,e)}const T2=Z("ZodISODuration",(e,t)=>{J4.init(e,t),Ce.init(e,t)});function D2(e){return r2(T2,e)}const M2=(e,t)=>{XU.init(e,t),e.name="ZodError",Object.defineProperties(e,{format:{value:A=>GL(e,A)},flatten:{value:A=>jL(e,A)},addIssue:{value:A=>{e.issues.push(A),e.message=JSON.stringify(e.issues,$B,2)}},addIssues:{value:A=>{e.issues.push(...A),e.message=JSON.stringify(e.issues,$B,2)}},isEmpty:{get(){return e.issues.length===0}}})},nd=Z("ZodError",M2,{Parent:Error}),L2=XL(nd),R2=ZL(nd),I2=YU(nd),N2=WU(nd),we=Z("ZodType",(e,t)=>(le.init(e,t),e.def=t,Object.defineProperty(e,"_def",{value:t}),e.check=(...A)=>e.clone({...t,checks:[...t.checks??[],...A.map(n=>typeof n=="function"?{_zod:{check:n,def:{check:"custom"},onattach:[]}}:n)]}),e.clone=(A,n)=>qs(e,A,n),e.brand=()=>e,e.register=(A,n)=>(A.add(e,n),e),e.parse=(A,n)=>L2(e,A,n,{callee:e.parse}),e.safeParse=(A,n)=>I2(e,A,n),e.parseAsync=async(A,n)=>R2(e,A,n,{callee:e.parseAsync}),e.safeParseAsync=async(A,n)=>N2(e,A,n),e.spa=e.safeParseAsync,e.refine=(A,n)=>e.check(TI(A,n)),e.superRefine=A=>e.check(DI(A)),e.overwrite=A=>e.check(Uc(A)),e.optional=()=>IC(e),e.nullable=()=>NC(e),e.nullish=()=>IC(NC(e)),e.nonoptional=A=>QI(e,A),e.array=()=>IA(e),e.or=A=>rd([e,A]),e.and=A=>BI(e,A),e.transform=A=>tm(e,uE(A)),e.default=A=>CI(e,A),e.prefault=A=>xI(e,A),e.catch=A=>EI(e,A),e.pipe=A=>tm(e,A),e.readonly=()=>HI(e),e.describe=A=>{const n=e.clone();return Yu.add(n,{description:A}),n},Object.defineProperty(e,"description",{get(){return Yu.get(e)?.description},configurable:!0}),e.meta=(...A)=>{if(A.length===0)return Yu.get(e);const n=e.clone();return Yu.add(n,A[0]),n},e.isOptional=()=>e.safeParse(void 0).success,e.isNullable=()=>e.safeParse(null).success,e)),oE=Z("_ZodString",(e,t)=>{sv.init(e,t),we.init(e,t);const A=e._zod.bag;e.format=A.format??null,e.minLength=A.minimum??null,e.maxLength=A.maximum??null,e.regex=(...n)=>e.check(h2(...n)),e.includes=(...n)=>e.check(p2(...n)),e.startsWith=(...n)=>e.check(B2(...n)),e.endsWith=(...n)=>e.check(m2(...n)),e.min=(...n)=>e.check(mh(...n)),e.max=(...n)=>e.check(sE(...n)),e.length=(...n)=>e.check(aE(...n)),e.nonempty=(...n)=>e.check(mh(1,...n)),e.lowercase=n=>e.check(d2(n)),e.uppercase=n=>e.check(g2(n)),e.trim=()=>e.check(w2()),e.normalize=(...n)=>e.check(v2(...n)),e.toLowerCase=()=>e.check(b2()),e.toUpperCase=()=>e.check(y2())}),k2=Z("ZodString",(e,t)=>{sv.init(e,t),oE.init(e,t),e.email=A=>e.check(MR(K2,A)),e.url=A=>e.check(kR(z2,A)),e.jwt=A=>e.check(e2(nI,A)),e.emoji=A=>e.check(KR(V2,A)),e.guid=A=>e.check(HC(MC,A)),e.uuid=A=>e.check(LR(Wu,A)),e.uuidv4=A=>e.check(RR(Wu,A)),e.uuidv6=A=>e.check(IR(Wu,A)),e.uuidv7=A=>e.check(NR(Wu,A)),e.nanoid=A=>e.check(zR(P2,A)),e.guid=A=>e.check(HC(MC,A)),e.cuid=A=>e.check(VR(j2,A)),e.cuid2=A=>e.check(PR(G2,A)),e.ulid=A=>e.check(jR(X2,A)),e.base64=A=>e.check(JR(tI,A)),e.base64url=A=>e.check(qR(eI,A)),e.xid=A=>e.check(GR(Z2,A)),e.ksuid=A=>e.check(XR(Y2,A)),e.ipv4=A=>e.check(ZR(W2,A)),e.ipv6=A=>e.check(YR($2,A)),e.cidrv4=A=>e.check(WR(J2,A)),e.cidrv6=A=>e.check($R(q2,A)),e.e164=A=>e.check(t2(AI,A)),e.datetime=A=>e.check(E2(A)),e.date=A=>e.check(S2(A)),e.time=A=>e.check(O2(A)),e.duration=A=>e.check(D2(A))});function gt(e){return DR(k2,e)}const Ce=Z("ZodStringFormat",(e,t)=>{ve.init(e,t),oE.init(e,t)}),K2=Z("ZodEmail",(e,t)=>{k4.init(e,t),Ce.init(e,t)}),MC=Z("ZodGUID",(e,t)=>{I4.init(e,t),Ce.init(e,t)}),Wu=Z("ZodUUID",(e,t)=>{N4.init(e,t),Ce.init(e,t)}),z2=Z("ZodURL",(e,t)=>{K4.init(e,t),Ce.init(e,t)}),V2=Z("ZodEmoji",(e,t)=>{z4.init(e,t),Ce.init(e,t)}),P2=Z("ZodNanoID",(e,t)=>{V4.init(e,t),Ce.init(e,t)}),j2=Z("ZodCUID",(e,t)=>{P4.init(e,t),Ce.init(e,t)}),G2=Z("ZodCUID2",(e,t)=>{j4.init(e,t),Ce.init(e,t)}),X2=Z("ZodULID",(e,t)=>{G4.init(e,t),Ce.init(e,t)}),Z2=Z("ZodXID",(e,t)=>{X4.init(e,t),Ce.init(e,t)}),Y2=Z("ZodKSUID",(e,t)=>{Z4.init(e,t),Ce.init(e,t)}),W2=Z("ZodIPv4",(e,t)=>{q4.init(e,t),Ce.init(e,t)}),$2=Z("ZodIPv6",(e,t)=>{tR.init(e,t),Ce.init(e,t)}),J2=Z("ZodCIDRv4",(e,t)=>{eR.init(e,t),Ce.init(e,t)}),q2=Z("ZodCIDRv6",(e,t)=>{AR.init(e,t),Ce.init(e,t)}),tI=Z("ZodBase64",(e,t)=>{nR.init(e,t),Ce.init(e,t)}),eI=Z("ZodBase64URL",(e,t)=>{rR.init(e,t),Ce.init(e,t)}),AI=Z("ZodE164",(e,t)=>{sR.init(e,t),Ce.init(e,t)}),nI=Z("ZodJWT",(e,t)=>{oR.init(e,t),Ce.init(e,t)}),lE=Z("ZodNumber",(e,t)=>{iE.init(e,t),we.init(e,t),e.gt=(n,i)=>e.check(TC(n,i)),e.gte=(n,i)=>e.check(Yf(n,i)),e.min=(n,i)=>e.check(Yf(n,i)),e.lt=(n,i)=>e.check(OC(n,i)),e.lte=(n,i)=>e.check(Zf(n,i)),e.max=(n,i)=>e.check(Zf(n,i)),e.int=n=>e.check(LC(n)),e.safe=n=>e.check(LC(n)),e.positive=n=>e.check(TC(0,n)),e.nonnegative=n=>e.check(Yf(0,n)),e.negative=n=>e.check(OC(0,n)),e.nonpositive=n=>e.check(Zf(0,n)),e.multipleOf=(n,i)=>e.check(DC(n,i)),e.step=(n,i)=>e.check(DC(n,i)),e.finite=()=>e;const A=e._zod.bag;e.minValue=Math.max(A.minimum??Number.NEGATIVE_INFINITY,A.exclusiveMinimum??Number.NEGATIVE_INFINITY)??null,e.maxValue=Math.min(A.maximum??Number.POSITIVE_INFINITY,A.exclusiveMaximum??Number.POSITIVE_INFINITY)??null,e.isInt=(A.format??"").includes("int")||Number.isSafeInteger(A.multipleOf??.5),e.isFinite=!0,e.format=A.format??null});function tA(e){return s2(lE,e)}const iI=Z("ZodNumberFormat",(e,t)=>{lR.init(e,t),lE.init(e,t)});function LC(e){return a2(iI,e)}const rI=Z("ZodBoolean",(e,t)=>{cR.init(e,t),we.init(e,t)});function id(e){return o2(rI,e)}const sI=Z("ZodAny",(e,t)=>{uR.init(e,t),we.init(e,t)});function wA(){return l2(sI)}const aI=Z("ZodUnknown",(e,t)=>{fR.init(e,t),we.init(e,t)});function RC(){return c2(aI)}const oI=Z("ZodNever",(e,t)=>{hR.init(e,t),we.init(e,t)});function lI(e){return u2(oI,e)}const cI=Z("ZodDate",(e,t)=>{dR.init(e,t),we.init(e,t),e.min=(n,i)=>e.check(Yf(n,i)),e.max=(n,i)=>e.check(Zf(n,i));const A=e._zod.bag;e.minDate=A.minimum?new Date(A.minimum):null,e.maxDate=A.maximum?new Date(A.maximum):null});function uI(e){return f2(cI,e)}const fI=Z("ZodArray",(e,t)=>{gR.init(e,t),we.init(e,t),e.element=t.element,e.min=(A,n)=>e.check(mh(A,n)),e.nonempty=A=>e.check(mh(1,A)),e.max=(A,n)=>e.check(sE(A,n)),e.length=(A,n)=>e.check(aE(A,n)),e.unwrap=()=>e.element});function IA(e,t){return C2(fI,e,t)}const hI=Z("ZodObject",(e,t)=>{pR.init(e,t),we.init(e,t),re(e,"shape",()=>t.shape),e.keyof=()=>av(Object.keys(e._zod.def.shape)),e.catchall=A=>e.clone({...e._zod.def,catchall:A}),e.passthrough=()=>e.clone({...e._zod.def,catchall:RC()}),e.loose=()=>e.clone({...e._zod.def,catchall:RC()}),e.strict=()=>e.clone({...e._zod.def,catchall:lI()}),e.strip=()=>e.clone({...e._zod.def,catchall:void 0}),e.extend=A=>KL(e,A),e.merge=A=>zL(e,A),e.pick=A=>NL(e,A),e.omit=A=>kL(e,A),e.partial=(...A)=>VL(fE,e,A[0]),e.required=(...A)=>PL(hE,e,A[0])});function fe(e,t){const A={type:"object",get shape(){return Js(this,"shape",{...e}),this.shape},...mt(t)};return new hI(A)}const cE=Z("ZodUnion",(e,t)=>{rE.init(e,t),we.init(e,t),e.options=t.options});function rd(e,t){return new cE({type:"union",options:e,...mt(t)})}const dI=Z("ZodDiscriminatedUnion",(e,t)=>{cE.init(e,t),BR.init(e,t)});function gI(e,t,A){return new dI({type:"union",options:t,discriminator:e,...mt(A)})}const pI=Z("ZodIntersection",(e,t)=>{mR.init(e,t),we.init(e,t)});function BI(e,t){return new pI({type:"intersection",left:e,right:t})}const mI=Z("ZodRecord",(e,t)=>{vR.init(e,t),we.init(e,t),e.keyType=t.keyType,e.valueType=t.valueType});function aA(e,t,A){return new mI({type:"record",keyType:e,valueType:t,...mt(A)})}const qB=Z("ZodEnum",(e,t)=>{wR.init(e,t),we.init(e,t),e.enum=t.entries,e.options=Object.values(t.entries);const A=new Set(Object.keys(t.entries));e.extract=(n,i)=>{const s={};for(const o of n)if(A.has(o))s[o]=t.entries[o];else throw new Error(`Key ${o} not found in enum`);return new qB({...t,checks:[],...mt(i),entries:s})},e.exclude=(n,i)=>{const s={...t.entries};for(const o of n)if(A.has(o))delete s[o];else throw new Error(`Key ${o} not found in enum`);return new qB({...t,checks:[],...mt(i),entries:s})}});function av(e,t){const A=Array.isArray(e)?Object.fromEntries(e.map(n=>[n,n])):e;return new qB({type:"enum",entries:A,...mt(t)})}const vI=Z("ZodLiteral",(e,t)=>{bR.init(e,t),we.init(e,t),e.values=new Set(t.values),Object.defineProperty(e,"value",{get(){if(t.values.length>1)throw new Error("This schema contains multiple valid literal values. Use `.values` instead.");return t.values[0]}})});function Ec(e,t){return new vI({type:"literal",values:Array.isArray(e)?e:[e],...mt(t)})}const wI=Z("ZodTransform",(e,t)=>{yR.init(e,t),we.init(e,t),e._zod.parse=(A,n)=>{A.addIssue=s=>{if(typeof s=="string")A.issues.push(rc(s,A.value,t));else{const o=s;o.fatal&&(o.continue=!1),o.code??(o.code="custom"),o.input??(o.input=A.value),o.inst??(o.inst=e),A.issues.push(rc(o))}};const i=t.transform(A.value,A);return i instanceof Promise?i.then(s=>(A.value=s,A)):(A.value=i,A)}});function uE(e){return new wI({type:"transform",transform:e})}const fE=Z("ZodOptional",(e,t)=>{CR.init(e,t),we.init(e,t),e.unwrap=()=>e._zod.def.innerType});function IC(e){return new fE({type:"optional",innerType:e})}const bI=Z("ZodNullable",(e,t)=>{_R.init(e,t),we.init(e,t),e.unwrap=()=>e._zod.def.innerType});function NC(e){return new bI({type:"nullable",innerType:e})}const yI=Z("ZodDefault",(e,t)=>{xR.init(e,t),we.init(e,t),e.unwrap=()=>e._zod.def.innerType,e.removeDefault=e.unwrap});function CI(e,t){return new yI({type:"default",innerType:e,get defaultValue(){return typeof t=="function"?t():t}})}const _I=Z("ZodPrefault",(e,t)=>{QR.init(e,t),we.init(e,t),e.unwrap=()=>e._zod.def.innerType});function xI(e,t){return new _I({type:"prefault",innerType:e,get defaultValue(){return typeof t=="function"?t():t}})}const hE=Z("ZodNonOptional",(e,t)=>{UR.init(e,t),we.init(e,t),e.unwrap=()=>e._zod.def.innerType});function QI(e,t){return new hE({type:"nonoptional",innerType:e,...mt(t)})}const UI=Z("ZodCatch",(e,t)=>{ER.init(e,t),we.init(e,t),e.unwrap=()=>e._zod.def.innerType,e.removeCatch=e.unwrap});function EI(e,t){return new UI({type:"catch",innerType:e,catchValue:typeof t=="function"?t:()=>t})}const FI=Z("ZodPipe",(e,t)=>{FR.init(e,t),we.init(e,t),e.in=t.in,e.out=t.out});function tm(e,t){return new FI({type:"pipe",in:e,out:t})}const SI=Z("ZodReadonly",(e,t)=>{SR.init(e,t),we.init(e,t),e.unwrap=()=>e._zod.def.innerType});function HI(e){return new SI({type:"readonly",innerType:e})}const OI=Z("ZodCustom",(e,t)=>{HR.init(e,t),we.init(e,t)});function TI(e,t={}){return _2(OI,e,t)}function DI(e){return x2(e)}function MI(e,t){return tm(uE(e),t)}const LI=fe({text:gt().describe("The text content."),type:Ec("text").default("text").describe("The type of the content part.")}),dE=fe({name:gt(),arguments:gt()}),RI=fe({id:gt(),type:Ec("function"),function:dE}),II=fe({role:gt().describe("assistant, user, system, tool"),content:rd([gt(),IA(LI)]).optional().default("").describe("The content of the message."),name:gt().optional(),tool_call_id:gt().optional(),tool_calls:IA(RI).optional(),function_call:dE.optional(),control_plane_step:aA(gt(),wA()).optional()}),NI=fe({is_score_valid:id().default(!0),score:tA().min(0).max(1),reason:gt()}),kI=fe({step_index:rd([tA(),gt()]).describe("User-defined index for the step (e.g., assistant message index, turn number). This is used by the system to map this output to the internal StepData."),base_reward:tA().describe("Base reward calculated by the user's reward function for this step."),terminated:id().default(!1).describe("Whether the environment signaled termination at this step."),control_plane_info:aA(gt(),wA()).optional().describe("Structured info from the environment's control plane."),metrics:aA(gt(),wA()).default({}).describe("Optional dictionary of custom metrics for this step."),reason:gt().optional().describe("Optional explanation for the step's base reward or metrics.")}),KI=fe({score:tA().describe("The overall evaluation score, typically between 0.0 and 1.0."),is_score_valid:id().default(!0).describe("Whether the overall score is valid."),reason:gt().optional().describe("Optional explanation for the overall score."),metrics:aA(gt(),NI).default({}).describe("Dictionary of component metrics for detailed breakdown."),step_outputs:IA(kI).optional().describe("For RL, a list of outputs for each conceptual step, providing base rewards."),error:gt().optional().describe("Optional error message if the evaluation itself encountered an issue."),trajectory_info:aA(gt(),wA()).optional().describe("Additional trajectory-level information (duration, steps, termination_reason, etc.)."),final_control_plane_info:aA(gt(),wA()).optional().describe("The final control plane state that led to termination."),agg_score:tA().optional().describe("The aggregated score of the evaluation across all runs."),standard_error:tA().optional().describe("The standard error of the evaluation across all runs.")}),zI=aA(gt(),wA());fe({reason:gt().describe("Short snake_case description of the error cause"),domain:gt().describe("Logical grouping for the error reason"),metadata:aA(gt(),wA()).default({}).describe("Additional dynamic information as context")});av(["OK","CANCELLED","UNKNOWN","INVALID_ARGUMENT","DEADLINE_EXCEEDED","NOT_FOUND","ALREADY_EXISTS","PERMISSION_DENIED","RESOURCE_EXHAUSTED","FAILED_PRECONDITION","ABORTED","OUT_OF_RANGE","UNIMPLEMENTED","INTERNAL","UNAVAILABLE","DATA_LOSS","UNAUTHENTICATED","FINISHED","RUNNING"]).describe("Common gRPC status codes as defined in google.rpc.Code");const VI={0:"OK",1:"CANCELLED",2:"UNKNOWN",3:"INVALID_ARGUMENT",4:"DEADLINE_EXCEEDED",5:"NOT_FOUND",6:"ALREADY_EXISTS",7:"PERMISSION_DENIED",8:"RESOURCE_EXHAUSTED",9:"FAILED_PRECONDITION",10:"ABORTED",11:"OUT_OF_RANGE",12:"UNIMPLEMENTED",13:"INTERNAL",14:"UNAVAILABLE",15:"DATA_LOSS",16:"UNAUTHENTICATED",100:"FINISHED",101:"RUNNING"},PI=e=>VI[e]||"UNKNOWN",gE=fe({code:tA().describe("The status code (numeric value from google.rpc.Code enum)"),message:gt().describe("Developer-facing, human-readable debug message in English"),details:IA(aA(gt(),wA())).default([]).describe("Additional error information, each packed in a google.protobuf.Any message format")}),jI=fe({success:tA().min(0).max(1).describe("Minimum success rate threshold (fraction of total score, 0.0 to 1.0)"),standard_error:tA().min(0).max(1).optional().describe("Maximum standard error threshold (fraction of total score, 0.0 to 1.0)")}),GI=fe({row_id:gt().optional().describe("Unique string to ID the row. If not provided, a stable hash will be generated based on the row's content. The hash removes fields that are not typically stable across processes such as created_at, execution_metadata, and pid."),completion_params:zI.describe("Completion endpoint parameters used"),dataset_info:aA(gt(),wA()).optional().describe("Dataset row details: seed, system_prompt, environment_context, etc"),session_data:aA(gt(),wA()).optional().describe("Session metadata like timestamp (input only, no duration/usage)")}).loose(),XI=fe({prompt_tokens:tA(),completion_tokens:tA(),total_tokens:tA()}),ZI=fe({name:gt().describe("Name of the evaluation"),description:gt().optional().describe("Description of the evaluation"),version:gt().describe("Version of the evaluation. Should be populated with a PEP 440 version string."),status:gE.optional().describe("Status of the evaluation"),num_runs:tA().int().describe("Number of times the evaluation was repeated"),aggregation_method:gt().describe("Method used to aggregate scores across runs"),passed_threshold:jI.optional().describe("Threshold configuration for test success"),passed:id().optional().describe("Whether the evaluation passed based on the threshold")}),YI=fe({invocation_id:gt().optional().describe("The ID of the invocation that this row belongs to."),experiment_id:gt().optional().describe("The ID of the experiment that this row belongs to."),rollout_id:gt().optional().describe("The ID of the rollout that this row belongs to."),run_id:gt().optional().describe("The ID of the run that this row belongs to.")}),em=fe({messages:IA(II).describe("List of messages in the conversation/trajectory."),tools:IA(aA(gt(),wA())).optional().describe("Available tools/functions that were provided to the agent."),input_metadata:GI.describe("Metadata related to the input (dataset info, model config, session data, etc.)."),rollout_status:gE.describe("The status of the rollout following AIP-193 standards."),execution_metadata:YI.optional().describe("Metadata about the execution of the evaluation."),ground_truth:gt().optional().describe("Optional ground truth reference for this evaluation."),evaluation_result:KI.optional().describe("The evaluation result for this row/trajectory."),usage:XI.optional().describe("Token usage statistics from LLM calls during execution."),created_at:MI(e=>typeof e=="string"?new Date(e):e,uI()).describe("The timestamp when the row was created. Accepts string and parses to Date."),eval_metadata:ZI.optional().describe("Metadata about the evaluation that was run."),pid:tA().optional().describe("The PID of the process that created the row. This is used by the evaluation watcher to detect stopped evaluations.")}),WI=fe({start_command:gt().describe("The command to start the server. The string '{port}' will be replaced with a dynamically allocated free port."),health_check_url:gt().describe("The URL to poll to check if the server is ready. The string '{port}' will be replaced with the allocated port.")}),$I=fe({final_state_query:gt().optional().describe("A query (e.g., SQL) to run on the final state of the resource."),expected_query_result_transform:gt().optional().describe("A Python lambda string (e.g., 'lambda x: x > 0') to transform and evaluate the query result to a boolean."),ground_truth_function_calls:IA(IA(gt())).optional().describe("Ground truth function calls for BFCL evaluation."),ground_truth_comparable_state:aA(gt(),wA()).optional().describe("Ground truth comparable state for BFCL evaluation.")});fe({name:gt().describe("Unique name for the task."),description:gt().optional().describe("A brief description of the task."),resource_type:gt().describe("The type of ForkableResource to use (e.g., 'SQLResource', 'PythonStateResource', 'FileSystemResource', 'DockerResource')."),base_resource_config:aA(gt(),wA()).default({}).describe("Configuration dictionary passed to the base resource's setup() method."),tools_module_path:gt().optional().describe("Optional Python import path to a module containing custom tool functions for this task."),reward_function_path:gt().describe("Python import path to the reward function (e.g., 'my_module.my_reward_func')."),goal_description:gt().optional().describe("A human-readable description of the agent's goal for this task."),evaluation_criteria:$I.optional().describe("Criteria used by the Orchestrator to determine if the primary goal was achieved."),initial_user_prompt:gt().optional().describe("The initial prompt or message to start the agent interaction. Deprecated if 'messages' field is used for multi-turn."),messages:IA(aA(gt(),wA())).optional().describe("A list of messages to start the conversation, can represent multiple user turns for sequential processing."),poc_max_turns:tA().int().min(1).default(3).describe("For PoC Orchestrator, the maximum number of interaction turns."),resource_server:WI.optional().describe("Configuration for a background server required for the task."),num_rollouts:tA().int().min(1).default(1).describe("Number of parallel rollouts to execute for this task definition."),dataset_path:gt().optional().describe("Path to dataset file (JSONL) containing experimental conditions for data-driven evaluation."),num_rollouts_per_sample:tA().int().min(1).default(1).describe("Number of rollouts to execute per sample from the dataset.")}).loose();const JI=fe({command:gt().describe("command to run the MCP server"),args:IA(gt()).default([]).describe("to pass to the command"),env:IA(gt()).default([]).describe("List of environment variables to verify exist in the environment")}),qI=fe({url:gt().describe("url to the MCP server")});fe({mcpServers:aA(gt(),rd([JI,qI]))});const tN=({color:e})=>Q.jsx("div",{className:`animate-spin w-1.5 h-1.5 rounded-full border border-current ${e} border-t-transparent`}),pE=({status:e,className:t="",showSpinner:A=!1})=>{const i=(o=>{switch(PI(o.code)){case"OK":return{dotColor:"bg-green-500",textColor:"text-green-700",text:"Connected"};case"CANCELLED":return{dotColor:"bg-red-500",textColor:"text-red-700",text:"Disconnected"};case"FINISHED":return{dotColor:"bg-green-500",textColor:"text-green-700",text:"finished"};case"RUNNING":return{dotColor:"bg-blue-500",textColor:"text-blue-700",text:"running"};case"INTERNAL":return{dotColor:"bg-red-500",textColor:"text-red-700",text:"error"};case"ABORTED":return{dotColor:"bg-yellow-500",textColor:"text-yellow-700",text:"stopped"};default:return{dotColor:"bg-gray-500",textColor:"text-gray-700",text:o.message}}})(e),s=A&&e.code===101;return Q.jsxs("div",{className:`inline-flex items-center gap-1.5 text-xs font-medium ${i.textColor} ${t}`,children:[s?Q.jsx(tN,{color:i.textColor}):Q.jsx("div",{className:`w-1.5 h-1.5 rounded-full ${i.dotColor}`}),i.text]})};function eN({children:e,className:t=""}){return Q.jsx("div",{className:`bg-white border border-gray-200 overflow-x-auto ${t}`,children:e})}function BE({children:e,className:t=""}){return Q.jsx("thead",{className:`bg-gray-50 border-b border-gray-200 ${t}`,children:e})}function mE({children:e,className:t=""}){return Q.jsx("tbody",{className:`divide-y divide-gray-200 ${t}`,children:e})}function Wf({children:e,className:t="",align:A="left",nowrap:n=!1}){const i={left:"text-left",center:"text-center",right:"text-right"};return Q.jsx("th",{className:`px-3 py-2 text-xs font-semibold text-gray-700 ${i[A]} ${n?"whitespace-nowrap":""} ${t}`,children:e})}function Hn({children:e,className:t="",align:A="left",nowrap:n=!1,sortField:i,currentSortField:s,currentSortDirection:o,onSort:c}){const u={left:"text-left",center:"text-center",right:"text-right"},d=s===i?o==="asc"?Q.jsx("svg",{className:"w-3 h-3 ml-1",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:Q.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 15l7-7 7 7"})}):Q.jsx("svg",{className:"w-3 h-3 ml-1",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:Q.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})}):Q.jsx("svg",{className:"w-3 h-3 ml-1 text-gray-400",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:Q.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4"})});return Q.jsx("th",{className:`px-3 py-2 text-xs font-semibold text-gray-700 cursor-pointer hover:bg-gray-100 transition-colors ${u[A]} ${n?"whitespace-nowrap":""} ${t}`,onClick:()=>c(i),style:{cursor:"pointer"},children:Q.jsxs("div",{className:"flex items-center",children:[e,d]})})}function kC({children:e,className:t="",gray:A=!1}){return Q.jsx("tr",{className:`${A?"bg-gray-50":""} ${t}`,children:e})}function AN({children:e,className:t="",onClick:A,interactive:n=!0}){const i=n?"hover:bg-gray-50 cursor-pointer":"";return Q.jsx("tr",{className:`text-sm ${i} ${t}`,onClick:A,children:e})}function We({children:e,className:t="",align:A="left",nowrap:n=!1,medium:i=!1,semibold:s=!1,colSpan:o}){const c={left:"text-left",center:"text-center",right:"text-right"},u=[];return i&&u.push("font-medium"),s&&u.push("font-semibold"),Q.jsx("td",{colSpan:o,className:`px-3 py-2 text-gray-900 ${c[A]} ${n?"whitespace-nowrap":""} ${u.join(" ")} ${t}`,children:e})}const nN=({children:e,data:t,position:A="top",className:n=""})=>{const i=`json-tooltip-${Math.random().toString(36).substr(2,9)}`,s=JSON.stringify(t,null,2);return Q.jsxs(Q.Fragment,{children:[Q.jsx("div",{"data-tooltip-id":i,className:`cursor-help ${n}`,children:e}),Q.jsx(zU,{id:i,place:A,className:"px-2 py-1 text-xs text-white bg-gray-800 rounded z-10 max-w-md",style:{fontSize:"0.75rem",lineHeight:"1rem",backgroundColor:"#1f2937",color:"white",borderRadius:"0.25rem",padding:"0.5rem",zIndex:10,userSelect:"text",pointerEvents:"auto"},delayShow:200,delayHide:300,clickable:!0,noArrow:!0,render:()=>Q.jsx("pre",{className:"whitespace-pre-wrap text-left text-xs",style:{userSelect:"text",pointerEvents:"auto",cursor:"text"},onMouseDown:o=>o.stopPropagation(),onClick:o=>o.stopPropagation(),onDoubleClick:o=>o.stopPropagation(),onContextMenu:o=>o.stopPropagation(),children:s})})]})},iN=Ae(({fieldPath:e,value:t,label:A})=>{const[n,i]=S.useState(!1),s=o=>{o.stopPropagation();const c={field:e,operator:"==",value:t,type:"text"},u=rt.filterConfig;let h;u.length===0?h=[{logic:"AND",filters:[c]}]:(h=[...u],h[0]={...h[0],filters:[...h[0].filters,c]}),rt.updateFilterConfig(h),i(!0),setTimeout(()=>i(!1),2e3)};return Q.jsx(VU,{content:n?"Filter Added!":`Add ${A} Filter`,position:"top",className:"text-gray-400 hover:text-gray-600 transition-colors",children:Q.jsx("div",{className:"flex items-center gap-1",children:Q.jsx("button",{className:"cursor-pointer",onClick:s,title:"Add filter for this value",children:n?Q.jsx("svg",{className:"w-3 h-3 text-green-600",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:Q.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 13l4 4L19 7"})}):Q.jsx("svg",{className:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:Q.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.207A1 1 0 013 6.5V4z"})})})})})}),rN=Ae(({rolloutId:e})=>{if(!e)throw new Error("Rollout ID is required");const t=rt.isRowExpanded(e);return Q.jsx("div",{className:"w-4 h-4 flex items-center justify-center",children:Q.jsx("svg",{className:`h-4 w-4 text-gray-500 transition-transform duration-200 ${t?"rotate-90":""}`,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:Q.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})})}),sN=Ae(({name:e})=>Q.jsx("span",{className:"text-gray-900 truncate block",children:e||"N/A"})),KC=Ae(({status:e,showSpinner:t})=>Q.jsx("div",{className:"whitespace-nowrap",children:Q.jsx(pE,{showSpinner:t,status:e||{code:2,message:"N/A",details:[]}})})),aN=Ae(({experimentId:e})=>e?Q.jsx("span",{className:"font-mono text-gray-900 whitespace-nowrap",children:e}):null),oN=Ae(({runId:e})=>e?Q.jsx("span",{className:"font-mono text-gray-900 whitespace-nowrap",children:e}):null),lN=Ae(({rowId:e})=>e?Q.jsx("span",{className:"font-mono text-gray-900 whitespace-nowrap",children:e}):null),cN=Ae(({rolloutId:e})=>e?Q.jsx("span",{className:"font-mono text-gray-900 whitespace-nowrap",children:e}):null),uN=Ae(({invocationId:e})=>e?Q.jsxs("span",{className:"font-mono text-gray-900 whitespace-nowrap flex items-center gap-1",children:[e,Q.jsx(iN,{fieldPath:"$.execution_metadata.invocation_id",value:e,label:"Invocation"})]}):null),fN=Ae(({model:e})=>{const t=e?typeof e=="string"?e:JSON.stringify(e):"N/A";return typeof e=="string"||!e?Q.jsx("span",{className:"text-gray-900 block",children:t}):Q.jsx(nN,{data:e,children:Q.jsx("span",{className:"text-gray-900 truncate block max-w-[200px] cursor-help",children:t})})}),hN=Ae(({score:e})=>{const t=e?e>=.8?"text-green-700":e>=.6?"text-yellow-700":"text-red-700":"text-gray-500";return Q.jsx("span",{className:`font-mono whitespace-nowrap ${t}`,children:e?.toFixed(3)||"N/A"})}),dN=Ae(({created_at:e})=>{const t=e instanceof Date?e:new Date(e);return Q.jsx("span",{className:"text-gray-600 whitespace-nowrap",children:t.toLocaleDateString()+" "+t.toLocaleTimeString()})}),gN=Ae(({data:e})=>Q.jsx(Jr,{title:"Eval Metadata",data:e,defaultExpanded:!0})),pN=Ae(({data:e})=>Q.jsx(Jr,{title:"Rollout Status",data:e,defaultExpanded:!0})),BN=Ae(({data:e})=>Q.jsx(Jr,{title:"Evaluation Result",data:e,defaultExpanded:!0})),mN=Ae(({data:e})=>Q.jsx(Jr,{title:"Ground Truth",data:e})),vN=Ae(({data:e})=>Q.jsx(Jr,{title:"Usage Stats",data:e})),wN=Ae(({data:e})=>Q.jsx(Jr,{title:"Input Metadata",data:e})),bN=Ae(({data:e})=>Q.jsx(Jr,{title:"IDs",data:{rollout_id:e.execution_metadata?.rollout_id,experiment_id:e.execution_metadata?.experiment_id,invocation_id:e.execution_metadata?.invocation_id,run_id:e.execution_metadata?.run_id}})),yN=Ae(({data:e})=>Q.jsx(Jr,{title:"Tools",data:e})),CN=Ae(({messages:e})=>Q.jsx(OL,{messages:e})),_N=Ae(({row:e,messages:t,eval_metadata:A,evaluation_result:n,ground_truth:i,usage:s,input_metadata:o,tools:c,rollout_status:u})=>Q.jsx("div",{className:"p-4 bg-gray-50",children:Q.jsxs("div",{className:"flex gap-3 w-fit",children:[Q.jsx("div",{className:"min-w-0",children:Q.jsx(CN,{messages:t})}),Q.jsxs("div",{className:"w-[500px] flex-shrink-0 space-y-3",children:[Q.jsx(gN,{data:A}),Q.jsx(BN,{data:n}),Q.jsx(pN,{data:u}),Q.jsx(bN,{data:e}),Q.jsx(mN,{data:i}),Q.jsx(vN,{data:s}),Q.jsx(wN,{data:o}),Q.jsx(yN,{data:c})]})]})})),xN=Ae(({row:e})=>{const t=e.execution_metadata?.rollout_id,A=rt.isRowExpanded(t),n=()=>rt.toggleRowExpansion(t);return Q.jsxs(Q.Fragment,{children:[Q.jsxs(AN,{onClick:n,children:[Q.jsx(We,{className:"w-8 py-3",children:Q.jsx(rN,{rolloutId:t})}),Q.jsx(We,{className:"py-3 text-xs",children:Q.jsx(sN,{name:e.eval_metadata?.name})}),Q.jsx(We,{className:"py-3 text-xs",children:Q.jsx(KC,{status:e.eval_metadata?.status,showSpinner:e.eval_metadata?.status?.code===101})}),Q.jsx(We,{className:"py-3 text-xs",children:Q.jsx(KC,{status:e.rollout_status,showSpinner:e.rollout_status?.code===101})}),Q.jsx(We,{className:"py-3 text-xs",children:Q.jsx(uN,{invocationId:e.execution_metadata?.invocation_id})}),Q.jsx(We,{className:"py-3 text-xs",children:Q.jsx(aN,{experimentId:e.execution_metadata?.experiment_id})}),Q.jsx(We,{className:"py-3 text-xs",children:Q.jsx(oN,{runId:e.execution_metadata?.run_id})}),Q.jsx(We,{className:"py-3 text-xs",children:Q.jsx(lN,{rowId:e.input_metadata?.row_id})}),Q.jsx(We,{className:"py-3 text-xs",children:Q.jsx(cN,{rolloutId:e.execution_metadata?.rollout_id})}),Q.jsx(We,{className:"py-3 text-xs",children:Q.jsx(fN,{model:e.input_metadata.completion_params.model})}),Q.jsx(We,{className:"py-3 text-xs",children:Q.jsx(hN,{score:e.evaluation_result?.score})}),Q.jsx(We,{className:"py-3 text-xs",children:Q.jsx(dN,{created_at:e.created_at})})]}),A&&Q.jsx("tr",{children:Q.jsx("td",{colSpan:9,className:"p-0",children:Q.jsx(_N,{row:e,messages:e.messages,eval_metadata:e.eval_metadata,evaluation_result:e.evaluation_result,ground_truth:e.ground_truth,usage:e.usage,input_metadata:e.input_metadata,tools:e.tools,rollout_status:e.rollout_status})})})]})}),ov=mA.forwardRef(({className:e="",size:t="sm",children:A,...n},i)=>Q.jsx("select",{ref:i,className:`${te.input.base} ${te.input.size[t]} ${e}`,style:{boxShadow:te.input.shadow},...n,children:A}));ov.displayName="Select";const Ds=mA.forwardRef(({options:e,value:t,onChange:A,placeholder:n="Select...",size:i="sm",className:s="",disabled:o=!1},c)=>{const[u,h]=S.useState(!1),[d,p]=S.useState(""),m=S.useMemo(()=>{const Y=d.toLowerCase();return Y?e.filter(ut=>ut.label.toLowerCase().includes(Y)||ut.value.toLowerCase().includes(Y)):e},[d,e]),[v,w]=S.useState("left"),[b,_]=S.useState(void 0),[C,U]=S.useState(-1),E=S.useRef(null),H=S.useRef(null);S.useEffect(()=>{U(-1)},[d,e]),S.useEffect(()=>{const Y=ut=>{E.current&&!E.current.contains(ut.target)&&(h(!1),p(""))};return document.addEventListener("mousedown",Y),()=>document.removeEventListener("mousedown",Y)},[]);const F=Y=>{A(Y),h(!1),p(""),U(-1)},D=Y=>{if(u)switch(Y.key){case"ArrowDown":Y.preventDefault(),U(ut=>utut>0?ut-1:m.length-1);break;case"Enter":Y.preventDefault(),C>=0&&m[C]&&F(m[C].value);break;case"Escape":h(!1),p(""),U(-1);break}},R=()=>{if(!E.current)return{side:"left",width:240};const Y=E.current.getBoundingClientRect(),ut=window.innerWidth,lt=16,Yt=Math.min(Y.width+240,600),An=ut-Y.left-lt,Pe=Y.right-lt,eA=Math.max(Y.width,Math.min(Yt,An)),EA=Math.max(Y.width,Math.min(Yt,Pe));if(eA>=EA&&eA>=Y.width)return{side:"left",width:eA};if(EA>eA&&EA>=Y.width)return{side:"right",width:EA};const FA=Math.max(Y.width,Math.min(Yt,ut-lt*2));return{side:Y.left{if(!o){if(!u){const Y=R();w(Y.side),_(Y.width)}h(!u),u||setTimeout(()=>H.current?.focus(),0)}},N=S.useMemo(()=>e.find(Y=>Y.value===t),[e,t]),J=S.useRef(null),[et,nt]=S.useState(0),[ot,ft]=S.useState(192),st=32,L=5,G=m.length,q=Math.max(1,Math.ceil(ot/st)),ct=Math.max(0,Math.floor(et/st)-L),T=Math.min(G,ct+q+L*2),j=ct*st,At=Math.max(0,(G-T)*st);S.useLayoutEffect(()=>{if(!u)return;const Y=J.current;if(!Y)return;const ut=()=>{ft(Y.clientHeight||192)};ut();const lt=new ResizeObserver(ut);return lt.observe(Y),()=>lt.disconnect()},[u]),S.useEffect(()=>{u&&J.current&&(J.current.scrollTop=0,nt(0))},[u,d]);const tt=Y=>{nt(Y.target.scrollTop)};return Q.jsxs("div",{ref:E,className:`relative ${s}`,children:[Q.jsxs("div",{ref:c,onClick:z,onKeyDown:Y=>{(Y.key==="Enter"||Y.key===" ")&&(Y.preventDefault(),z())},tabIndex:0,role:"combobox","aria-expanded":u,"aria-haspopup":"listbox",className:` ${te.input.base} ${te.input.size[i]} cursor-pointer flex items-center justify-between @@ -133,4 +133,4 @@ PERFORMANCE OF THIS SOFTWARE. display: none !important; }`,j6=function(e){G6(e,"."+Tm+V6+lQ+` .`+Dm+P6+lQ)},G6=function(e,t){var A=e.ownerDocument;if(A){var n=A.createElement("style");n.textContent=t,e.appendChild(n)}},vS=function(){function e(){}return e.getOrigin=function(t){var A=e._link;return A?(A.href=t,A.href=A.href,A.protocol+A.hostname+A.port):"about:blank"},e.isSameOrigin=function(t){return e.getOrigin(t)===e._origin},e.setContext=function(t){e._link=t.document.createElement("a"),e._origin=e.getOrigin(t.location.href)},e._origin="about:blank",e}(),X6=function(){function e(t,A){this.context=t,this._options=A,this._cache={}}return e.prototype.addImage=function(t){var A=Promise.resolve();return this.has(t)||(EB(t)||$6(t))&&(this._cache[t]=this.loadImage(t)).catch(function(){}),A},e.prototype.match=function(t){return this._cache[t]},e.prototype.loadImage=function(t){return UA(this,void 0,void 0,function(){var A,n,i,s,o=this;return dA(this,function(c){switch(c.label){case 0:return A=vS.isSameOrigin(t),n=!UB(t)&&this._options.useCORS===!0&&rA.SUPPORT_CORS_IMAGES&&!A,i=!UB(t)&&!A&&!EB(t)&&typeof this._options.proxy=="string"&&rA.SUPPORT_CORS_XHR&&!n,!A&&this._options.allowTaint===!1&&!UB(t)&&!EB(t)&&!i&&!n?[2]:(s=t,i?[4,this.proxy(s)]:[3,2]);case 1:s=c.sent(),c.label=2;case 2:return this.context.logger.debug("Added image "+t.substring(0,256)),[4,new Promise(function(u,h){var d=new Image;d.onload=function(){return u(d)},d.onerror=h,(J6(s)||n)&&(d.crossOrigin="anonymous"),d.src=s,d.complete===!0&&setTimeout(function(){return u(d)},500),o._options.imageTimeout>0&&setTimeout(function(){return h("Timed out ("+o._options.imageTimeout+"ms) loading image")},o._options.imageTimeout)})];case 3:return[2,c.sent()]}})})},e.prototype.has=function(t){return typeof this._cache[t]<"u"},e.prototype.keys=function(){return Promise.resolve(Object.keys(this._cache))},e.prototype.proxy=function(t){var A=this,n=this._options.proxy;if(!n)throw new Error("No proxy defined");var i=t.substring(0,256);return new Promise(function(s,o){var c=rA.SUPPORT_RESPONSE_TYPE?"blob":"text",u=new XMLHttpRequest;u.onload=function(){if(u.status===200)if(c==="text")s(u.response);else{var p=new FileReader;p.addEventListener("load",function(){return s(p.result)},!1),p.addEventListener("error",function(m){return o(m)},!1),p.readAsDataURL(u.response)}else o("Failed to proxy resource "+i+" with status code "+u.status)},u.onerror=o;var h=n.indexOf("?")>-1?"&":"?";if(u.open("GET",""+n+h+"url="+encodeURIComponent(t)+"&responseType="+c),c!=="text"&&u instanceof XMLHttpRequest&&(u.responseType=c),A._options.imageTimeout){var d=A._options.imageTimeout;u.timeout=d,u.ontimeout=function(){return o("Timed out ("+d+"ms) proxying "+i)}}u.send()})},e}(),Z6=/^data:image\/svg\+xml/i,Y6=/^data:image\/.*;base64,/i,W6=/^data:image\/.*/i,$6=function(e){return rA.SUPPORT_SVG_DRAWING||!q6(e)},UB=function(e){return W6.test(e)},J6=function(e){return Y6.test(e)},EB=function(e){return e.substr(0,4)==="blob"},q6=function(e){return e.substr(-3).toLowerCase()==="svg"||Z6.test(e)},ht=function(){function e(t,A){this.type=0,this.x=t,this.y=A}return e.prototype.add=function(t,A){return new e(this.x+t,this.y+A)},e}(),Xa=function(e,t,A){return new ht(e.x+(t.x-e.x)*A,e.y+(t.y-e.y)*A)},Df=function(){function e(t,A,n,i){this.type=1,this.start=t,this.startControl=A,this.endControl=n,this.end=i}return e.prototype.subdivide=function(t,A){var n=Xa(this.start,this.startControl,t),i=Xa(this.startControl,this.endControl,t),s=Xa(this.endControl,this.end,t),o=Xa(n,i,t),c=Xa(i,s,t),u=Xa(o,c,t);return A?new e(this.start,n,o,u):new e(u,c,s,this.end)},e.prototype.add=function(t,A){return new e(this.start.add(t,A),this.startControl.add(t,A),this.endControl.add(t,A),this.end.add(t,A))},e.prototype.reverse=function(){return new e(this.end,this.endControl,this.startControl,this.start)},e}(),bn=function(e){return e.type===1},t8=function(){function e(t){var A=t.styles,n=t.bounds,i=Rl(A.borderTopLeftRadius,n.width,n.height),s=i[0],o=i[1],c=Rl(A.borderTopRightRadius,n.width,n.height),u=c[0],h=c[1],d=Rl(A.borderBottomRightRadius,n.width,n.height),p=d[0],m=d[1],v=Rl(A.borderBottomLeftRadius,n.width,n.height),w=v[0],b=v[1],_=[];_.push((s+u)/n.width),_.push((w+p)/n.width),_.push((o+b)/n.height),_.push((h+m)/n.height);var C=Math.max.apply(Math,_);C>1&&(s/=C,o/=C,u/=C,h/=C,p/=C,m/=C,w/=C,b/=C);var U=n.width-u,E=n.height-m,H=n.width-p,F=n.height-b,D=A.borderTopWidth,R=A.borderRightWidth,z=A.borderBottomWidth,N=A.borderLeftWidth,J=ie(A.paddingTop,t.bounds.width),et=ie(A.paddingRight,t.bounds.width),nt=ie(A.paddingBottom,t.bounds.width),ot=ie(A.paddingLeft,t.bounds.width);this.topLeftBorderDoubleOuterBox=s>0||o>0?ge(n.left+N/3,n.top+D/3,s-N/3,o-D/3,jt.TOP_LEFT):new ht(n.left+N/3,n.top+D/3),this.topRightBorderDoubleOuterBox=s>0||o>0?ge(n.left+U,n.top+D/3,u-R/3,h-D/3,jt.TOP_RIGHT):new ht(n.left+n.width-R/3,n.top+D/3),this.bottomRightBorderDoubleOuterBox=p>0||m>0?ge(n.left+H,n.top+E,p-R/3,m-z/3,jt.BOTTOM_RIGHT):new ht(n.left+n.width-R/3,n.top+n.height-z/3),this.bottomLeftBorderDoubleOuterBox=w>0||b>0?ge(n.left+N/3,n.top+F,w-N/3,b-z/3,jt.BOTTOM_LEFT):new ht(n.left+N/3,n.top+n.height-z/3),this.topLeftBorderDoubleInnerBox=s>0||o>0?ge(n.left+N*2/3,n.top+D*2/3,s-N*2/3,o-D*2/3,jt.TOP_LEFT):new ht(n.left+N*2/3,n.top+D*2/3),this.topRightBorderDoubleInnerBox=s>0||o>0?ge(n.left+U,n.top+D*2/3,u-R*2/3,h-D*2/3,jt.TOP_RIGHT):new ht(n.left+n.width-R*2/3,n.top+D*2/3),this.bottomRightBorderDoubleInnerBox=p>0||m>0?ge(n.left+H,n.top+E,p-R*2/3,m-z*2/3,jt.BOTTOM_RIGHT):new ht(n.left+n.width-R*2/3,n.top+n.height-z*2/3),this.bottomLeftBorderDoubleInnerBox=w>0||b>0?ge(n.left+N*2/3,n.top+F,w-N*2/3,b-z*2/3,jt.BOTTOM_LEFT):new ht(n.left+N*2/3,n.top+n.height-z*2/3),this.topLeftBorderStroke=s>0||o>0?ge(n.left+N/2,n.top+D/2,s-N/2,o-D/2,jt.TOP_LEFT):new ht(n.left+N/2,n.top+D/2),this.topRightBorderStroke=s>0||o>0?ge(n.left+U,n.top+D/2,u-R/2,h-D/2,jt.TOP_RIGHT):new ht(n.left+n.width-R/2,n.top+D/2),this.bottomRightBorderStroke=p>0||m>0?ge(n.left+H,n.top+E,p-R/2,m-z/2,jt.BOTTOM_RIGHT):new ht(n.left+n.width-R/2,n.top+n.height-z/2),this.bottomLeftBorderStroke=w>0||b>0?ge(n.left+N/2,n.top+F,w-N/2,b-z/2,jt.BOTTOM_LEFT):new ht(n.left+N/2,n.top+n.height-z/2),this.topLeftBorderBox=s>0||o>0?ge(n.left,n.top,s,o,jt.TOP_LEFT):new ht(n.left,n.top),this.topRightBorderBox=u>0||h>0?ge(n.left+U,n.top,u,h,jt.TOP_RIGHT):new ht(n.left+n.width,n.top),this.bottomRightBorderBox=p>0||m>0?ge(n.left+H,n.top+E,p,m,jt.BOTTOM_RIGHT):new ht(n.left+n.width,n.top+n.height),this.bottomLeftBorderBox=w>0||b>0?ge(n.left,n.top+F,w,b,jt.BOTTOM_LEFT):new ht(n.left,n.top+n.height),this.topLeftPaddingBox=s>0||o>0?ge(n.left+N,n.top+D,Math.max(0,s-N),Math.max(0,o-D),jt.TOP_LEFT):new ht(n.left+N,n.top+D),this.topRightPaddingBox=u>0||h>0?ge(n.left+Math.min(U,n.width-R),n.top+D,U>n.width+R?0:Math.max(0,u-R),Math.max(0,h-D),jt.TOP_RIGHT):new ht(n.left+n.width-R,n.top+D),this.bottomRightPaddingBox=p>0||m>0?ge(n.left+Math.min(H,n.width-N),n.top+Math.min(E,n.height-z),Math.max(0,p-R),Math.max(0,m-z),jt.BOTTOM_RIGHT):new ht(n.left+n.width-R,n.top+n.height-z),this.bottomLeftPaddingBox=w>0||b>0?ge(n.left+N,n.top+Math.min(F,n.height-z),Math.max(0,w-N),Math.max(0,b-z),jt.BOTTOM_LEFT):new ht(n.left+N,n.top+n.height-z),this.topLeftContentBox=s>0||o>0?ge(n.left+N+ot,n.top+D+J,Math.max(0,s-(N+ot)),Math.max(0,o-(D+J)),jt.TOP_LEFT):new ht(n.left+N+ot,n.top+D+J),this.topRightContentBox=u>0||h>0?ge(n.left+Math.min(U,n.width+N+ot),n.top+D+J,U>n.width+N+ot?0:u-N+ot,h-(D+J),jt.TOP_RIGHT):new ht(n.left+n.width-(R+et),n.top+D+J),this.bottomRightContentBox=p>0||m>0?ge(n.left+Math.min(H,n.width-(N+ot)),n.top+Math.min(E,n.height+D+J),Math.max(0,p-(R+et)),m-(z+nt),jt.BOTTOM_RIGHT):new ht(n.left+n.width-(R+et),n.top+n.height-(z+nt)),this.bottomLeftContentBox=w>0||b>0?ge(n.left+N+ot,n.top+F,Math.max(0,w-(N+ot)),b-(z+nt),jt.BOTTOM_LEFT):new ht(n.left+N+ot,n.top+n.height-(z+nt))}return e}(),jt;(function(e){e[e.TOP_LEFT=0]="TOP_LEFT",e[e.TOP_RIGHT=1]="TOP_RIGHT",e[e.BOTTOM_RIGHT=2]="BOTTOM_RIGHT",e[e.BOTTOM_LEFT=3]="BOTTOM_LEFT"})(jt||(jt={}));var ge=function(e,t,A,n,i){var s=4*((Math.sqrt(2)-1)/3),o=A*s,c=n*s,u=e+A,h=t+n;switch(i){case jt.TOP_LEFT:return new Df(new ht(e,h),new ht(e,h-c),new ht(u-o,t),new ht(u,t));case jt.TOP_RIGHT:return new Df(new ht(e,t),new ht(e+o,t),new ht(u,h-c),new ht(u,h));case jt.BOTTOM_RIGHT:return new Df(new ht(u,t),new ht(u,t+c),new ht(e+o,h),new ht(e,h));case jt.BOTTOM_LEFT:default:return new Df(new ht(u,h),new ht(u-o,h),new ht(e,t+c),new ht(e,t))}},Mh=function(e){return[e.topLeftBorderBox,e.topRightBorderBox,e.bottomRightBorderBox,e.bottomLeftBorderBox]},e8=function(e){return[e.topLeftContentBox,e.topRightContentBox,e.bottomRightContentBox,e.bottomLeftContentBox]},Lh=function(e){return[e.topLeftPaddingBox,e.topRightPaddingBox,e.bottomRightPaddingBox,e.bottomLeftPaddingBox]},A8=function(){function e(t,A,n){this.offsetX=t,this.offsetY=A,this.matrix=n,this.type=0,this.target=6}return e}(),Mf=function(){function e(t,A){this.path=t,this.target=A,this.type=1}return e}(),n8=function(){function e(t){this.opacity=t,this.type=2,this.target=6}return e}(),i8=function(e){return e.type===0},wS=function(e){return e.type===1},r8=function(e){return e.type===2},cQ=function(e,t){return e.length===t.length?e.some(function(A,n){return A===t[n]}):!1},s8=function(e,t,A,n,i){return e.map(function(s,o){switch(o){case 0:return s.add(t,A);case 1:return s.add(t+n,A);case 2:return s.add(t+n,A+i);case 3:return s.add(t,A+i)}return s})},bS=function(){function e(t){this.element=t,this.inlineLevel=[],this.nonInlineLevel=[],this.negativeZIndex=[],this.zeroOrAutoZIndexOrTransformedOrOpacity=[],this.positiveZIndex=[],this.nonPositionedFloats=[],this.nonPositionedInlineLevel=[]}return e}(),yS=function(){function e(t,A){if(this.container=t,this.parent=A,this.effects=[],this.curves=new t8(this.container),this.container.styles.opacity<1&&this.effects.push(new n8(this.container.styles.opacity)),this.container.styles.transform!==null){var n=this.container.bounds.left+this.container.styles.transformOrigin[0].number,i=this.container.bounds.top+this.container.styles.transformOrigin[1].number,s=this.container.styles.transform;this.effects.push(new A8(n,i,s))}if(this.container.styles.overflowX!==0){var o=Mh(this.curves),c=Lh(this.curves);cQ(o,c)?this.effects.push(new Mf(o,6)):(this.effects.push(new Mf(o,2)),this.effects.push(new Mf(c,4)))}}return e.prototype.getEffects=function(t){for(var A=[2,3].indexOf(this.container.styles.position)===-1,n=this.parent,i=this.effects.slice(0);n;){var s=n.effects.filter(function(u){return!wS(u)});if(A||n.container.styles.position!==0||!n.parent){if(i.unshift.apply(i,s),A=[2,3].indexOf(n.container.styles.position)===-1,n.container.styles.overflowX!==0){var o=Mh(n.curves),c=Lh(n.curves);cQ(o,c)||i.unshift(new Mf(c,6))}}else i.unshift.apply(i,s);n=n.parent}return i.filter(function(u){return ze(u.target,t)})},e}(),Mm=function(e,t,A,n){e.container.elements.forEach(function(i){var s=ze(i.flags,4),o=ze(i.flags,2),c=new yS(i,e);ze(i.styles.display,2048)&&n.push(c);var u=ze(i.flags,8)?[]:n;if(s||o){var h=s||i.styles.isPositioned()?A:t,d=new bS(c);if(i.styles.isPositioned()||i.styles.opacity<1||i.styles.isTransformed()){var p=i.styles.zIndex.order;if(p<0){var m=0;h.negativeZIndex.some(function(w,b){return p>w.element.container.styles.zIndex.order?(m=b,!1):m>0}),h.negativeZIndex.splice(m,0,d)}else if(p>0){var v=0;h.positiveZIndex.some(function(w,b){return p>=w.element.container.styles.zIndex.order?(v=b+1,!1):v>0}),h.positiveZIndex.splice(v,0,d)}else h.zeroOrAutoZIndexOrTransformedOrOpacity.push(d)}else i.styles.isFloating()?h.nonPositionedFloats.push(d):h.nonPositionedInlineLevel.push(d);Mm(c,d,s?d:A,u)}else i.styles.isInlineLevel()?t.inlineLevel.push(c):t.nonInlineLevel.push(c),Mm(c,t,A,u);ze(i.flags,8)&&CS(i,u)})},CS=function(e,t){for(var A=e instanceof Sm?e.start:1,n=e instanceof Sm?e.reversed:!1,i=0;i"u"?e[0]:A},d8=function(e,t,A,n,i){var s=t[0],o=t[1],c=A[0],u=A[1];switch(e){case 2:return[new ht(Math.round(n.left),Math.round(n.top+o)),new ht(Math.round(n.left+n.width),Math.round(n.top+o)),new ht(Math.round(n.left+n.width),Math.round(u+n.top+o)),new ht(Math.round(n.left),Math.round(u+n.top+o))];case 3:return[new ht(Math.round(n.left+s),Math.round(n.top)),new ht(Math.round(n.left+s+c),Math.round(n.top)),new ht(Math.round(n.left+s+c),Math.round(n.height+n.top)),new ht(Math.round(n.left+s),Math.round(n.height+n.top))];case 1:return[new ht(Math.round(n.left+s),Math.round(n.top+o)),new ht(Math.round(n.left+s+c),Math.round(n.top+o)),new ht(Math.round(n.left+s+c),Math.round(n.top+o+u)),new ht(Math.round(n.left+s),Math.round(n.top+o+u))];default:return[new ht(Math.round(i.left),Math.round(i.top)),new ht(Math.round(i.left+i.width),Math.round(i.top)),new ht(Math.round(i.left+i.width),Math.round(i.height+i.top)),new ht(Math.round(i.left),Math.round(i.height+i.top))]}},g8="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",fQ="Hidden Text",p8=function(){function e(t){this._data={},this._document=t}return e.prototype.parseMetrics=function(t,A){var n=this._document.createElement("div"),i=this._document.createElement("img"),s=this._document.createElement("span"),o=this._document.body;n.style.visibility="hidden",n.style.fontFamily=t,n.style.fontSize=A,n.style.margin="0",n.style.padding="0",n.style.whiteSpace="nowrap",o.appendChild(n),i.src=g8,i.width=1,i.height=1,i.style.margin="0",i.style.padding="0",i.style.verticalAlign="baseline",s.style.fontFamily=t,s.style.fontSize=A,s.style.margin="0",s.style.padding="0",s.appendChild(this._document.createTextNode(fQ)),n.appendChild(s),n.appendChild(i);var c=i.offsetTop-s.offsetTop+2;n.removeChild(s),n.appendChild(this._document.createTextNode(fQ)),n.style.lineHeight="normal",i.style.verticalAlign="super";var u=i.offsetTop-n.offsetTop+2;return o.removeChild(n),{baseline:c,middle:u}},e.prototype.getMetrics=function(t,A){var n=t+" "+A;return typeof this._data[n]>"u"&&(this._data[n]=this.parseMetrics(t,A)),this._data[n]},e}(),xS=function(){function e(t,A){this.context=t,this.options=A}return e}(),B8=1e4,m8=function(e){Vn(t,e);function t(A,n){var i=e.call(this,A,n)||this;return i._activeEffects=[],i.canvas=n.canvas?n.canvas:document.createElement("canvas"),i.ctx=i.canvas.getContext("2d"),n.canvas||(i.canvas.width=Math.floor(n.width*n.scale),i.canvas.height=Math.floor(n.height*n.scale),i.canvas.style.width=n.width+"px",i.canvas.style.height=n.height+"px"),i.fontMetrics=new p8(document),i.ctx.scale(i.options.scale,i.options.scale),i.ctx.translate(-n.x,-n.y),i.ctx.textBaseline="bottom",i._activeEffects=[],i.context.logger.debug("Canvas renderer initialized ("+n.width+"x"+n.height+") with scale "+n.scale),i}return t.prototype.applyEffects=function(A){for(var n=this;this._activeEffects.length;)this.popEffect();A.forEach(function(i){return n.applyEffect(i)})},t.prototype.applyEffect=function(A){this.ctx.save(),r8(A)&&(this.ctx.globalAlpha=A.opacity),i8(A)&&(this.ctx.translate(A.offsetX,A.offsetY),this.ctx.transform(A.matrix[0],A.matrix[1],A.matrix[2],A.matrix[3],A.matrix[4],A.matrix[5]),this.ctx.translate(-A.offsetX,-A.offsetY)),wS(A)&&(this.path(A.path),this.ctx.clip()),this._activeEffects.push(A)},t.prototype.popEffect=function(){this._activeEffects.pop(),this.ctx.restore()},t.prototype.renderStack=function(A){return UA(this,void 0,void 0,function(){var n;return dA(this,function(i){switch(i.label){case 0:return n=A.element.container.styles,n.isVisible()?[4,this.renderStackContent(A)]:[3,2];case 1:i.sent(),i.label=2;case 2:return[2]}})})},t.prototype.renderNode=function(A){return UA(this,void 0,void 0,function(){return dA(this,function(n){switch(n.label){case 0:if(ze(A.container.flags,16))debugger;return A.container.styles.isVisible()?[4,this.renderNodeBackgroundAndBorders(A)]:[3,3];case 1:return n.sent(),[4,this.renderNodeContent(A)];case 2:n.sent(),n.label=3;case 3:return[2]}})})},t.prototype.renderTextWithLetterSpacing=function(A,n,i){var s=this;if(n===0)this.ctx.fillText(A.text,A.bounds.left,A.bounds.top+i);else{var o=Hv(A.text);o.reduce(function(c,u){return s.ctx.fillText(u,c,A.bounds.top+i),c+s.ctx.measureText(u).width},A.bounds.left)}},t.prototype.createFontStyle=function(A){var n=A.fontVariant.filter(function(o){return o==="normal"||o==="small-caps"}).join(""),i=C8(A.fontFamily).join(", "),s=Oc(A.fontSize)?""+A.fontSize.number+A.fontSize.unit:A.fontSize.number+"px";return[[A.fontStyle,n,A.fontWeight,s,i].join(" "),i,s]},t.prototype.renderTextNode=function(A,n){return UA(this,void 0,void 0,function(){var i,s,o,c,u,h,d,p,m=this;return dA(this,function(v){return i=this.createFontStyle(n),s=i[0],o=i[1],c=i[2],this.ctx.font=s,this.ctx.direction=n.direction===1?"rtl":"ltr",this.ctx.textAlign="left",this.ctx.textBaseline="alphabetic",u=this.fontMetrics.getMetrics(o,c),h=u.baseline,d=u.middle,p=n.paintOrder,A.textBounds.forEach(function(w){p.forEach(function(b){switch(b){case 0:m.ctx.fillStyle=Ye(n.color),m.renderTextWithLetterSpacing(w,n.letterSpacing,h);var _=n.textShadow;_.length&&w.text.trim().length&&(_.slice(0).reverse().forEach(function(C){m.ctx.shadowColor=Ye(C.color),m.ctx.shadowOffsetX=C.offsetX.number*m.options.scale,m.ctx.shadowOffsetY=C.offsetY.number*m.options.scale,m.ctx.shadowBlur=C.blur.number,m.renderTextWithLetterSpacing(w,n.letterSpacing,h)}),m.ctx.shadowColor="",m.ctx.shadowOffsetX=0,m.ctx.shadowOffsetY=0,m.ctx.shadowBlur=0),n.textDecorationLine.length&&(m.ctx.fillStyle=Ye(n.textDecorationColor||n.color),n.textDecorationLine.forEach(function(C){switch(C){case 1:m.ctx.fillRect(w.bounds.left,Math.round(w.bounds.top+h),w.bounds.width,1);break;case 2:m.ctx.fillRect(w.bounds.left,Math.round(w.bounds.top),w.bounds.width,1);break;case 3:m.ctx.fillRect(w.bounds.left,Math.ceil(w.bounds.top+d),w.bounds.width,1);break}}));break;case 1:n.webkitTextStrokeWidth&&w.text.trim().length&&(m.ctx.strokeStyle=Ye(n.webkitTextStrokeColor),m.ctx.lineWidth=n.webkitTextStrokeWidth,m.ctx.lineJoin=window.chrome?"miter":"round",m.ctx.strokeText(w.text,w.bounds.left,w.bounds.top+h)),m.ctx.strokeStyle="",m.ctx.lineWidth=0,m.ctx.lineJoin="miter";break}})}),[2]})})},t.prototype.renderReplacedElement=function(A,n,i){if(i&&A.intrinsicWidth>0&&A.intrinsicHeight>0){var s=Rh(A),o=Lh(n);this.path(o),this.ctx.save(),this.ctx.clip(),this.ctx.drawImage(i,0,0,A.intrinsicWidth,A.intrinsicHeight,s.left,s.top,s.width,s.height),this.ctx.restore()}},t.prototype.renderNodeContent=function(A){return UA(this,void 0,void 0,function(){var n,i,s,o,c,u,U,U,h,d,p,m,H,v,w,F,b,_,C,U,E,H,F;return dA(this,function(D){switch(D.label){case 0:this.applyEffects(A.getEffects(4)),n=A.container,i=A.curves,s=n.styles,o=0,c=n.textNodes,D.label=1;case 1:return o0&&ft>0&&(z=s.ctx.createPattern(F,"repeat"),s.renderRepeat(J,z,L,G))):r5(d)&&(N=FB(A,n,[null,null,null]),J=N[0],et=N[1],nt=N[2],ot=N[3],ft=N[4],st=d.position.length===0?[Ev]:d.position,L=ie(st[0],ot),G=ie(st[st.length-1],ft),q=t5(d,L,G,ot,ft),ct=q[0],T=q[1],ct>0&&T>0&&(j=s.ctx.createRadialGradient(et+L,nt+G,0,et+L,nt+G,ct),Dx(d.stops,ct*2).forEach(function(he){return j.addColorStop(he.stop,Ye(he.color))}),s.path(J),s.ctx.fillStyle=j,ct!==T?(At=A.bounds.left+.5*A.bounds.width,tt=A.bounds.top+.5*A.bounds.height,Y=T/ct,ut=1/Y,s.ctx.save(),s.ctx.translate(At,tt),s.ctx.transform(1,0,0,Y,0,0),s.ctx.translate(-At,-tt),s.ctx.fillRect(et,ut*(nt-tt)+tt,ot,ft*ut),s.ctx.restore()):s.ctx.fill())),lt.label=6;case 6:return n--,[2]}})},s=this,o=0,c=A.styles.backgroundImage.slice(0).reverse(),h.label=1;case 1:return o0?d.style!==2?[3,5]:[4,this.renderDashedDottedBorder(d.color,d.width,c,A.curves,2)]:[3,11]):[3,13];case 4:return m.sent(),[3,11];case 5:return d.style!==3?[3,7]:[4,this.renderDashedDottedBorder(d.color,d.width,c,A.curves,3)];case 6:return m.sent(),[3,11];case 7:return d.style!==4?[3,9]:[4,this.renderDoubleBorder(d.color,d.width,c,A.curves)];case 8:return m.sent(),[3,11];case 9:return[4,this.renderSolidBorder(d.color,c,A.curves)];case 10:m.sent(),m.label=11;case 11:c++,m.label=12;case 12:return u++,[3,3];case 13:return[2]}})})},t.prototype.renderDashedDottedBorder=function(A,n,i,s,o){return UA(this,void 0,void 0,function(){var c,u,h,d,p,m,v,w,b,_,C,U,E,H,F,D,F,D;return dA(this,function(R){return this.ctx.save(),c=c8(s,i),u=uQ(s,i),o===2&&(this.path(u),this.ctx.clip()),bn(u[0])?(h=u[0].start.x,d=u[0].start.y):(h=u[0].x,d=u[0].y),bn(u[1])?(p=u[1].end.x,m=u[1].end.y):(p=u[1].x,m=u[1].y),i===0||i===2?v=Math.abs(h-p):v=Math.abs(d-m),this.ctx.beginPath(),o===3?this.formatPath(c):this.formatPath(u.slice(0,2)),w=n<3?n*3:n*2,b=n<3?n*2:n,o===3&&(w=n,b=n),_=!0,v<=w*2?_=!1:v<=w*2+b?(C=v/(2*w+b),w*=C,b*=C):(U=Math.floor((v+b)/(w+b)),E=(v-U*w)/(U-1),H=(v-(U+1)*w)/U,b=H<=0||Math.abs(b-E){const c=S.useRef(null),[u,h]=S.useState(s),[d,p]=S.useState(!1),v=S.useCallback(()=>{const{rowKeyTuples:E,colKeyTuples:H,cells:F}=e;if(u==="bar"||u==="line"){const D=E.map(z=>z.map(N=>String(N??"")).join(" / ")),R=H.map((z,N)=>{const J=z.map(st=>String(st??"")).join(" / "),et=A.length>0?J:`Column ${N+1}`,nt=E.map(st=>{const L=st.map(q=>String(q??"")).join("||"),G=F[L]?.[J];return G?G.value:0}),ft=`hsl(${N*137.5%360}, 70%, 60%)`;return{label:et,data:nt,backgroundColor:u==="line"?"transparent":ft,borderColor:ft,borderWidth:u==="line"?2:1,fill:u!=="line",tension:u==="line"?.1:void 0}});return{labels:D,datasets:R}}else{const D={};Object.values(F).forEach(J=>{Object.values(J).forEach(et=>{const nt=Object.keys(J).find(ot=>J[ot]===et);if(nt){const ot=nt||"Unknown";D[ot]=(D[ot]||0)+et.value}})});const R=Object.keys(D),z=Object.values(D),N=R.map((J,et)=>`hsl(${et*137.5%360}, 60%, 60%)`);return{labels:R,datasets:[{data:z,backgroundColor:N,borderColor:N.map(J=>J),borderWidth:1}]}}},[e,t,A,u])(),w=v.labels.length>0&&v.datasets.length>0,b=u!=="line"||!v.datasets.some(E=>E.data.length===0),_={responsive:!0,maintainAspectRatio:!1,plugins:{title:{display:!0,text:`Pivot Table: ${i} of ${String(n||"records")}`,font:{size:16,weight:"bold"}},legend:{display:!0,position:"top"},tooltip:{enabled:!0}},scales:u==="bar"||u==="line"?{y:{type:"linear",beginAtZero:!0,title:{display:!0,text:i==="count"?"Count":"Value"}},x:{type:"category",title:{display:!0,text:t.map(E=>String(E)).join(" / ")}}}:void 0,elements:u==="line"?{line:{tension:.1},point:{radius:3,hoverRadius:5}}:void 0},C=S.useCallback(async()=>{if(c.current){p(!0);try{const E=await E8(c.current,{backgroundColor:"#ffffff",scale:2,useCORS:!0,allowTaint:!0}),H=document.createElement("a");H.download=`pivot-chart-${u}-${Date.now()}.png`,H.href=E.toDataURL("image/png"),H.click()}catch(E){console.error("Error exporting chart:",E)}finally{p(!1)}}},[u]),U=[{value:"bar",label:"Bar Chart"},{value:"line",label:"Line Chart"},{value:"doughnut",label:"Doughnut Chart"},{value:"pie",label:"Pie Chart"}];return Q.jsxs(Q.Fragment,{children:[o&&null,!o&&!w&&Q.jsxs("div",{className:"mb-4 bg-white",children:[Q.jsx("div",{className:"flex items-center justify-between mb-4",children:Q.jsx("h3",{className:"text-sm font-medium text-gray-900",children:"Chart Export"})}),Q.jsx("div",{className:"text-center text-gray-500 py-8",children:"No data available for chart visualization. Please select row and column fields."})]}),!o&&w&&!b&&Q.jsxs("div",{className:"mb-4 bg-white",children:[Q.jsx("div",{className:"flex items-center justify-between mb-4",children:Q.jsx("h3",{className:"text-sm font-medium text-gray-900",children:"Chart Export"})}),Q.jsx("div",{className:"text-center text-gray-500 py-8",children:"Line charts require data in all datasets. Please check your pivot configuration."})]}),!o&&w&&b&&Q.jsxs("div",{className:"mb-4 bg-white",children:[Q.jsxs("div",{className:"flex items-center justify-between mb-4",children:[Q.jsx("h3",{className:"text-sm font-medium text-gray-900",children:"Chart Export"}),Q.jsxs("div",{className:"flex items-center space-x-2",children:[Q.jsx(ov,{value:u,onChange:E=>h(E.target.value),size:"sm",className:"min-w-32",children:U.map(E=>Q.jsx("option",{value:E.value,children:E.label},E.value))}),Q.jsx(Je,{onClick:C,disabled:d,size:"sm",variant:"secondary",children:d?"Exporting...":"Export as Image"})]})]}),Q.jsx("div",{className:"text-xs text-gray-600 mb-3",children:"Visualize your pivot table data as a chart and export it as a high-resolution PNG image. You can adjust your browser window size to change the exported image dimensions."}),Q.jsx("div",{ref:c,className:"w-full h-96 bg-white p-4",children:Q.jsx(nP,{type:u,data:v,options:_})})]})]})};function O8(e){const{rowFields:t,columnFields:A,valueField:n,aggregator:i}=e,s=S.useMemo(()=>t.filter(d=>d!==""),[t]),o=S.useMemo(()=>A.filter(d=>d!==""),[A]),c=S.useMemo(()=>n&&n!==""?n:void 0,[n]),u=S.useMemo(()=>s.length>0&&o.length>0,[s,o]),h=S.useMemo(()=>u?bE({data:rt.flattenedDataset,rowFields:s,columnFields:o,valueField:c,aggregator:i,filter:vh(rt.filterConfig)}):{rowKeyTuples:[],colKeyTuples:[],cells:{},rowTotals:{},colTotals:{},grandTotal:0},[u,s,o,c,i,rt.filterConfig]);return{rowFields:s,columnFields:o,valueField:c,aggregator:i,pivotResult:h,hasValidConfiguration:u}}function T8(e){return(t,A)=>{e(t,A)}}function D8(e,t,A=3){return()=>{e.length{t(e.filter((n,i)=>i!==A))}}function hQ(e,t,A=3){return{onFieldChange:T8((n,i)=>{const s=[...e];s[n]=i,t(s)}),onAddField:D8(e,t,A),onRemoveField:M8(e,t)}}function L8(){return rt.flattenedDatasetKeys}function R8(){return rt.pivotConfig}function If(e){rt.updatePivotConfig(e)}function I8(){rt.resetPivotConfig()}function N8(e){rt.updateFilterConfig(e)}function k8(){return rt.flattenedDataset}function K8(){return vh(rt.filterConfig)}function z8(){return rt.filterConfig}const dQ=({title:e,fields:t,onFieldChange:A,onAddField:n,onRemoveField:i,availableKeys:s,variant:o="default"})=>{const c={row:"border-l-4 border-l-blue-500 pl-3",column:"border-l-4 border-l-green-500 pl-3",default:""};return Q.jsxs("div",{className:`mb-4 ${c[o]}`,children:[Q.jsxs("div",{className:"text-xs font-medium text-gray-700 mb-2",children:[e,":"]}),Q.jsxs("div",{className:"space-y-2",children:[t.map((u,h)=>Q.jsxs("div",{className:"flex items-center space-x-2",children:[Q.jsx(Ds,{value:u,onChange:d=>A(h,d),options:[{value:"",label:"Select a field..."},...s?.map(d=>({value:d,label:d}))||[]],size:"sm",className:"min-w-48"}),t.length>0&&Q.jsx("button",{onClick:()=>i(h),className:"text-xs text-red-600 hover:text-red-800 px-2 py-1",children:"Remove"})]},h)),t.length<3&&Q.jsxs("button",{onClick:n,className:"text-xs text-blue-600 hover:text-blue-800 px-2 py-1",children:["+ Add ",e.slice(0,-1)]})]})]})},V8=({title:e,field:t,onFieldChange:A,availableKeys:n})=>Q.jsxs("div",{className:"mb-4",children:[Q.jsxs("div",{className:"text-xs font-medium text-gray-700 mb-2",children:[e,":"]}),Q.jsx(Ds,{value:t,onChange:i=>A(i),options:[{value:"",label:"Select a field..."},...n?.map(i=>({value:i,label:i}))||[]],size:"sm",className:"min-w-48"})]}),P8=({aggregator:e,onAggregatorChange:t})=>Q.jsxs("div",{className:"mb-4",children:[Q.jsx("div",{className:"text-xs font-medium text-gray-700 mb-2",children:"Aggregation Method:"}),Q.jsx(Ds,{value:e,onChange:A=>t(A),options:[{value:"count",label:"Count"},{value:"sum",label:"Sum"},{value:"avg",label:"Average"},{value:"min",label:"Minimum"},{value:"max",label:"Maximum"}],size:"sm",className:"min-w-48"})]}),j8=Ae(()=>{const e=R8(),t=L8(),A=O8({rowFields:e.selectedRowFields,columnFields:e.selectedColumnFields,valueField:e.selectedValueField,aggregator:e.selectedAggregator}),n=S.useMemo(()=>hQ(e.selectedRowFields,d=>If({selectedRowFields:d})),[e.selectedRowFields]),i=S.useMemo(()=>hQ(e.selectedColumnFields,d=>If({selectedColumnFields:d})),[e.selectedColumnFields]),s=S.useCallback(d=>{If({selectedValueField:d})},[]),o=S.useCallback(d=>{If({selectedAggregator:d})},[]),c=S.useCallback(d=>{N8(d)},[]),u=S.useMemo(()=>k8(),[]),h=S.useMemo(()=>K8(),[]);return Q.jsxs("div",{children:[Q.jsx("div",{className:"text-xs text-gray-600 mb-2 max-w-2xl",children:"Answer questions about your dataset by creating pivot tables that summarize and analyze your data. Select fields for rows, columns, and values to explore patterns, compare metrics across different dimensions, and gain insights from your evaluation results. Use filters to focus on specific subsets of your data."}),Q.jsx("div",{className:"mb-4 flex justify-between items-center",children:Q.jsx(Je,{onClick:()=>I8(),variant:"secondary",size:"sm",children:"Reset to Defaults"})}),Q.jsx(dQ,{title:"Row Fields",fields:e.selectedRowFields,...n,availableKeys:t,variant:"row"}),Q.jsx(dQ,{title:"Column Fields",fields:e.selectedColumnFields,...i,availableKeys:t,variant:"column"}),Q.jsx(V8,{title:"Value Field",field:e.selectedValueField,onFieldChange:s,availableKeys:t}),Q.jsx(P8,{aggregator:e.selectedAggregator,onAggregatorChange:o}),Q.jsx(wE,{filters:z8(),onFiltersChange:c,availableKeys:t,title:"Filters"}),Q.jsx(H8,{pivotData:A.pivotResult,rowFields:A.rowFields,columnFields:A.columnFields,valueField:A.valueField,aggregator:A.aggregator,showRowTotals:!0,showColumnTotals:!0,hidden:!A.hasValidConfiguration}),Q.jsx(HN,{data:u,rowFields:A.rowFields,columnFields:A.columnFields,valueField:A.valueField,aggregator:A.aggregator,showRowTotals:!0,showColumnTotals:!0,filter:h})]})}),gQ=({label:e,isActive:t,onClick:A,title:n})=>Q.jsx("button",{type:"button",role:"tab","aria-selected":t,title:n,onClick:A,className:`text-xs font-medium px-2 py-0.5 border-b-2 focus:outline-none cursor-pointer transition-colors ${t?"text-gray-900 border-gray-900 bg-transparent":"text-gray-700 hover:text-gray-900 hover:border-gray-400 border-transparent bg-transparent hover:bg-gray-100"}`,children:e}),G8=({onRefresh:e})=>{const t=()=>{e()};return Q.jsx("div",{className:"bg-white border border-gray-200 p-8 text-center",children:Q.jsxs("div",{className:"max-w-sm mx-auto",children:[Q.jsx("div",{className:"text-gray-400 mb-4",children:Q.jsx("svg",{className:"mx-auto h-12 w-12",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:Q.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1,d:"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"})})}),Q.jsx("h3",{className:"text-sm font-medium text-gray-900 mb-2",children:"No evaluation data available"}),Q.jsx("p",{className:"text-xs text-gray-500 mb-4",children:"No evaluation rows have been loaded yet. Click refresh to reconnect and load data."}),Q.jsx(Je,{onClick:t,size:"md",children:"Refresh"})]})})},X8=()=>Q.jsx("div",{className:"bg-white border border-gray-200 p-8 text-center",children:Q.jsxs("div",{className:"max-w-sm mx-auto",children:[Q.jsx("div",{className:"text-gray-400 mb-4",children:Q.jsx("div",{className:"animate-spin rounded-full h-6 w-6 border-2 border-gray-300 border-t-gray-600 mx-auto"})}),Q.jsx("h3",{className:"text-sm font-medium text-gray-900 mb-2",children:"Loading evaluation data..."}),Q.jsx("p",{className:"text-xs text-gray-500",children:"Connecting to the server and loading data"})]})}),pQ=Ae(({onRefresh:e})=>{const t=()=>rt.setAllRowsExpanded(!0),A=()=>rt.setAllRowsExpanded(!1),n=tr(),i=km(),s=u=>u.endsWith("/pivot")?"pivot":"table",[o,c]=S.useState(s(n.pathname));return S.useEffect(()=>{c(s(n.pathname))},[n.pathname]),Q.jsx("div",{className:"text-sm",children:rt.isLoading?Q.jsx(X8,{}):rt.sortedDataset.length===0?Q.jsx(G8,{onRefresh:e}):Q.jsxs("div",{className:"bg-white border border-gray-200",children:[Q.jsx("div",{className:"px-3 pt-2 border-b border-gray-200",children:Q.jsxs("div",{className:"flex justify-between h-8",children:[Q.jsxs("div",{id:"tabs",className:"flex gap-1",children:[Q.jsx(gQ,{label:"Table",isActive:o==="table",onClick:()=>{c("table"),i("/table")},title:"View table"}),Q.jsx(gQ,{label:"Pivot",isActive:o==="pivot",onClick:()=>{c("pivot"),i("/pivot")},title:"View pivot"})]}),o==="table"&&Q.jsxs("div",{className:"flex gap-2 pb-2",children:[Q.jsx(Je,{onClick:t,size:"sm",variant:"secondary",children:"Expand All"}),Q.jsx(Je,{onClick:A,size:"sm",variant:"secondary",children:"Collapse All"})]})]})}),Q.jsx("div",{className:"p-3",children:o==="table"?Q.jsx(SN,{}):Q.jsx(j8,{})})]})})}),Z8=fe({type:Ec("initialize_logs"),logs:IA(wA())}),Y8=fe({type:Ec("log"),row:em}),W8=gI("type",[Z8,Y8]);fe({status:Ec("ok"),build_dir:gt(),active_connections:tA(),watch_paths:IA(gt())});fe({id:gt(),timestamp:gt(),level:av(["DEBUG","INFO","WARNING","ERROR"]),message:gt(),metadata:aA(gt(),wA()).optional()});function $8(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function BQ(e,t){if(typeof t=="number")return`${e}[${t}]`;if(/^[A-Za-z_][A-Za-z0-9_]*$/.test(t))return`${e}.${t}`;const n=t.replace(/'/g,"\\'");return`${e}['${n}']`}function J8(e,t="$"){const A={},n=(i,s)=>{if(i===null||typeof i=="string"||typeof i=="number"||typeof i=="boolean"||i===void 0){A[s]=i;return}if(i instanceof Date){A[s]=i;return}if(Array.isArray(i)){for(let o=0;o{try{localStorage.setItem("pivotConfig",JSON.stringify(this.pivotConfig))}catch(t){console.warn("Failed to save pivot config to localStorage:",t)}},200)}saveFilterConfig(){this.saveFilterConfigTimer&&clearTimeout(this.saveFilterConfigTimer),this.saveFilterConfigTimer=setTimeout(()=>{try{localStorage.setItem("filterConfig",JSON.stringify(this.filterConfig))}catch(t){console.warn("Failed to save filter config to localStorage:",t)}},200)}savePaginationConfig(){this.savePaginationConfigTimer&&clearTimeout(this.savePaginationConfigTimer),this.savePaginationConfigTimer=setTimeout(()=>{try{localStorage.setItem("paginationConfig",JSON.stringify({currentPage:this.currentPage,pageSize:this.pageSize}))}catch(t){console.warn("Failed to save pagination config to localStorage:",t)}},200)}saveSortConfig(){this.saveFilterConfigTimer&&clearTimeout(this.saveFilterConfigTimer),this.saveFilterConfigTimer=setTimeout(()=>{try{localStorage.setItem("sortConfig",JSON.stringify({sortField:this.sortField,sortDirection:this.sortDirection}))}catch(t){console.warn("Failed to save sort config to localStorage:",t)}},200)}updatePivotConfig(t){Object.assign(this.pivotConfig,t),this.savePivotConfig()}updateFilterConfig(t){this.filterConfig=t,this.saveFilterConfig(),this.applyFilterTimer&&clearTimeout(this.applyFilterTimer),this.applyFilterTimer=setTimeout(()=>{this.appliedFilterConfig=this.filterConfig.slice()},150)}updatePaginationConfig(t){t.currentPage!==void 0&&(this.currentPage=t.currentPage),t.pageSize!==void 0&&(this.pageSize=t.pageSize),this.savePaginationConfig()}updateSortConfig(t){Object.assign(this,t),this.currentPage=1,this.saveSortConfig()}handleSortFieldClick(t){this.sortField===t?this.sortDirection=this.sortDirection==="asc"?"desc":"asc":(this.sortField=t,this.sortDirection="asc"),this.saveSortConfig()}resetPivotConfig(){this.pivotConfig={...SB},this.savePivotConfig()}resetFilterConfig(){this.filterConfig=[...Nf],this.appliedFilterConfig=[...Nf],this.saveFilterConfig()}resetPaginationConfig(){this.currentPage=kf.currentPage,this.pageSize=kf.pageSize,this.savePaginationConfig()}resetSortConfig(){this.sortField=Kf.sortField,this.sortDirection=Kf.sortDirection,this.saveSortConfig()}setCurrentPage(t){this.currentPage=t,this.savePaginationConfig()}setPageSize(t){this.pageSize=t,this.currentPage=1,this.savePaginationConfig()}setLoading(t){this.isLoading=t}setConnected(t){this.isConnected=t}upsertRows(t){Oy(()=>{this.isLoading=!0}),t.forEach(A=>{if(!A.execution_metadata?.rollout_id)return;const n=A.execution_metadata.rollout_id;this.dataset[n]=A;const i=new Date(A.created_at).getTime();this.createdAtMsById[n]=isNaN(i)?0:i,this.flattenedById[n]=J8(A)}),Oy(()=>{this.currentPage=1,this.isLoading=!1}),this.savePaginationConfig()}toggleRowExpansion(t){t&&(this.expandedRows[t]?this.expandedRows[t]=!1:this.expandedRows[t]=!0)}isRowExpanded(t){return t?this.expandedRows[t]:!1}setAllRowsExpanded(t){Object.keys(this.dataset).forEach(A=>{this.expandedRows[A]=t})}get sortedIds(){const t=Object.keys(this.dataset);return this.sortField==="created_at"?t.sort((A,n)=>{const i=this.createdAtMsById[A]??0,s=this.createdAtMsById[n]??0;return this.sortDirection==="asc"?i-s:s-i}):t.sort((A,n)=>{const i=this.flattenedById[A],s=this.flattenedById[n];if(!i||!s)return 0;const o=i[this.sortField],c=s[this.sortField];if(o===void 0&&c===void 0)return 0;if(o===void 0)return this.sortDirection==="asc"?-1:1;if(c===void 0)return this.sortDirection==="asc"?1:-1;if(typeof o=="string"&&typeof c=="string"){const p=o.localeCompare(c);return this.sortDirection==="asc"?p:-p}if(typeof o=="number"&&typeof c=="number")return this.sortDirection==="asc"?o-c:c-o;const u=String(o),h=String(c),d=u.localeCompare(h);return this.sortDirection==="asc"?d:-d})}get sortedDataset(){return this.sortedIds.map(t=>this.dataset[t])}get flattenedDataset(){return this.sortedIds.map(t=>this.flattenedById[t])}get filteredFlattenedDataset(){if(this.appliedFilterConfig.length===0)return this.flattenedDataset;const t=vh(this.appliedFilterConfig);return this.flattenedDataset.filter(t)}get filteredOriginalDataset(){if(this.appliedFilterConfig.length===0)return this.sortedDataset;const t=vh(this.appliedFilterConfig);return this.sortedIds.filter(A=>t(this.flattenedById[A])).map(A=>this.dataset[A])}get flattenedDatasetKeys(){const t=new Set;return this.sortedIds.forEach(A=>{const n=this.flattenedById[A];n&&Object.keys(n).forEach(i=>t.add(i))}),Array.from(t)}get totalCount(){return this.filteredFlattenedDataset.length}get totalPages(){return Math.ceil(this.totalCount/this.pageSize)}get startRow(){return(this.currentPage-1)*this.pageSize+1}get endRow(){return Math.min(this.currentPage*this.pageSize,this.totalCount)}}const tX="/assets/logo-light-BprIBJQW.png",QA={websocket:{host:"localhost",port:"8000",protocol:"ws"},api:{host:"localhost",port:"8000",protocol:"http"}},eX=()=>{const{protocol:e,host:t,port:A}=QA.websocket;return`${e}://${t}:${A}/ws`},AX=async()=>{try{if(window.SERVER_CONFIG){const n=window.SERVER_CONFIG;QA.websocket.host=n.host,QA.websocket.port=n.port,QA.websocket.protocol=n.protocol,QA.api.host=n.host,QA.api.port=n.port,QA.api.protocol=n.apiProtocol,console.log("Using server-injected config:",QA);return}const e=window.location.hostname,t=window.location.port,A=window.location.protocol==="https:"?"wss:":"ws:";QA.websocket.host=e,QA.websocket.port=t||(A==="wss:"?"443":"80"),QA.websocket.protocol=A,QA.api.host=e,QA.api.port=t||(A==="wss:"?"443":"80"),QA.api.protocol=window.location.protocol==="https:"?"https:":"http:",console.log("Using discovered config from location:",QA)}catch(e){console.warn("Failed to discover server config, using defaults:",e)}},rt=new q8,nX=1e3,mQ=5,iX=Ae(()=>{const e=S.useRef(null),t=S.useRef(null),A=S.useRef(0),n=()=>{if(e.current?.readyState===WebSocket.OPEN)return;const o=new WebSocket(eX());e.current=o,o.onopen=()=>{console.log("Connected to file watcher"),rt.setConnected(!0),rt.setLoading(!0),A.current=0},o.onmessage=c=>{try{const u=W8.parse(JSON.parse(c.data));if(u.type==="initialize_logs"){const h=u.logs.map(d=>em.parse(d));console.log("initialize_logs",h),rt.upsertRows(h)}else if(u.type==="log"){rt.setLoading(!0);const h=em.parse(u.row);console.log("log",h),rt.upsertRows([h])}}catch(u){console.error("Failed to parse WebSocket message:",u),rt.setLoading(!1)}},o.onclose=c=>{console.log("Disconnected from file watcher",c.code,c.reason),rt.setConnected(!1),rt.setLoading(!1),c.code!==1e3&&A.current{console.error("WebSocket error:",c),rt.setConnected(!1),rt.setLoading(!1)}},i=()=>{t.current&&clearTimeout(t.current);const o=nX*Math.pow(2,A.current);console.log(`Scheduling reconnect attempt ${A.current+1} in ${o}ms`),t.current=setTimeout(()=>{A.current++,console.log(`Attempting to reconnect (attempt ${A.current}/${mQ})`),n()},o)},s=()=>{if(rt.setLoading(!0),e.current){try{e.current.onclose=null,e.current.close()}catch{}e.current=null}n()};return S.useEffect(()=>((async()=>{await AX(),n()})(),()=>{t.current&&clearTimeout(t.current),e.current&&e.current.close()}),[]),Q.jsxs("div",{className:"min-h-screen bg-gray-50",children:[Q.jsx("nav",{className:"bg-white border-b border-gray-200",children:Q.jsx("div",{className:"max-w-7xl mx-auto px-3",children:Q.jsxs("div",{className:"flex justify-between items-center h-10",children:[Q.jsx("div",{className:"flex items-center space-x-2",children:Q.jsx("a",{href:"https://evalprotocol.io",target:"_blank",children:Q.jsx("img",{src:tX,alt:"Eval Protocol",className:"h-6 w-auto"})})}),Q.jsxs("div",{className:"flex items-center gap-2",children:[Q.jsx(pE,{status:rt.isConnected?{code:0,message:"Connected",details:[]}:{code:1,message:"Disconnected",details:[]}}),Q.jsx(Je,{onClick:s,className:"ml-2",children:"Refresh"})]})]})})}),Q.jsx("main",{className:"max-w-7xl mx-auto px-3 py-4",children:Q.jsxs(OO,{children:[Q.jsx(zf,{path:"/",element:Q.jsx(SO,{to:"/table",replace:!0})}),Q.jsx(zf,{path:"/table",element:Q.jsx(pQ,{onRefresh:s})}),Q.jsx(zf,{path:"/pivot",element:Q.jsx(pQ,{onRefresh:s})})]})})]})});KH.createRoot(document.getElementById("root")).render(Q.jsx(mA.StrictMode,{children:Q.jsx(eT,{children:Q.jsx(iX,{})})})); -//# sourceMappingURL=index-CWShMUgl.js.map +//# sourceMappingURL=index-CMzLJz8S.js.map diff --git a/vite-app/dist/assets/index-CWShMUgl.js.map b/vite-app/dist/assets/index-CMzLJz8S.js.map similarity index 54% rename from vite-app/dist/assets/index-CWShMUgl.js.map rename to vite-app/dist/assets/index-CMzLJz8S.js.map index 2385ca4d..09b1eba9 100644 --- a/vite-app/dist/assets/index-CWShMUgl.js.map +++ b/vite-app/dist/assets/index-CMzLJz8S.js.map @@ -1 +1 @@ -{"version":3,"file":"index-CWShMUgl.js","sources":["../../node_modules/.pnpm/react@19.1.1/node_modules/react/cjs/react-jsx-runtime.production.js","../../node_modules/.pnpm/react@19.1.1/node_modules/react/jsx-runtime.js","../../node_modules/.pnpm/react@19.1.1/node_modules/react/cjs/react.production.js","../../node_modules/.pnpm/react@19.1.1/node_modules/react/index.js","../../node_modules/.pnpm/scheduler@0.26.0/node_modules/scheduler/cjs/scheduler.production.js","../../node_modules/.pnpm/scheduler@0.26.0/node_modules/scheduler/index.js","../../node_modules/.pnpm/react-dom@19.1.1_react@19.1.1/node_modules/react-dom/cjs/react-dom.production.js","../../node_modules/.pnpm/react-dom@19.1.1_react@19.1.1/node_modules/react-dom/index.js","../../node_modules/.pnpm/react-dom@19.1.1_react@19.1.1/node_modules/react-dom/cjs/react-dom-client.production.js","../../node_modules/.pnpm/react-dom@19.1.1_react@19.1.1/node_modules/react-dom/client.js","../../node_modules/.pnpm/react-router@7.7.1_react-dom@19.1.1_react@19.1.1__react@19.1.1/node_modules/react-router/dist/development/chunk-C37GKA54.mjs","../../node_modules/.pnpm/mobx@6.13.7/node_modules/mobx/dist/mobx.esm.js","../../node_modules/.pnpm/mobx-react-lite@4.1.0_mobx@6.13.7_react-dom@19.1.1_react@19.1.1__react@19.1.1/node_modules/mobx-react-lite/es/utils/assertEnvironment.js","../../node_modules/.pnpm/mobx-react-lite@4.1.0_mobx@6.13.7_react-dom@19.1.1_react@19.1.1__react@19.1.1/node_modules/mobx-react-lite/es/utils/observerBatching.js","../../node_modules/.pnpm/mobx-react-lite@4.1.0_mobx@6.13.7_react-dom@19.1.1_react@19.1.1__react@19.1.1/node_modules/mobx-react-lite/es/utils/printDebugValue.js","../../node_modules/.pnpm/mobx-react-lite@4.1.0_mobx@6.13.7_react-dom@19.1.1_react@19.1.1__react@19.1.1/node_modules/mobx-react-lite/es/utils/UniversalFinalizationRegistry.js","../../node_modules/.pnpm/mobx-react-lite@4.1.0_mobx@6.13.7_react-dom@19.1.1_react@19.1.1__react@19.1.1/node_modules/mobx-react-lite/es/utils/observerFinalizationRegistry.js","../../node_modules/.pnpm/use-sync-external-store@1.5.0_react@19.1.1/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.production.js","../../node_modules/.pnpm/use-sync-external-store@1.5.0_react@19.1.1/node_modules/use-sync-external-store/shim/index.js","../../node_modules/.pnpm/mobx-react-lite@4.1.0_mobx@6.13.7_react-dom@19.1.1_react@19.1.1__react@19.1.1/node_modules/mobx-react-lite/es/useObserver.js","../../node_modules/.pnpm/mobx-react-lite@4.1.0_mobx@6.13.7_react-dom@19.1.1_react@19.1.1__react@19.1.1/node_modules/mobx-react-lite/es/observer.js","../../node_modules/.pnpm/mobx-react-lite@4.1.0_mobx@6.13.7_react-dom@19.1.1_react@19.1.1__react@19.1.1/node_modules/mobx-react-lite/es/index.js","../../node_modules/.pnpm/mobx-react@9.2.0_mobx@6.13.7_react-dom@19.1.1_react@19.1.1__react@19.1.1/node_modules/mobx-react/dist/mobxreact.esm.js","../../src/styles/common.ts","../../src/components/Button.tsx","../../node_modules/.pnpm/@floating-ui+utils@0.2.10/node_modules/@floating-ui/utils/dist/floating-ui.utils.mjs","../../node_modules/.pnpm/@floating-ui+core@1.7.3/node_modules/@floating-ui/core/dist/floating-ui.core.mjs","../../node_modules/.pnpm/@floating-ui+utils@0.2.10/node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.mjs","../../node_modules/.pnpm/@floating-ui+dom@1.7.4/node_modules/@floating-ui/dom/dist/floating-ui.dom.mjs","../../node_modules/.pnpm/classnames@2.5.1/node_modules/classnames/index.js","../../node_modules/.pnpm/react-tooltip@5.29.1_react-dom@19.1.1_react@19.1.1__react@19.1.1/node_modules/react-tooltip/dist/react-tooltip.min.mjs","../../src/components/Tooltip.tsx","../../src/components/MessageBubble.tsx","../../src/components/ChatInterface.tsx","../../src/components/MetadataSection.tsx","../../node_modules/.pnpm/zod@4.0.14/node_modules/zod/v4/core/core.js","../../node_modules/.pnpm/zod@4.0.14/node_modules/zod/v4/core/util.js","../../node_modules/.pnpm/zod@4.0.14/node_modules/zod/v4/core/errors.js","../../node_modules/.pnpm/zod@4.0.14/node_modules/zod/v4/core/parse.js","../../node_modules/.pnpm/zod@4.0.14/node_modules/zod/v4/core/regexes.js","../../node_modules/.pnpm/zod@4.0.14/node_modules/zod/v4/core/checks.js","../../node_modules/.pnpm/zod@4.0.14/node_modules/zod/v4/core/doc.js","../../node_modules/.pnpm/zod@4.0.14/node_modules/zod/v4/core/versions.js","../../node_modules/.pnpm/zod@4.0.14/node_modules/zod/v4/core/schemas.js","../../node_modules/.pnpm/zod@4.0.14/node_modules/zod/v4/core/registries.js","../../node_modules/.pnpm/zod@4.0.14/node_modules/zod/v4/core/api.js","../../node_modules/.pnpm/zod@4.0.14/node_modules/zod/v4/classic/iso.js","../../node_modules/.pnpm/zod@4.0.14/node_modules/zod/v4/classic/errors.js","../../node_modules/.pnpm/zod@4.0.14/node_modules/zod/v4/classic/parse.js","../../node_modules/.pnpm/zod@4.0.14/node_modules/zod/v4/classic/schemas.js","../../src/types/eval-protocol.ts","../../src/components/StatusIndicator.tsx","../../src/components/TableContainer.tsx","../../src/components/JSONTooltip.tsx","../../src/components/EvaluationRow.tsx","../../src/components/Select.tsx","../../src/components/SearchableSelect.tsx","../../src/components/FilterInput.tsx","../../src/util/filter-utils.ts","../../src/components/FilterSelector.tsx","../../src/components/EvaluationTable.tsx","../../src/util/pivot.ts","../../src/components/PivotTable.tsx","../../node_modules/.pnpm/@kurkle+color@0.3.4/node_modules/@kurkle/color/dist/color.esm.js","../../node_modules/.pnpm/chart.js@4.5.0/node_modules/chart.js/dist/chunks/helpers.dataset.js","../../node_modules/.pnpm/chart.js@4.5.0/node_modules/chart.js/dist/chart.js","../../node_modules/.pnpm/react-chartjs-2@5.3.0_chart.js@4.5.0_react@19.1.1/node_modules/react-chartjs-2/dist/index.js","../../node_modules/.pnpm/html2canvas-oklch@1.5.0-alpha.0/node_modules/html2canvas-oklch/dist/html2canvas.esm.js","../../src/components/ChartExport.tsx","../../src/hooks/usePivotData.ts","../../src/util/field-processors.ts","../../src/components/PivotTab.tsx","../../src/components/TabButton.tsx","../../src/components/Dashboard.tsx","../../src/types/websocket.ts","../../src/util/flatten-json.ts","../../src/GlobalState.tsx","../../src/assets/logo-light.png","../../src/config.ts","../../src/App.tsx","../../src/main.tsx"],"sourcesContent":["/**\n * @license React\n * react-jsx-runtime.production.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\nvar REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\");\nfunction jsxProd(type, config, maybeKey) {\n var key = null;\n void 0 !== maybeKey && (key = \"\" + maybeKey);\n void 0 !== config.key && (key = \"\" + config.key);\n if (\"key\" in config) {\n maybeKey = {};\n for (var propName in config)\n \"key\" !== propName && (maybeKey[propName] = config[propName]);\n } else maybeKey = config;\n config = maybeKey.ref;\n return {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n ref: void 0 !== config ? config : null,\n props: maybeKey\n };\n}\nexports.Fragment = REACT_FRAGMENT_TYPE;\nexports.jsx = jsxProd;\nexports.jsxs = jsxProd;\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react-jsx-runtime.production.js');\n} else {\n module.exports = require('./cjs/react-jsx-runtime.development.js');\n}\n","/**\n * @license React\n * react.production.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\nvar REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_PORTAL_TYPE = Symbol.for(\"react.portal\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\"),\n REACT_STRICT_MODE_TYPE = Symbol.for(\"react.strict_mode\"),\n REACT_PROFILER_TYPE = Symbol.for(\"react.profiler\"),\n REACT_CONSUMER_TYPE = Symbol.for(\"react.consumer\"),\n REACT_CONTEXT_TYPE = Symbol.for(\"react.context\"),\n REACT_FORWARD_REF_TYPE = Symbol.for(\"react.forward_ref\"),\n REACT_SUSPENSE_TYPE = Symbol.for(\"react.suspense\"),\n REACT_MEMO_TYPE = Symbol.for(\"react.memo\"),\n REACT_LAZY_TYPE = Symbol.for(\"react.lazy\"),\n MAYBE_ITERATOR_SYMBOL = Symbol.iterator;\nfunction getIteratorFn(maybeIterable) {\n if (null === maybeIterable || \"object\" !== typeof maybeIterable) return null;\n maybeIterable =\n (MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL]) ||\n maybeIterable[\"@@iterator\"];\n return \"function\" === typeof maybeIterable ? maybeIterable : null;\n}\nvar ReactNoopUpdateQueue = {\n isMounted: function () {\n return !1;\n },\n enqueueForceUpdate: function () {},\n enqueueReplaceState: function () {},\n enqueueSetState: function () {}\n },\n assign = Object.assign,\n emptyObject = {};\nfunction Component(props, context, updater) {\n this.props = props;\n this.context = context;\n this.refs = emptyObject;\n this.updater = updater || ReactNoopUpdateQueue;\n}\nComponent.prototype.isReactComponent = {};\nComponent.prototype.setState = function (partialState, callback) {\n if (\n \"object\" !== typeof partialState &&\n \"function\" !== typeof partialState &&\n null != partialState\n )\n throw Error(\n \"takes an object of state variables to update or a function which returns an object of state variables.\"\n );\n this.updater.enqueueSetState(this, partialState, callback, \"setState\");\n};\nComponent.prototype.forceUpdate = function (callback) {\n this.updater.enqueueForceUpdate(this, callback, \"forceUpdate\");\n};\nfunction ComponentDummy() {}\nComponentDummy.prototype = Component.prototype;\nfunction PureComponent(props, context, updater) {\n this.props = props;\n this.context = context;\n this.refs = emptyObject;\n this.updater = updater || ReactNoopUpdateQueue;\n}\nvar pureComponentPrototype = (PureComponent.prototype = new ComponentDummy());\npureComponentPrototype.constructor = PureComponent;\nassign(pureComponentPrototype, Component.prototype);\npureComponentPrototype.isPureReactComponent = !0;\nvar isArrayImpl = Array.isArray,\n ReactSharedInternals = { H: null, A: null, T: null, S: null, V: null },\n hasOwnProperty = Object.prototype.hasOwnProperty;\nfunction ReactElement(type, key, self, source, owner, props) {\n self = props.ref;\n return {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n ref: void 0 !== self ? self : null,\n props: props\n };\n}\nfunction cloneAndReplaceKey(oldElement, newKey) {\n return ReactElement(\n oldElement.type,\n newKey,\n void 0,\n void 0,\n void 0,\n oldElement.props\n );\n}\nfunction isValidElement(object) {\n return (\n \"object\" === typeof object &&\n null !== object &&\n object.$$typeof === REACT_ELEMENT_TYPE\n );\n}\nfunction escape(key) {\n var escaperLookup = { \"=\": \"=0\", \":\": \"=2\" };\n return (\n \"$\" +\n key.replace(/[=:]/g, function (match) {\n return escaperLookup[match];\n })\n );\n}\nvar userProvidedKeyEscapeRegex = /\\/+/g;\nfunction getElementKey(element, index) {\n return \"object\" === typeof element && null !== element && null != element.key\n ? escape(\"\" + element.key)\n : index.toString(36);\n}\nfunction noop$1() {}\nfunction resolveThenable(thenable) {\n switch (thenable.status) {\n case \"fulfilled\":\n return thenable.value;\n case \"rejected\":\n throw thenable.reason;\n default:\n switch (\n (\"string\" === typeof thenable.status\n ? thenable.then(noop$1, noop$1)\n : ((thenable.status = \"pending\"),\n thenable.then(\n function (fulfilledValue) {\n \"pending\" === thenable.status &&\n ((thenable.status = \"fulfilled\"),\n (thenable.value = fulfilledValue));\n },\n function (error) {\n \"pending\" === thenable.status &&\n ((thenable.status = \"rejected\"), (thenable.reason = error));\n }\n )),\n thenable.status)\n ) {\n case \"fulfilled\":\n return thenable.value;\n case \"rejected\":\n throw thenable.reason;\n }\n }\n throw thenable;\n}\nfunction mapIntoArray(children, array, escapedPrefix, nameSoFar, callback) {\n var type = typeof children;\n if (\"undefined\" === type || \"boolean\" === type) children = null;\n var invokeCallback = !1;\n if (null === children) invokeCallback = !0;\n else\n switch (type) {\n case \"bigint\":\n case \"string\":\n case \"number\":\n invokeCallback = !0;\n break;\n case \"object\":\n switch (children.$$typeof) {\n case REACT_ELEMENT_TYPE:\n case REACT_PORTAL_TYPE:\n invokeCallback = !0;\n break;\n case REACT_LAZY_TYPE:\n return (\n (invokeCallback = children._init),\n mapIntoArray(\n invokeCallback(children._payload),\n array,\n escapedPrefix,\n nameSoFar,\n callback\n )\n );\n }\n }\n if (invokeCallback)\n return (\n (callback = callback(children)),\n (invokeCallback =\n \"\" === nameSoFar ? \".\" + getElementKey(children, 0) : nameSoFar),\n isArrayImpl(callback)\n ? ((escapedPrefix = \"\"),\n null != invokeCallback &&\n (escapedPrefix =\n invokeCallback.replace(userProvidedKeyEscapeRegex, \"$&/\") + \"/\"),\n mapIntoArray(callback, array, escapedPrefix, \"\", function (c) {\n return c;\n }))\n : null != callback &&\n (isValidElement(callback) &&\n (callback = cloneAndReplaceKey(\n callback,\n escapedPrefix +\n (null == callback.key ||\n (children && children.key === callback.key)\n ? \"\"\n : (\"\" + callback.key).replace(\n userProvidedKeyEscapeRegex,\n \"$&/\"\n ) + \"/\") +\n invokeCallback\n )),\n array.push(callback)),\n 1\n );\n invokeCallback = 0;\n var nextNamePrefix = \"\" === nameSoFar ? \".\" : nameSoFar + \":\";\n if (isArrayImpl(children))\n for (var i = 0; i < children.length; i++)\n (nameSoFar = children[i]),\n (type = nextNamePrefix + getElementKey(nameSoFar, i)),\n (invokeCallback += mapIntoArray(\n nameSoFar,\n array,\n escapedPrefix,\n type,\n callback\n ));\n else if (((i = getIteratorFn(children)), \"function\" === typeof i))\n for (\n children = i.call(children), i = 0;\n !(nameSoFar = children.next()).done;\n\n )\n (nameSoFar = nameSoFar.value),\n (type = nextNamePrefix + getElementKey(nameSoFar, i++)),\n (invokeCallback += mapIntoArray(\n nameSoFar,\n array,\n escapedPrefix,\n type,\n callback\n ));\n else if (\"object\" === type) {\n if (\"function\" === typeof children.then)\n return mapIntoArray(\n resolveThenable(children),\n array,\n escapedPrefix,\n nameSoFar,\n callback\n );\n array = String(children);\n throw Error(\n \"Objects are not valid as a React child (found: \" +\n (\"[object Object]\" === array\n ? \"object with keys {\" + Object.keys(children).join(\", \") + \"}\"\n : array) +\n \"). If you meant to render a collection of children, use an array instead.\"\n );\n }\n return invokeCallback;\n}\nfunction mapChildren(children, func, context) {\n if (null == children) return children;\n var result = [],\n count = 0;\n mapIntoArray(children, result, \"\", \"\", function (child) {\n return func.call(context, child, count++);\n });\n return result;\n}\nfunction lazyInitializer(payload) {\n if (-1 === payload._status) {\n var ctor = payload._result;\n ctor = ctor();\n ctor.then(\n function (moduleObject) {\n if (0 === payload._status || -1 === payload._status)\n (payload._status = 1), (payload._result = moduleObject);\n },\n function (error) {\n if (0 === payload._status || -1 === payload._status)\n (payload._status = 2), (payload._result = error);\n }\n );\n -1 === payload._status && ((payload._status = 0), (payload._result = ctor));\n }\n if (1 === payload._status) return payload._result.default;\n throw payload._result;\n}\nvar reportGlobalError =\n \"function\" === typeof reportError\n ? reportError\n : function (error) {\n if (\n \"object\" === typeof window &&\n \"function\" === typeof window.ErrorEvent\n ) {\n var event = new window.ErrorEvent(\"error\", {\n bubbles: !0,\n cancelable: !0,\n message:\n \"object\" === typeof error &&\n null !== error &&\n \"string\" === typeof error.message\n ? String(error.message)\n : String(error),\n error: error\n });\n if (!window.dispatchEvent(event)) return;\n } else if (\n \"object\" === typeof process &&\n \"function\" === typeof process.emit\n ) {\n process.emit(\"uncaughtException\", error);\n return;\n }\n console.error(error);\n };\nfunction noop() {}\nexports.Children = {\n map: mapChildren,\n forEach: function (children, forEachFunc, forEachContext) {\n mapChildren(\n children,\n function () {\n forEachFunc.apply(this, arguments);\n },\n forEachContext\n );\n },\n count: function (children) {\n var n = 0;\n mapChildren(children, function () {\n n++;\n });\n return n;\n },\n toArray: function (children) {\n return (\n mapChildren(children, function (child) {\n return child;\n }) || []\n );\n },\n only: function (children) {\n if (!isValidElement(children))\n throw Error(\n \"React.Children.only expected to receive a single React element child.\"\n );\n return children;\n }\n};\nexports.Component = Component;\nexports.Fragment = REACT_FRAGMENT_TYPE;\nexports.Profiler = REACT_PROFILER_TYPE;\nexports.PureComponent = PureComponent;\nexports.StrictMode = REACT_STRICT_MODE_TYPE;\nexports.Suspense = REACT_SUSPENSE_TYPE;\nexports.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE =\n ReactSharedInternals;\nexports.__COMPILER_RUNTIME = {\n __proto__: null,\n c: function (size) {\n return ReactSharedInternals.H.useMemoCache(size);\n }\n};\nexports.cache = function (fn) {\n return function () {\n return fn.apply(null, arguments);\n };\n};\nexports.cloneElement = function (element, config, children) {\n if (null === element || void 0 === element)\n throw Error(\n \"The argument must be a React element, but you passed \" + element + \".\"\n );\n var props = assign({}, element.props),\n key = element.key,\n owner = void 0;\n if (null != config)\n for (propName in (void 0 !== config.ref && (owner = void 0),\n void 0 !== config.key && (key = \"\" + config.key),\n config))\n !hasOwnProperty.call(config, propName) ||\n \"key\" === propName ||\n \"__self\" === propName ||\n \"__source\" === propName ||\n (\"ref\" === propName && void 0 === config.ref) ||\n (props[propName] = config[propName]);\n var propName = arguments.length - 2;\n if (1 === propName) props.children = children;\n else if (1 < propName) {\n for (var childArray = Array(propName), i = 0; i < propName; i++)\n childArray[i] = arguments[i + 2];\n props.children = childArray;\n }\n return ReactElement(element.type, key, void 0, void 0, owner, props);\n};\nexports.createContext = function (defaultValue) {\n defaultValue = {\n $$typeof: REACT_CONTEXT_TYPE,\n _currentValue: defaultValue,\n _currentValue2: defaultValue,\n _threadCount: 0,\n Provider: null,\n Consumer: null\n };\n defaultValue.Provider = defaultValue;\n defaultValue.Consumer = {\n $$typeof: REACT_CONSUMER_TYPE,\n _context: defaultValue\n };\n return defaultValue;\n};\nexports.createElement = function (type, config, children) {\n var propName,\n props = {},\n key = null;\n if (null != config)\n for (propName in (void 0 !== config.key && (key = \"\" + config.key), config))\n hasOwnProperty.call(config, propName) &&\n \"key\" !== propName &&\n \"__self\" !== propName &&\n \"__source\" !== propName &&\n (props[propName] = config[propName]);\n var childrenLength = arguments.length - 2;\n if (1 === childrenLength) props.children = children;\n else if (1 < childrenLength) {\n for (var childArray = Array(childrenLength), i = 0; i < childrenLength; i++)\n childArray[i] = arguments[i + 2];\n props.children = childArray;\n }\n if (type && type.defaultProps)\n for (propName in ((childrenLength = type.defaultProps), childrenLength))\n void 0 === props[propName] &&\n (props[propName] = childrenLength[propName]);\n return ReactElement(type, key, void 0, void 0, null, props);\n};\nexports.createRef = function () {\n return { current: null };\n};\nexports.forwardRef = function (render) {\n return { $$typeof: REACT_FORWARD_REF_TYPE, render: render };\n};\nexports.isValidElement = isValidElement;\nexports.lazy = function (ctor) {\n return {\n $$typeof: REACT_LAZY_TYPE,\n _payload: { _status: -1, _result: ctor },\n _init: lazyInitializer\n };\n};\nexports.memo = function (type, compare) {\n return {\n $$typeof: REACT_MEMO_TYPE,\n type: type,\n compare: void 0 === compare ? null : compare\n };\n};\nexports.startTransition = function (scope) {\n var prevTransition = ReactSharedInternals.T,\n currentTransition = {};\n ReactSharedInternals.T = currentTransition;\n try {\n var returnValue = scope(),\n onStartTransitionFinish = ReactSharedInternals.S;\n null !== onStartTransitionFinish &&\n onStartTransitionFinish(currentTransition, returnValue);\n \"object\" === typeof returnValue &&\n null !== returnValue &&\n \"function\" === typeof returnValue.then &&\n returnValue.then(noop, reportGlobalError);\n } catch (error) {\n reportGlobalError(error);\n } finally {\n ReactSharedInternals.T = prevTransition;\n }\n};\nexports.unstable_useCacheRefresh = function () {\n return ReactSharedInternals.H.useCacheRefresh();\n};\nexports.use = function (usable) {\n return ReactSharedInternals.H.use(usable);\n};\nexports.useActionState = function (action, initialState, permalink) {\n return ReactSharedInternals.H.useActionState(action, initialState, permalink);\n};\nexports.useCallback = function (callback, deps) {\n return ReactSharedInternals.H.useCallback(callback, deps);\n};\nexports.useContext = function (Context) {\n return ReactSharedInternals.H.useContext(Context);\n};\nexports.useDebugValue = function () {};\nexports.useDeferredValue = function (value, initialValue) {\n return ReactSharedInternals.H.useDeferredValue(value, initialValue);\n};\nexports.useEffect = function (create, createDeps, update) {\n var dispatcher = ReactSharedInternals.H;\n if (\"function\" === typeof update)\n throw Error(\n \"useEffect CRUD overload is not enabled in this build of React.\"\n );\n return dispatcher.useEffect(create, createDeps);\n};\nexports.useId = function () {\n return ReactSharedInternals.H.useId();\n};\nexports.useImperativeHandle = function (ref, create, deps) {\n return ReactSharedInternals.H.useImperativeHandle(ref, create, deps);\n};\nexports.useInsertionEffect = function (create, deps) {\n return ReactSharedInternals.H.useInsertionEffect(create, deps);\n};\nexports.useLayoutEffect = function (create, deps) {\n return ReactSharedInternals.H.useLayoutEffect(create, deps);\n};\nexports.useMemo = function (create, deps) {\n return ReactSharedInternals.H.useMemo(create, deps);\n};\nexports.useOptimistic = function (passthrough, reducer) {\n return ReactSharedInternals.H.useOptimistic(passthrough, reducer);\n};\nexports.useReducer = function (reducer, initialArg, init) {\n return ReactSharedInternals.H.useReducer(reducer, initialArg, init);\n};\nexports.useRef = function (initialValue) {\n return ReactSharedInternals.H.useRef(initialValue);\n};\nexports.useState = function (initialState) {\n return ReactSharedInternals.H.useState(initialState);\n};\nexports.useSyncExternalStore = function (\n subscribe,\n getSnapshot,\n getServerSnapshot\n) {\n return ReactSharedInternals.H.useSyncExternalStore(\n subscribe,\n getSnapshot,\n getServerSnapshot\n );\n};\nexports.useTransition = function () {\n return ReactSharedInternals.H.useTransition();\n};\nexports.version = \"19.1.1\";\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react.production.js');\n} else {\n module.exports = require('./cjs/react.development.js');\n}\n","/**\n * @license React\n * scheduler.production.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\nfunction push(heap, node) {\n var index = heap.length;\n heap.push(node);\n a: for (; 0 < index; ) {\n var parentIndex = (index - 1) >>> 1,\n parent = heap[parentIndex];\n if (0 < compare(parent, node))\n (heap[parentIndex] = node), (heap[index] = parent), (index = parentIndex);\n else break a;\n }\n}\nfunction peek(heap) {\n return 0 === heap.length ? null : heap[0];\n}\nfunction pop(heap) {\n if (0 === heap.length) return null;\n var first = heap[0],\n last = heap.pop();\n if (last !== first) {\n heap[0] = last;\n a: for (\n var index = 0, length = heap.length, halfLength = length >>> 1;\n index < halfLength;\n\n ) {\n var leftIndex = 2 * (index + 1) - 1,\n left = heap[leftIndex],\n rightIndex = leftIndex + 1,\n right = heap[rightIndex];\n if (0 > compare(left, last))\n rightIndex < length && 0 > compare(right, left)\n ? ((heap[index] = right),\n (heap[rightIndex] = last),\n (index = rightIndex))\n : ((heap[index] = left),\n (heap[leftIndex] = last),\n (index = leftIndex));\n else if (rightIndex < length && 0 > compare(right, last))\n (heap[index] = right), (heap[rightIndex] = last), (index = rightIndex);\n else break a;\n }\n }\n return first;\n}\nfunction compare(a, b) {\n var diff = a.sortIndex - b.sortIndex;\n return 0 !== diff ? diff : a.id - b.id;\n}\nexports.unstable_now = void 0;\nif (\"object\" === typeof performance && \"function\" === typeof performance.now) {\n var localPerformance = performance;\n exports.unstable_now = function () {\n return localPerformance.now();\n };\n} else {\n var localDate = Date,\n initialTime = localDate.now();\n exports.unstable_now = function () {\n return localDate.now() - initialTime;\n };\n}\nvar taskQueue = [],\n timerQueue = [],\n taskIdCounter = 1,\n currentTask = null,\n currentPriorityLevel = 3,\n isPerformingWork = !1,\n isHostCallbackScheduled = !1,\n isHostTimeoutScheduled = !1,\n needsPaint = !1,\n localSetTimeout = \"function\" === typeof setTimeout ? setTimeout : null,\n localClearTimeout = \"function\" === typeof clearTimeout ? clearTimeout : null,\n localSetImmediate = \"undefined\" !== typeof setImmediate ? setImmediate : null;\nfunction advanceTimers(currentTime) {\n for (var timer = peek(timerQueue); null !== timer; ) {\n if (null === timer.callback) pop(timerQueue);\n else if (timer.startTime <= currentTime)\n pop(timerQueue),\n (timer.sortIndex = timer.expirationTime),\n push(taskQueue, timer);\n else break;\n timer = peek(timerQueue);\n }\n}\nfunction handleTimeout(currentTime) {\n isHostTimeoutScheduled = !1;\n advanceTimers(currentTime);\n if (!isHostCallbackScheduled)\n if (null !== peek(taskQueue))\n (isHostCallbackScheduled = !0),\n isMessageLoopRunning ||\n ((isMessageLoopRunning = !0), schedulePerformWorkUntilDeadline());\n else {\n var firstTimer = peek(timerQueue);\n null !== firstTimer &&\n requestHostTimeout(handleTimeout, firstTimer.startTime - currentTime);\n }\n}\nvar isMessageLoopRunning = !1,\n taskTimeoutID = -1,\n frameInterval = 5,\n startTime = -1;\nfunction shouldYieldToHost() {\n return needsPaint\n ? !0\n : exports.unstable_now() - startTime < frameInterval\n ? !1\n : !0;\n}\nfunction performWorkUntilDeadline() {\n needsPaint = !1;\n if (isMessageLoopRunning) {\n var currentTime = exports.unstable_now();\n startTime = currentTime;\n var hasMoreWork = !0;\n try {\n a: {\n isHostCallbackScheduled = !1;\n isHostTimeoutScheduled &&\n ((isHostTimeoutScheduled = !1),\n localClearTimeout(taskTimeoutID),\n (taskTimeoutID = -1));\n isPerformingWork = !0;\n var previousPriorityLevel = currentPriorityLevel;\n try {\n b: {\n advanceTimers(currentTime);\n for (\n currentTask = peek(taskQueue);\n null !== currentTask &&\n !(\n currentTask.expirationTime > currentTime && shouldYieldToHost()\n );\n\n ) {\n var callback = currentTask.callback;\n if (\"function\" === typeof callback) {\n currentTask.callback = null;\n currentPriorityLevel = currentTask.priorityLevel;\n var continuationCallback = callback(\n currentTask.expirationTime <= currentTime\n );\n currentTime = exports.unstable_now();\n if (\"function\" === typeof continuationCallback) {\n currentTask.callback = continuationCallback;\n advanceTimers(currentTime);\n hasMoreWork = !0;\n break b;\n }\n currentTask === peek(taskQueue) && pop(taskQueue);\n advanceTimers(currentTime);\n } else pop(taskQueue);\n currentTask = peek(taskQueue);\n }\n if (null !== currentTask) hasMoreWork = !0;\n else {\n var firstTimer = peek(timerQueue);\n null !== firstTimer &&\n requestHostTimeout(\n handleTimeout,\n firstTimer.startTime - currentTime\n );\n hasMoreWork = !1;\n }\n }\n break a;\n } finally {\n (currentTask = null),\n (currentPriorityLevel = previousPriorityLevel),\n (isPerformingWork = !1);\n }\n hasMoreWork = void 0;\n }\n } finally {\n hasMoreWork\n ? schedulePerformWorkUntilDeadline()\n : (isMessageLoopRunning = !1);\n }\n }\n}\nvar schedulePerformWorkUntilDeadline;\nif (\"function\" === typeof localSetImmediate)\n schedulePerformWorkUntilDeadline = function () {\n localSetImmediate(performWorkUntilDeadline);\n };\nelse if (\"undefined\" !== typeof MessageChannel) {\n var channel = new MessageChannel(),\n port = channel.port2;\n channel.port1.onmessage = performWorkUntilDeadline;\n schedulePerformWorkUntilDeadline = function () {\n port.postMessage(null);\n };\n} else\n schedulePerformWorkUntilDeadline = function () {\n localSetTimeout(performWorkUntilDeadline, 0);\n };\nfunction requestHostTimeout(callback, ms) {\n taskTimeoutID = localSetTimeout(function () {\n callback(exports.unstable_now());\n }, ms);\n}\nexports.unstable_IdlePriority = 5;\nexports.unstable_ImmediatePriority = 1;\nexports.unstable_LowPriority = 4;\nexports.unstable_NormalPriority = 3;\nexports.unstable_Profiling = null;\nexports.unstable_UserBlockingPriority = 2;\nexports.unstable_cancelCallback = function (task) {\n task.callback = null;\n};\nexports.unstable_forceFrameRate = function (fps) {\n 0 > fps || 125 < fps\n ? console.error(\n \"forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported\"\n )\n : (frameInterval = 0 < fps ? Math.floor(1e3 / fps) : 5);\n};\nexports.unstable_getCurrentPriorityLevel = function () {\n return currentPriorityLevel;\n};\nexports.unstable_next = function (eventHandler) {\n switch (currentPriorityLevel) {\n case 1:\n case 2:\n case 3:\n var priorityLevel = 3;\n break;\n default:\n priorityLevel = currentPriorityLevel;\n }\n var previousPriorityLevel = currentPriorityLevel;\n currentPriorityLevel = priorityLevel;\n try {\n return eventHandler();\n } finally {\n currentPriorityLevel = previousPriorityLevel;\n }\n};\nexports.unstable_requestPaint = function () {\n needsPaint = !0;\n};\nexports.unstable_runWithPriority = function (priorityLevel, eventHandler) {\n switch (priorityLevel) {\n case 1:\n case 2:\n case 3:\n case 4:\n case 5:\n break;\n default:\n priorityLevel = 3;\n }\n var previousPriorityLevel = currentPriorityLevel;\n currentPriorityLevel = priorityLevel;\n try {\n return eventHandler();\n } finally {\n currentPriorityLevel = previousPriorityLevel;\n }\n};\nexports.unstable_scheduleCallback = function (\n priorityLevel,\n callback,\n options\n) {\n var currentTime = exports.unstable_now();\n \"object\" === typeof options && null !== options\n ? ((options = options.delay),\n (options =\n \"number\" === typeof options && 0 < options\n ? currentTime + options\n : currentTime))\n : (options = currentTime);\n switch (priorityLevel) {\n case 1:\n var timeout = -1;\n break;\n case 2:\n timeout = 250;\n break;\n case 5:\n timeout = 1073741823;\n break;\n case 4:\n timeout = 1e4;\n break;\n default:\n timeout = 5e3;\n }\n timeout = options + timeout;\n priorityLevel = {\n id: taskIdCounter++,\n callback: callback,\n priorityLevel: priorityLevel,\n startTime: options,\n expirationTime: timeout,\n sortIndex: -1\n };\n options > currentTime\n ? ((priorityLevel.sortIndex = options),\n push(timerQueue, priorityLevel),\n null === peek(taskQueue) &&\n priorityLevel === peek(timerQueue) &&\n (isHostTimeoutScheduled\n ? (localClearTimeout(taskTimeoutID), (taskTimeoutID = -1))\n : (isHostTimeoutScheduled = !0),\n requestHostTimeout(handleTimeout, options - currentTime)))\n : ((priorityLevel.sortIndex = timeout),\n push(taskQueue, priorityLevel),\n isHostCallbackScheduled ||\n isPerformingWork ||\n ((isHostCallbackScheduled = !0),\n isMessageLoopRunning ||\n ((isMessageLoopRunning = !0), schedulePerformWorkUntilDeadline())));\n return priorityLevel;\n};\nexports.unstable_shouldYield = shouldYieldToHost;\nexports.unstable_wrapCallback = function (callback) {\n var parentPriorityLevel = currentPriorityLevel;\n return function () {\n var previousPriorityLevel = currentPriorityLevel;\n currentPriorityLevel = parentPriorityLevel;\n try {\n return callback.apply(this, arguments);\n } finally {\n currentPriorityLevel = previousPriorityLevel;\n }\n };\n};\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/scheduler.production.js');\n} else {\n module.exports = require('./cjs/scheduler.development.js');\n}\n","/**\n * @license React\n * react-dom.production.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\nvar React = require(\"react\");\nfunction formatProdErrorMessage(code) {\n var url = \"https://react.dev/errors/\" + code;\n if (1 < arguments.length) {\n url += \"?args[]=\" + encodeURIComponent(arguments[1]);\n for (var i = 2; i < arguments.length; i++)\n url += \"&args[]=\" + encodeURIComponent(arguments[i]);\n }\n return (\n \"Minified React error #\" +\n code +\n \"; visit \" +\n url +\n \" for the full message or use the non-minified dev environment for full errors and additional helpful warnings.\"\n );\n}\nfunction noop() {}\nvar Internals = {\n d: {\n f: noop,\n r: function () {\n throw Error(formatProdErrorMessage(522));\n },\n D: noop,\n C: noop,\n L: noop,\n m: noop,\n X: noop,\n S: noop,\n M: noop\n },\n p: 0,\n findDOMNode: null\n },\n REACT_PORTAL_TYPE = Symbol.for(\"react.portal\");\nfunction createPortal$1(children, containerInfo, implementation) {\n var key =\n 3 < arguments.length && void 0 !== arguments[3] ? arguments[3] : null;\n return {\n $$typeof: REACT_PORTAL_TYPE,\n key: null == key ? null : \"\" + key,\n children: children,\n containerInfo: containerInfo,\n implementation: implementation\n };\n}\nvar ReactSharedInternals =\n React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;\nfunction getCrossOriginStringAs(as, input) {\n if (\"font\" === as) return \"\";\n if (\"string\" === typeof input)\n return \"use-credentials\" === input ? input : \"\";\n}\nexports.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE =\n Internals;\nexports.createPortal = function (children, container) {\n var key =\n 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : null;\n if (\n !container ||\n (1 !== container.nodeType &&\n 9 !== container.nodeType &&\n 11 !== container.nodeType)\n )\n throw Error(formatProdErrorMessage(299));\n return createPortal$1(children, container, null, key);\n};\nexports.flushSync = function (fn) {\n var previousTransition = ReactSharedInternals.T,\n previousUpdatePriority = Internals.p;\n try {\n if (((ReactSharedInternals.T = null), (Internals.p = 2), fn)) return fn();\n } finally {\n (ReactSharedInternals.T = previousTransition),\n (Internals.p = previousUpdatePriority),\n Internals.d.f();\n }\n};\nexports.preconnect = function (href, options) {\n \"string\" === typeof href &&\n (options\n ? ((options = options.crossOrigin),\n (options =\n \"string\" === typeof options\n ? \"use-credentials\" === options\n ? options\n : \"\"\n : void 0))\n : (options = null),\n Internals.d.C(href, options));\n};\nexports.prefetchDNS = function (href) {\n \"string\" === typeof href && Internals.d.D(href);\n};\nexports.preinit = function (href, options) {\n if (\"string\" === typeof href && options && \"string\" === typeof options.as) {\n var as = options.as,\n crossOrigin = getCrossOriginStringAs(as, options.crossOrigin),\n integrity =\n \"string\" === typeof options.integrity ? options.integrity : void 0,\n fetchPriority =\n \"string\" === typeof options.fetchPriority\n ? options.fetchPriority\n : void 0;\n \"style\" === as\n ? Internals.d.S(\n href,\n \"string\" === typeof options.precedence ? options.precedence : void 0,\n {\n crossOrigin: crossOrigin,\n integrity: integrity,\n fetchPriority: fetchPriority\n }\n )\n : \"script\" === as &&\n Internals.d.X(href, {\n crossOrigin: crossOrigin,\n integrity: integrity,\n fetchPriority: fetchPriority,\n nonce: \"string\" === typeof options.nonce ? options.nonce : void 0\n });\n }\n};\nexports.preinitModule = function (href, options) {\n if (\"string\" === typeof href)\n if (\"object\" === typeof options && null !== options) {\n if (null == options.as || \"script\" === options.as) {\n var crossOrigin = getCrossOriginStringAs(\n options.as,\n options.crossOrigin\n );\n Internals.d.M(href, {\n crossOrigin: crossOrigin,\n integrity:\n \"string\" === typeof options.integrity ? options.integrity : void 0,\n nonce: \"string\" === typeof options.nonce ? options.nonce : void 0\n });\n }\n } else null == options && Internals.d.M(href);\n};\nexports.preload = function (href, options) {\n if (\n \"string\" === typeof href &&\n \"object\" === typeof options &&\n null !== options &&\n \"string\" === typeof options.as\n ) {\n var as = options.as,\n crossOrigin = getCrossOriginStringAs(as, options.crossOrigin);\n Internals.d.L(href, as, {\n crossOrigin: crossOrigin,\n integrity:\n \"string\" === typeof options.integrity ? options.integrity : void 0,\n nonce: \"string\" === typeof options.nonce ? options.nonce : void 0,\n type: \"string\" === typeof options.type ? options.type : void 0,\n fetchPriority:\n \"string\" === typeof options.fetchPriority\n ? options.fetchPriority\n : void 0,\n referrerPolicy:\n \"string\" === typeof options.referrerPolicy\n ? options.referrerPolicy\n : void 0,\n imageSrcSet:\n \"string\" === typeof options.imageSrcSet ? options.imageSrcSet : void 0,\n imageSizes:\n \"string\" === typeof options.imageSizes ? options.imageSizes : void 0,\n media: \"string\" === typeof options.media ? options.media : void 0\n });\n }\n};\nexports.preloadModule = function (href, options) {\n if (\"string\" === typeof href)\n if (options) {\n var crossOrigin = getCrossOriginStringAs(options.as, options.crossOrigin);\n Internals.d.m(href, {\n as:\n \"string\" === typeof options.as && \"script\" !== options.as\n ? options.as\n : void 0,\n crossOrigin: crossOrigin,\n integrity:\n \"string\" === typeof options.integrity ? options.integrity : void 0\n });\n } else Internals.d.m(href);\n};\nexports.requestFormReset = function (form) {\n Internals.d.r(form);\n};\nexports.unstable_batchedUpdates = function (fn, a) {\n return fn(a);\n};\nexports.useFormState = function (action, initialState, permalink) {\n return ReactSharedInternals.H.useFormState(action, initialState, permalink);\n};\nexports.useFormStatus = function () {\n return ReactSharedInternals.H.useHostTransitionStatus();\n};\nexports.version = \"19.1.1\";\n","'use strict';\n\nfunction checkDCE() {\n /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */\n if (\n typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined' ||\n typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE !== 'function'\n ) {\n return;\n }\n if (process.env.NODE_ENV !== 'production') {\n // This branch is unreachable because this function is only called\n // in production, but the condition is true only in development.\n // Therefore if the branch is still here, dead code elimination wasn't\n // properly applied.\n // Don't change the message. React DevTools relies on it. Also make sure\n // this message doesn't occur elsewhere in this function, or it will cause\n // a false positive.\n throw new Error('^_^');\n }\n try {\n // Verify that the code above has been dead code eliminated (DCE'd).\n __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(checkDCE);\n } catch (err) {\n // DevTools shouldn't crash React, no matter what.\n // We should still report in case we break this code.\n console.error(err);\n }\n}\n\nif (process.env.NODE_ENV === 'production') {\n // DCE check should happen before ReactDOM bundle executes so that\n // DevTools can report bad minification during injection.\n checkDCE();\n module.exports = require('./cjs/react-dom.production.js');\n} else {\n module.exports = require('./cjs/react-dom.development.js');\n}\n","/**\n * @license React\n * react-dom-client.production.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n/*\n Modernizr 3.0.0pre (Custom Build) | MIT\n*/\n\"use strict\";\nvar Scheduler = require(\"scheduler\"),\n React = require(\"react\"),\n ReactDOM = require(\"react-dom\");\nfunction formatProdErrorMessage(code) {\n var url = \"https://react.dev/errors/\" + code;\n if (1 < arguments.length) {\n url += \"?args[]=\" + encodeURIComponent(arguments[1]);\n for (var i = 2; i < arguments.length; i++)\n url += \"&args[]=\" + encodeURIComponent(arguments[i]);\n }\n return (\n \"Minified React error #\" +\n code +\n \"; visit \" +\n url +\n \" for the full message or use the non-minified dev environment for full errors and additional helpful warnings.\"\n );\n}\nfunction isValidContainer(node) {\n return !(\n !node ||\n (1 !== node.nodeType && 9 !== node.nodeType && 11 !== node.nodeType)\n );\n}\nfunction getNearestMountedFiber(fiber) {\n var node = fiber,\n nearestMounted = fiber;\n if (fiber.alternate) for (; node.return; ) node = node.return;\n else {\n fiber = node;\n do\n (node = fiber),\n 0 !== (node.flags & 4098) && (nearestMounted = node.return),\n (fiber = node.return);\n while (fiber);\n }\n return 3 === node.tag ? nearestMounted : null;\n}\nfunction getSuspenseInstanceFromFiber(fiber) {\n if (13 === fiber.tag) {\n var suspenseState = fiber.memoizedState;\n null === suspenseState &&\n ((fiber = fiber.alternate),\n null !== fiber && (suspenseState = fiber.memoizedState));\n if (null !== suspenseState) return suspenseState.dehydrated;\n }\n return null;\n}\nfunction assertIsMounted(fiber) {\n if (getNearestMountedFiber(fiber) !== fiber)\n throw Error(formatProdErrorMessage(188));\n}\nfunction findCurrentFiberUsingSlowPath(fiber) {\n var alternate = fiber.alternate;\n if (!alternate) {\n alternate = getNearestMountedFiber(fiber);\n if (null === alternate) throw Error(formatProdErrorMessage(188));\n return alternate !== fiber ? null : fiber;\n }\n for (var a = fiber, b = alternate; ; ) {\n var parentA = a.return;\n if (null === parentA) break;\n var parentB = parentA.alternate;\n if (null === parentB) {\n b = parentA.return;\n if (null !== b) {\n a = b;\n continue;\n }\n break;\n }\n if (parentA.child === parentB.child) {\n for (parentB = parentA.child; parentB; ) {\n if (parentB === a) return assertIsMounted(parentA), fiber;\n if (parentB === b) return assertIsMounted(parentA), alternate;\n parentB = parentB.sibling;\n }\n throw Error(formatProdErrorMessage(188));\n }\n if (a.return !== b.return) (a = parentA), (b = parentB);\n else {\n for (var didFindChild = !1, child$0 = parentA.child; child$0; ) {\n if (child$0 === a) {\n didFindChild = !0;\n a = parentA;\n b = parentB;\n break;\n }\n if (child$0 === b) {\n didFindChild = !0;\n b = parentA;\n a = parentB;\n break;\n }\n child$0 = child$0.sibling;\n }\n if (!didFindChild) {\n for (child$0 = parentB.child; child$0; ) {\n if (child$0 === a) {\n didFindChild = !0;\n a = parentB;\n b = parentA;\n break;\n }\n if (child$0 === b) {\n didFindChild = !0;\n b = parentB;\n a = parentA;\n break;\n }\n child$0 = child$0.sibling;\n }\n if (!didFindChild) throw Error(formatProdErrorMessage(189));\n }\n }\n if (a.alternate !== b) throw Error(formatProdErrorMessage(190));\n }\n if (3 !== a.tag) throw Error(formatProdErrorMessage(188));\n return a.stateNode.current === a ? fiber : alternate;\n}\nfunction findCurrentHostFiberImpl(node) {\n var tag = node.tag;\n if (5 === tag || 26 === tag || 27 === tag || 6 === tag) return node;\n for (node = node.child; null !== node; ) {\n tag = findCurrentHostFiberImpl(node);\n if (null !== tag) return tag;\n node = node.sibling;\n }\n return null;\n}\nvar assign = Object.assign,\n REACT_LEGACY_ELEMENT_TYPE = Symbol.for(\"react.element\"),\n REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_PORTAL_TYPE = Symbol.for(\"react.portal\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\"),\n REACT_STRICT_MODE_TYPE = Symbol.for(\"react.strict_mode\"),\n REACT_PROFILER_TYPE = Symbol.for(\"react.profiler\"),\n REACT_PROVIDER_TYPE = Symbol.for(\"react.provider\"),\n REACT_CONSUMER_TYPE = Symbol.for(\"react.consumer\"),\n REACT_CONTEXT_TYPE = Symbol.for(\"react.context\"),\n REACT_FORWARD_REF_TYPE = Symbol.for(\"react.forward_ref\"),\n REACT_SUSPENSE_TYPE = Symbol.for(\"react.suspense\"),\n REACT_SUSPENSE_LIST_TYPE = Symbol.for(\"react.suspense_list\"),\n REACT_MEMO_TYPE = Symbol.for(\"react.memo\"),\n REACT_LAZY_TYPE = Symbol.for(\"react.lazy\");\nSymbol.for(\"react.scope\");\nvar REACT_ACTIVITY_TYPE = Symbol.for(\"react.activity\");\nSymbol.for(\"react.legacy_hidden\");\nSymbol.for(\"react.tracing_marker\");\nvar REACT_MEMO_CACHE_SENTINEL = Symbol.for(\"react.memo_cache_sentinel\");\nSymbol.for(\"react.view_transition\");\nvar MAYBE_ITERATOR_SYMBOL = Symbol.iterator;\nfunction getIteratorFn(maybeIterable) {\n if (null === maybeIterable || \"object\" !== typeof maybeIterable) return null;\n maybeIterable =\n (MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL]) ||\n maybeIterable[\"@@iterator\"];\n return \"function\" === typeof maybeIterable ? maybeIterable : null;\n}\nvar REACT_CLIENT_REFERENCE = Symbol.for(\"react.client.reference\");\nfunction getComponentNameFromType(type) {\n if (null == type) return null;\n if (\"function\" === typeof type)\n return type.$$typeof === REACT_CLIENT_REFERENCE\n ? null\n : type.displayName || type.name || null;\n if (\"string\" === typeof type) return type;\n switch (type) {\n case REACT_FRAGMENT_TYPE:\n return \"Fragment\";\n case REACT_PROFILER_TYPE:\n return \"Profiler\";\n case REACT_STRICT_MODE_TYPE:\n return \"StrictMode\";\n case REACT_SUSPENSE_TYPE:\n return \"Suspense\";\n case REACT_SUSPENSE_LIST_TYPE:\n return \"SuspenseList\";\n case REACT_ACTIVITY_TYPE:\n return \"Activity\";\n }\n if (\"object\" === typeof type)\n switch (type.$$typeof) {\n case REACT_PORTAL_TYPE:\n return \"Portal\";\n case REACT_CONTEXT_TYPE:\n return (type.displayName || \"Context\") + \".Provider\";\n case REACT_CONSUMER_TYPE:\n return (type._context.displayName || \"Context\") + \".Consumer\";\n case REACT_FORWARD_REF_TYPE:\n var innerType = type.render;\n type = type.displayName;\n type ||\n ((type = innerType.displayName || innerType.name || \"\"),\n (type = \"\" !== type ? \"ForwardRef(\" + type + \")\" : \"ForwardRef\"));\n return type;\n case REACT_MEMO_TYPE:\n return (\n (innerType = type.displayName || null),\n null !== innerType\n ? innerType\n : getComponentNameFromType(type.type) || \"Memo\"\n );\n case REACT_LAZY_TYPE:\n innerType = type._payload;\n type = type._init;\n try {\n return getComponentNameFromType(type(innerType));\n } catch (x) {}\n }\n return null;\n}\nvar isArrayImpl = Array.isArray,\n ReactSharedInternals =\n React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,\n ReactDOMSharedInternals =\n ReactDOM.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,\n sharedNotPendingObject = {\n pending: !1,\n data: null,\n method: null,\n action: null\n },\n valueStack = [],\n index = -1;\nfunction createCursor(defaultValue) {\n return { current: defaultValue };\n}\nfunction pop(cursor) {\n 0 > index ||\n ((cursor.current = valueStack[index]), (valueStack[index] = null), index--);\n}\nfunction push(cursor, value) {\n index++;\n valueStack[index] = cursor.current;\n cursor.current = value;\n}\nvar contextStackCursor = createCursor(null),\n contextFiberStackCursor = createCursor(null),\n rootInstanceStackCursor = createCursor(null),\n hostTransitionProviderCursor = createCursor(null);\nfunction pushHostContainer(fiber, nextRootInstance) {\n push(rootInstanceStackCursor, nextRootInstance);\n push(contextFiberStackCursor, fiber);\n push(contextStackCursor, null);\n switch (nextRootInstance.nodeType) {\n case 9:\n case 11:\n fiber = (fiber = nextRootInstance.documentElement)\n ? (fiber = fiber.namespaceURI)\n ? getOwnHostContext(fiber)\n : 0\n : 0;\n break;\n default:\n if (\n ((fiber = nextRootInstance.tagName),\n (nextRootInstance = nextRootInstance.namespaceURI))\n )\n (nextRootInstance = getOwnHostContext(nextRootInstance)),\n (fiber = getChildHostContextProd(nextRootInstance, fiber));\n else\n switch (fiber) {\n case \"svg\":\n fiber = 1;\n break;\n case \"math\":\n fiber = 2;\n break;\n default:\n fiber = 0;\n }\n }\n pop(contextStackCursor);\n push(contextStackCursor, fiber);\n}\nfunction popHostContainer() {\n pop(contextStackCursor);\n pop(contextFiberStackCursor);\n pop(rootInstanceStackCursor);\n}\nfunction pushHostContext(fiber) {\n null !== fiber.memoizedState && push(hostTransitionProviderCursor, fiber);\n var context = contextStackCursor.current;\n var JSCompiler_inline_result = getChildHostContextProd(context, fiber.type);\n context !== JSCompiler_inline_result &&\n (push(contextFiberStackCursor, fiber),\n push(contextStackCursor, JSCompiler_inline_result));\n}\nfunction popHostContext(fiber) {\n contextFiberStackCursor.current === fiber &&\n (pop(contextStackCursor), pop(contextFiberStackCursor));\n hostTransitionProviderCursor.current === fiber &&\n (pop(hostTransitionProviderCursor),\n (HostTransitionContext._currentValue = sharedNotPendingObject));\n}\nvar hasOwnProperty = Object.prototype.hasOwnProperty,\n scheduleCallback$3 = Scheduler.unstable_scheduleCallback,\n cancelCallback$1 = Scheduler.unstable_cancelCallback,\n shouldYield = Scheduler.unstable_shouldYield,\n requestPaint = Scheduler.unstable_requestPaint,\n now = Scheduler.unstable_now,\n getCurrentPriorityLevel = Scheduler.unstable_getCurrentPriorityLevel,\n ImmediatePriority = Scheduler.unstable_ImmediatePriority,\n UserBlockingPriority = Scheduler.unstable_UserBlockingPriority,\n NormalPriority$1 = Scheduler.unstable_NormalPriority,\n LowPriority = Scheduler.unstable_LowPriority,\n IdlePriority = Scheduler.unstable_IdlePriority,\n log$1 = Scheduler.log,\n unstable_setDisableYieldValue = Scheduler.unstable_setDisableYieldValue,\n rendererID = null,\n injectedHook = null;\nfunction setIsStrictModeForDevtools(newIsStrictMode) {\n \"function\" === typeof log$1 && unstable_setDisableYieldValue(newIsStrictMode);\n if (injectedHook && \"function\" === typeof injectedHook.setStrictMode)\n try {\n injectedHook.setStrictMode(rendererID, newIsStrictMode);\n } catch (err) {}\n}\nvar clz32 = Math.clz32 ? Math.clz32 : clz32Fallback,\n log = Math.log,\n LN2 = Math.LN2;\nfunction clz32Fallback(x) {\n x >>>= 0;\n return 0 === x ? 32 : (31 - ((log(x) / LN2) | 0)) | 0;\n}\nvar nextTransitionLane = 256,\n nextRetryLane = 4194304;\nfunction getHighestPriorityLanes(lanes) {\n var pendingSyncLanes = lanes & 42;\n if (0 !== pendingSyncLanes) return pendingSyncLanes;\n switch (lanes & -lanes) {\n case 1:\n return 1;\n case 2:\n return 2;\n case 4:\n return 4;\n case 8:\n return 8;\n case 16:\n return 16;\n case 32:\n return 32;\n case 64:\n return 64;\n case 128:\n return 128;\n case 256:\n case 512:\n case 1024:\n case 2048:\n case 4096:\n case 8192:\n case 16384:\n case 32768:\n case 65536:\n case 131072:\n case 262144:\n case 524288:\n case 1048576:\n case 2097152:\n return lanes & 4194048;\n case 4194304:\n case 8388608:\n case 16777216:\n case 33554432:\n return lanes & 62914560;\n case 67108864:\n return 67108864;\n case 134217728:\n return 134217728;\n case 268435456:\n return 268435456;\n case 536870912:\n return 536870912;\n case 1073741824:\n return 0;\n default:\n return lanes;\n }\n}\nfunction getNextLanes(root, wipLanes, rootHasPendingCommit) {\n var pendingLanes = root.pendingLanes;\n if (0 === pendingLanes) return 0;\n var nextLanes = 0,\n suspendedLanes = root.suspendedLanes,\n pingedLanes = root.pingedLanes;\n root = root.warmLanes;\n var nonIdlePendingLanes = pendingLanes & 134217727;\n 0 !== nonIdlePendingLanes\n ? ((pendingLanes = nonIdlePendingLanes & ~suspendedLanes),\n 0 !== pendingLanes\n ? (nextLanes = getHighestPriorityLanes(pendingLanes))\n : ((pingedLanes &= nonIdlePendingLanes),\n 0 !== pingedLanes\n ? (nextLanes = getHighestPriorityLanes(pingedLanes))\n : rootHasPendingCommit ||\n ((rootHasPendingCommit = nonIdlePendingLanes & ~root),\n 0 !== rootHasPendingCommit &&\n (nextLanes = getHighestPriorityLanes(rootHasPendingCommit)))))\n : ((nonIdlePendingLanes = pendingLanes & ~suspendedLanes),\n 0 !== nonIdlePendingLanes\n ? (nextLanes = getHighestPriorityLanes(nonIdlePendingLanes))\n : 0 !== pingedLanes\n ? (nextLanes = getHighestPriorityLanes(pingedLanes))\n : rootHasPendingCommit ||\n ((rootHasPendingCommit = pendingLanes & ~root),\n 0 !== rootHasPendingCommit &&\n (nextLanes = getHighestPriorityLanes(rootHasPendingCommit))));\n return 0 === nextLanes\n ? 0\n : 0 !== wipLanes &&\n wipLanes !== nextLanes &&\n 0 === (wipLanes & suspendedLanes) &&\n ((suspendedLanes = nextLanes & -nextLanes),\n (rootHasPendingCommit = wipLanes & -wipLanes),\n suspendedLanes >= rootHasPendingCommit ||\n (32 === suspendedLanes && 0 !== (rootHasPendingCommit & 4194048)))\n ? wipLanes\n : nextLanes;\n}\nfunction checkIfRootIsPrerendering(root, renderLanes) {\n return (\n 0 ===\n (root.pendingLanes &\n ~(root.suspendedLanes & ~root.pingedLanes) &\n renderLanes)\n );\n}\nfunction computeExpirationTime(lane, currentTime) {\n switch (lane) {\n case 1:\n case 2:\n case 4:\n case 8:\n case 64:\n return currentTime + 250;\n case 16:\n case 32:\n case 128:\n case 256:\n case 512:\n case 1024:\n case 2048:\n case 4096:\n case 8192:\n case 16384:\n case 32768:\n case 65536:\n case 131072:\n case 262144:\n case 524288:\n case 1048576:\n case 2097152:\n return currentTime + 5e3;\n case 4194304:\n case 8388608:\n case 16777216:\n case 33554432:\n return -1;\n case 67108864:\n case 134217728:\n case 268435456:\n case 536870912:\n case 1073741824:\n return -1;\n default:\n return -1;\n }\n}\nfunction claimNextTransitionLane() {\n var lane = nextTransitionLane;\n nextTransitionLane <<= 1;\n 0 === (nextTransitionLane & 4194048) && (nextTransitionLane = 256);\n return lane;\n}\nfunction claimNextRetryLane() {\n var lane = nextRetryLane;\n nextRetryLane <<= 1;\n 0 === (nextRetryLane & 62914560) && (nextRetryLane = 4194304);\n return lane;\n}\nfunction createLaneMap(initial) {\n for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial);\n return laneMap;\n}\nfunction markRootUpdated$1(root, updateLane) {\n root.pendingLanes |= updateLane;\n 268435456 !== updateLane &&\n ((root.suspendedLanes = 0), (root.pingedLanes = 0), (root.warmLanes = 0));\n}\nfunction markRootFinished(\n root,\n finishedLanes,\n remainingLanes,\n spawnedLane,\n updatedLanes,\n suspendedRetryLanes\n) {\n var previouslyPendingLanes = root.pendingLanes;\n root.pendingLanes = remainingLanes;\n root.suspendedLanes = 0;\n root.pingedLanes = 0;\n root.warmLanes = 0;\n root.expiredLanes &= remainingLanes;\n root.entangledLanes &= remainingLanes;\n root.errorRecoveryDisabledLanes &= remainingLanes;\n root.shellSuspendCounter = 0;\n var entanglements = root.entanglements,\n expirationTimes = root.expirationTimes,\n hiddenUpdates = root.hiddenUpdates;\n for (\n remainingLanes = previouslyPendingLanes & ~remainingLanes;\n 0 < remainingLanes;\n\n ) {\n var index$5 = 31 - clz32(remainingLanes),\n lane = 1 << index$5;\n entanglements[index$5] = 0;\n expirationTimes[index$5] = -1;\n var hiddenUpdatesForLane = hiddenUpdates[index$5];\n if (null !== hiddenUpdatesForLane)\n for (\n hiddenUpdates[index$5] = null, index$5 = 0;\n index$5 < hiddenUpdatesForLane.length;\n index$5++\n ) {\n var update = hiddenUpdatesForLane[index$5];\n null !== update && (update.lane &= -536870913);\n }\n remainingLanes &= ~lane;\n }\n 0 !== spawnedLane && markSpawnedDeferredLane(root, spawnedLane, 0);\n 0 !== suspendedRetryLanes &&\n 0 === updatedLanes &&\n 0 !== root.tag &&\n (root.suspendedLanes |=\n suspendedRetryLanes & ~(previouslyPendingLanes & ~finishedLanes));\n}\nfunction markSpawnedDeferredLane(root, spawnedLane, entangledLanes) {\n root.pendingLanes |= spawnedLane;\n root.suspendedLanes &= ~spawnedLane;\n var spawnedLaneIndex = 31 - clz32(spawnedLane);\n root.entangledLanes |= spawnedLane;\n root.entanglements[spawnedLaneIndex] =\n root.entanglements[spawnedLaneIndex] |\n 1073741824 |\n (entangledLanes & 4194090);\n}\nfunction markRootEntangled(root, entangledLanes) {\n var rootEntangledLanes = (root.entangledLanes |= entangledLanes);\n for (root = root.entanglements; rootEntangledLanes; ) {\n var index$6 = 31 - clz32(rootEntangledLanes),\n lane = 1 << index$6;\n (lane & entangledLanes) | (root[index$6] & entangledLanes) &&\n (root[index$6] |= entangledLanes);\n rootEntangledLanes &= ~lane;\n }\n}\nfunction getBumpedLaneForHydrationByLane(lane) {\n switch (lane) {\n case 2:\n lane = 1;\n break;\n case 8:\n lane = 4;\n break;\n case 32:\n lane = 16;\n break;\n case 256:\n case 512:\n case 1024:\n case 2048:\n case 4096:\n case 8192:\n case 16384:\n case 32768:\n case 65536:\n case 131072:\n case 262144:\n case 524288:\n case 1048576:\n case 2097152:\n case 4194304:\n case 8388608:\n case 16777216:\n case 33554432:\n lane = 128;\n break;\n case 268435456:\n lane = 134217728;\n break;\n default:\n lane = 0;\n }\n return lane;\n}\nfunction lanesToEventPriority(lanes) {\n lanes &= -lanes;\n return 2 < lanes\n ? 8 < lanes\n ? 0 !== (lanes & 134217727)\n ? 32\n : 268435456\n : 8\n : 2;\n}\nfunction resolveUpdatePriority() {\n var updatePriority = ReactDOMSharedInternals.p;\n if (0 !== updatePriority) return updatePriority;\n updatePriority = window.event;\n return void 0 === updatePriority ? 32 : getEventPriority(updatePriority.type);\n}\nfunction runWithPriority(priority, fn) {\n var previousPriority = ReactDOMSharedInternals.p;\n try {\n return (ReactDOMSharedInternals.p = priority), fn();\n } finally {\n ReactDOMSharedInternals.p = previousPriority;\n }\n}\nvar randomKey = Math.random().toString(36).slice(2),\n internalInstanceKey = \"__reactFiber$\" + randomKey,\n internalPropsKey = \"__reactProps$\" + randomKey,\n internalContainerInstanceKey = \"__reactContainer$\" + randomKey,\n internalEventHandlersKey = \"__reactEvents$\" + randomKey,\n internalEventHandlerListenersKey = \"__reactListeners$\" + randomKey,\n internalEventHandlesSetKey = \"__reactHandles$\" + randomKey,\n internalRootNodeResourcesKey = \"__reactResources$\" + randomKey,\n internalHoistableMarker = \"__reactMarker$\" + randomKey;\nfunction detachDeletedInstance(node) {\n delete node[internalInstanceKey];\n delete node[internalPropsKey];\n delete node[internalEventHandlersKey];\n delete node[internalEventHandlerListenersKey];\n delete node[internalEventHandlesSetKey];\n}\nfunction getClosestInstanceFromNode(targetNode) {\n var targetInst = targetNode[internalInstanceKey];\n if (targetInst) return targetInst;\n for (var parentNode = targetNode.parentNode; parentNode; ) {\n if (\n (targetInst =\n parentNode[internalContainerInstanceKey] ||\n parentNode[internalInstanceKey])\n ) {\n parentNode = targetInst.alternate;\n if (\n null !== targetInst.child ||\n (null !== parentNode && null !== parentNode.child)\n )\n for (\n targetNode = getParentSuspenseInstance(targetNode);\n null !== targetNode;\n\n ) {\n if ((parentNode = targetNode[internalInstanceKey])) return parentNode;\n targetNode = getParentSuspenseInstance(targetNode);\n }\n return targetInst;\n }\n targetNode = parentNode;\n parentNode = targetNode.parentNode;\n }\n return null;\n}\nfunction getInstanceFromNode(node) {\n if (\n (node = node[internalInstanceKey] || node[internalContainerInstanceKey])\n ) {\n var tag = node.tag;\n if (\n 5 === tag ||\n 6 === tag ||\n 13 === tag ||\n 26 === tag ||\n 27 === tag ||\n 3 === tag\n )\n return node;\n }\n return null;\n}\nfunction getNodeFromInstance(inst) {\n var tag = inst.tag;\n if (5 === tag || 26 === tag || 27 === tag || 6 === tag) return inst.stateNode;\n throw Error(formatProdErrorMessage(33));\n}\nfunction getResourcesFromRoot(root) {\n var resources = root[internalRootNodeResourcesKey];\n resources ||\n (resources = root[internalRootNodeResourcesKey] =\n { hoistableStyles: new Map(), hoistableScripts: new Map() });\n return resources;\n}\nfunction markNodeAsHoistable(node) {\n node[internalHoistableMarker] = !0;\n}\nvar allNativeEvents = new Set(),\n registrationNameDependencies = {};\nfunction registerTwoPhaseEvent(registrationName, dependencies) {\n registerDirectEvent(registrationName, dependencies);\n registerDirectEvent(registrationName + \"Capture\", dependencies);\n}\nfunction registerDirectEvent(registrationName, dependencies) {\n registrationNameDependencies[registrationName] = dependencies;\n for (\n registrationName = 0;\n registrationName < dependencies.length;\n registrationName++\n )\n allNativeEvents.add(dependencies[registrationName]);\n}\nvar VALID_ATTRIBUTE_NAME_REGEX = RegExp(\n \"^[:A-Z_a-z\\\\u00C0-\\\\u00D6\\\\u00D8-\\\\u00F6\\\\u00F8-\\\\u02FF\\\\u0370-\\\\u037D\\\\u037F-\\\\u1FFF\\\\u200C-\\\\u200D\\\\u2070-\\\\u218F\\\\u2C00-\\\\u2FEF\\\\u3001-\\\\uD7FF\\\\uF900-\\\\uFDCF\\\\uFDF0-\\\\uFFFD][:A-Z_a-z\\\\u00C0-\\\\u00D6\\\\u00D8-\\\\u00F6\\\\u00F8-\\\\u02FF\\\\u0370-\\\\u037D\\\\u037F-\\\\u1FFF\\\\u200C-\\\\u200D\\\\u2070-\\\\u218F\\\\u2C00-\\\\u2FEF\\\\u3001-\\\\uD7FF\\\\uF900-\\\\uFDCF\\\\uFDF0-\\\\uFFFD\\\\-.0-9\\\\u00B7\\\\u0300-\\\\u036F\\\\u203F-\\\\u2040]*$\"\n ),\n illegalAttributeNameCache = {},\n validatedAttributeNameCache = {};\nfunction isAttributeNameSafe(attributeName) {\n if (hasOwnProperty.call(validatedAttributeNameCache, attributeName))\n return !0;\n if (hasOwnProperty.call(illegalAttributeNameCache, attributeName)) return !1;\n if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName))\n return (validatedAttributeNameCache[attributeName] = !0);\n illegalAttributeNameCache[attributeName] = !0;\n return !1;\n}\nfunction setValueForAttribute(node, name, value) {\n if (isAttributeNameSafe(name))\n if (null === value) node.removeAttribute(name);\n else {\n switch (typeof value) {\n case \"undefined\":\n case \"function\":\n case \"symbol\":\n node.removeAttribute(name);\n return;\n case \"boolean\":\n var prefix$8 = name.toLowerCase().slice(0, 5);\n if (\"data-\" !== prefix$8 && \"aria-\" !== prefix$8) {\n node.removeAttribute(name);\n return;\n }\n }\n node.setAttribute(name, \"\" + value);\n }\n}\nfunction setValueForKnownAttribute(node, name, value) {\n if (null === value) node.removeAttribute(name);\n else {\n switch (typeof value) {\n case \"undefined\":\n case \"function\":\n case \"symbol\":\n case \"boolean\":\n node.removeAttribute(name);\n return;\n }\n node.setAttribute(name, \"\" + value);\n }\n}\nfunction setValueForNamespacedAttribute(node, namespace, name, value) {\n if (null === value) node.removeAttribute(name);\n else {\n switch (typeof value) {\n case \"undefined\":\n case \"function\":\n case \"symbol\":\n case \"boolean\":\n node.removeAttribute(name);\n return;\n }\n node.setAttributeNS(namespace, name, \"\" + value);\n }\n}\nvar prefix, suffix;\nfunction describeBuiltInComponentFrame(name) {\n if (void 0 === prefix)\n try {\n throw Error();\n } catch (x) {\n var match = x.stack.trim().match(/\\n( *(at )?)/);\n prefix = (match && match[1]) || \"\";\n suffix =\n -1 < x.stack.indexOf(\"\\n at\")\n ? \" ()\"\n : -1 < x.stack.indexOf(\"@\")\n ? \"@unknown:0:0\"\n : \"\";\n }\n return \"\\n\" + prefix + name + suffix;\n}\nvar reentry = !1;\nfunction describeNativeComponentFrame(fn, construct) {\n if (!fn || reentry) return \"\";\n reentry = !0;\n var previousPrepareStackTrace = Error.prepareStackTrace;\n Error.prepareStackTrace = void 0;\n try {\n var RunInRootFrame = {\n DetermineComponentFrameRoot: function () {\n try {\n if (construct) {\n var Fake = function () {\n throw Error();\n };\n Object.defineProperty(Fake.prototype, \"props\", {\n set: function () {\n throw Error();\n }\n });\n if (\"object\" === typeof Reflect && Reflect.construct) {\n try {\n Reflect.construct(Fake, []);\n } catch (x) {\n var control = x;\n }\n Reflect.construct(fn, [], Fake);\n } else {\n try {\n Fake.call();\n } catch (x$9) {\n control = x$9;\n }\n fn.call(Fake.prototype);\n }\n } else {\n try {\n throw Error();\n } catch (x$10) {\n control = x$10;\n }\n (Fake = fn()) &&\n \"function\" === typeof Fake.catch &&\n Fake.catch(function () {});\n }\n } catch (sample) {\n if (sample && control && \"string\" === typeof sample.stack)\n return [sample.stack, control.stack];\n }\n return [null, null];\n }\n };\n RunInRootFrame.DetermineComponentFrameRoot.displayName =\n \"DetermineComponentFrameRoot\";\n var namePropDescriptor = Object.getOwnPropertyDescriptor(\n RunInRootFrame.DetermineComponentFrameRoot,\n \"name\"\n );\n namePropDescriptor &&\n namePropDescriptor.configurable &&\n Object.defineProperty(\n RunInRootFrame.DetermineComponentFrameRoot,\n \"name\",\n { value: \"DetermineComponentFrameRoot\" }\n );\n var _RunInRootFrame$Deter = RunInRootFrame.DetermineComponentFrameRoot(),\n sampleStack = _RunInRootFrame$Deter[0],\n controlStack = _RunInRootFrame$Deter[1];\n if (sampleStack && controlStack) {\n var sampleLines = sampleStack.split(\"\\n\"),\n controlLines = controlStack.split(\"\\n\");\n for (\n namePropDescriptor = RunInRootFrame = 0;\n RunInRootFrame < sampleLines.length &&\n !sampleLines[RunInRootFrame].includes(\"DetermineComponentFrameRoot\");\n\n )\n RunInRootFrame++;\n for (\n ;\n namePropDescriptor < controlLines.length &&\n !controlLines[namePropDescriptor].includes(\n \"DetermineComponentFrameRoot\"\n );\n\n )\n namePropDescriptor++;\n if (\n RunInRootFrame === sampleLines.length ||\n namePropDescriptor === controlLines.length\n )\n for (\n RunInRootFrame = sampleLines.length - 1,\n namePropDescriptor = controlLines.length - 1;\n 1 <= RunInRootFrame &&\n 0 <= namePropDescriptor &&\n sampleLines[RunInRootFrame] !== controlLines[namePropDescriptor];\n\n )\n namePropDescriptor--;\n for (\n ;\n 1 <= RunInRootFrame && 0 <= namePropDescriptor;\n RunInRootFrame--, namePropDescriptor--\n )\n if (sampleLines[RunInRootFrame] !== controlLines[namePropDescriptor]) {\n if (1 !== RunInRootFrame || 1 !== namePropDescriptor) {\n do\n if (\n (RunInRootFrame--,\n namePropDescriptor--,\n 0 > namePropDescriptor ||\n sampleLines[RunInRootFrame] !==\n controlLines[namePropDescriptor])\n ) {\n var frame =\n \"\\n\" +\n sampleLines[RunInRootFrame].replace(\" at new \", \" at \");\n fn.displayName &&\n frame.includes(\"\") &&\n (frame = frame.replace(\"\", fn.displayName));\n return frame;\n }\n while (1 <= RunInRootFrame && 0 <= namePropDescriptor);\n }\n break;\n }\n }\n } finally {\n (reentry = !1), (Error.prepareStackTrace = previousPrepareStackTrace);\n }\n return (previousPrepareStackTrace = fn ? fn.displayName || fn.name : \"\")\n ? describeBuiltInComponentFrame(previousPrepareStackTrace)\n : \"\";\n}\nfunction describeFiber(fiber) {\n switch (fiber.tag) {\n case 26:\n case 27:\n case 5:\n return describeBuiltInComponentFrame(fiber.type);\n case 16:\n return describeBuiltInComponentFrame(\"Lazy\");\n case 13:\n return describeBuiltInComponentFrame(\"Suspense\");\n case 19:\n return describeBuiltInComponentFrame(\"SuspenseList\");\n case 0:\n case 15:\n return describeNativeComponentFrame(fiber.type, !1);\n case 11:\n return describeNativeComponentFrame(fiber.type.render, !1);\n case 1:\n return describeNativeComponentFrame(fiber.type, !0);\n case 31:\n return describeBuiltInComponentFrame(\"Activity\");\n default:\n return \"\";\n }\n}\nfunction getStackByFiberInDevAndProd(workInProgress) {\n try {\n var info = \"\";\n do\n (info += describeFiber(workInProgress)),\n (workInProgress = workInProgress.return);\n while (workInProgress);\n return info;\n } catch (x) {\n return \"\\nError generating stack: \" + x.message + \"\\n\" + x.stack;\n }\n}\nfunction getToStringValue(value) {\n switch (typeof value) {\n case \"bigint\":\n case \"boolean\":\n case \"number\":\n case \"string\":\n case \"undefined\":\n return value;\n case \"object\":\n return value;\n default:\n return \"\";\n }\n}\nfunction isCheckable(elem) {\n var type = elem.type;\n return (\n (elem = elem.nodeName) &&\n \"input\" === elem.toLowerCase() &&\n (\"checkbox\" === type || \"radio\" === type)\n );\n}\nfunction trackValueOnNode(node) {\n var valueField = isCheckable(node) ? \"checked\" : \"value\",\n descriptor = Object.getOwnPropertyDescriptor(\n node.constructor.prototype,\n valueField\n ),\n currentValue = \"\" + node[valueField];\n if (\n !node.hasOwnProperty(valueField) &&\n \"undefined\" !== typeof descriptor &&\n \"function\" === typeof descriptor.get &&\n \"function\" === typeof descriptor.set\n ) {\n var get = descriptor.get,\n set = descriptor.set;\n Object.defineProperty(node, valueField, {\n configurable: !0,\n get: function () {\n return get.call(this);\n },\n set: function (value) {\n currentValue = \"\" + value;\n set.call(this, value);\n }\n });\n Object.defineProperty(node, valueField, {\n enumerable: descriptor.enumerable\n });\n return {\n getValue: function () {\n return currentValue;\n },\n setValue: function (value) {\n currentValue = \"\" + value;\n },\n stopTracking: function () {\n node._valueTracker = null;\n delete node[valueField];\n }\n };\n }\n}\nfunction track(node) {\n node._valueTracker || (node._valueTracker = trackValueOnNode(node));\n}\nfunction updateValueIfChanged(node) {\n if (!node) return !1;\n var tracker = node._valueTracker;\n if (!tracker) return !0;\n var lastValue = tracker.getValue();\n var value = \"\";\n node &&\n (value = isCheckable(node)\n ? node.checked\n ? \"true\"\n : \"false\"\n : node.value);\n node = value;\n return node !== lastValue ? (tracker.setValue(node), !0) : !1;\n}\nfunction getActiveElement(doc) {\n doc = doc || (\"undefined\" !== typeof document ? document : void 0);\n if (\"undefined\" === typeof doc) return null;\n try {\n return doc.activeElement || doc.body;\n } catch (e) {\n return doc.body;\n }\n}\nvar escapeSelectorAttributeValueInsideDoubleQuotesRegex = /[\\n\"\\\\]/g;\nfunction escapeSelectorAttributeValueInsideDoubleQuotes(value) {\n return value.replace(\n escapeSelectorAttributeValueInsideDoubleQuotesRegex,\n function (ch) {\n return \"\\\\\" + ch.charCodeAt(0).toString(16) + \" \";\n }\n );\n}\nfunction updateInput(\n element,\n value,\n defaultValue,\n lastDefaultValue,\n checked,\n defaultChecked,\n type,\n name\n) {\n element.name = \"\";\n null != type &&\n \"function\" !== typeof type &&\n \"symbol\" !== typeof type &&\n \"boolean\" !== typeof type\n ? (element.type = type)\n : element.removeAttribute(\"type\");\n if (null != value)\n if (\"number\" === type) {\n if ((0 === value && \"\" === element.value) || element.value != value)\n element.value = \"\" + getToStringValue(value);\n } else\n element.value !== \"\" + getToStringValue(value) &&\n (element.value = \"\" + getToStringValue(value));\n else\n (\"submit\" !== type && \"reset\" !== type) || element.removeAttribute(\"value\");\n null != value\n ? setDefaultValue(element, type, getToStringValue(value))\n : null != defaultValue\n ? setDefaultValue(element, type, getToStringValue(defaultValue))\n : null != lastDefaultValue && element.removeAttribute(\"value\");\n null == checked &&\n null != defaultChecked &&\n (element.defaultChecked = !!defaultChecked);\n null != checked &&\n (element.checked =\n checked && \"function\" !== typeof checked && \"symbol\" !== typeof checked);\n null != name &&\n \"function\" !== typeof name &&\n \"symbol\" !== typeof name &&\n \"boolean\" !== typeof name\n ? (element.name = \"\" + getToStringValue(name))\n : element.removeAttribute(\"name\");\n}\nfunction initInput(\n element,\n value,\n defaultValue,\n checked,\n defaultChecked,\n type,\n name,\n isHydrating\n) {\n null != type &&\n \"function\" !== typeof type &&\n \"symbol\" !== typeof type &&\n \"boolean\" !== typeof type &&\n (element.type = type);\n if (null != value || null != defaultValue) {\n if (\n !(\n (\"submit\" !== type && \"reset\" !== type) ||\n (void 0 !== value && null !== value)\n )\n )\n return;\n defaultValue =\n null != defaultValue ? \"\" + getToStringValue(defaultValue) : \"\";\n value = null != value ? \"\" + getToStringValue(value) : defaultValue;\n isHydrating || value === element.value || (element.value = value);\n element.defaultValue = value;\n }\n checked = null != checked ? checked : defaultChecked;\n checked =\n \"function\" !== typeof checked && \"symbol\" !== typeof checked && !!checked;\n element.checked = isHydrating ? element.checked : !!checked;\n element.defaultChecked = !!checked;\n null != name &&\n \"function\" !== typeof name &&\n \"symbol\" !== typeof name &&\n \"boolean\" !== typeof name &&\n (element.name = name);\n}\nfunction setDefaultValue(node, type, value) {\n (\"number\" === type && getActiveElement(node.ownerDocument) === node) ||\n node.defaultValue === \"\" + value ||\n (node.defaultValue = \"\" + value);\n}\nfunction updateOptions(node, multiple, propValue, setDefaultSelected) {\n node = node.options;\n if (multiple) {\n multiple = {};\n for (var i = 0; i < propValue.length; i++)\n multiple[\"$\" + propValue[i]] = !0;\n for (propValue = 0; propValue < node.length; propValue++)\n (i = multiple.hasOwnProperty(\"$\" + node[propValue].value)),\n node[propValue].selected !== i && (node[propValue].selected = i),\n i && setDefaultSelected && (node[propValue].defaultSelected = !0);\n } else {\n propValue = \"\" + getToStringValue(propValue);\n multiple = null;\n for (i = 0; i < node.length; i++) {\n if (node[i].value === propValue) {\n node[i].selected = !0;\n setDefaultSelected && (node[i].defaultSelected = !0);\n return;\n }\n null !== multiple || node[i].disabled || (multiple = node[i]);\n }\n null !== multiple && (multiple.selected = !0);\n }\n}\nfunction updateTextarea(element, value, defaultValue) {\n if (\n null != value &&\n ((value = \"\" + getToStringValue(value)),\n value !== element.value && (element.value = value),\n null == defaultValue)\n ) {\n element.defaultValue !== value && (element.defaultValue = value);\n return;\n }\n element.defaultValue =\n null != defaultValue ? \"\" + getToStringValue(defaultValue) : \"\";\n}\nfunction initTextarea(element, value, defaultValue, children) {\n if (null == value) {\n if (null != children) {\n if (null != defaultValue) throw Error(formatProdErrorMessage(92));\n if (isArrayImpl(children)) {\n if (1 < children.length) throw Error(formatProdErrorMessage(93));\n children = children[0];\n }\n defaultValue = children;\n }\n null == defaultValue && (defaultValue = \"\");\n value = defaultValue;\n }\n defaultValue = getToStringValue(value);\n element.defaultValue = defaultValue;\n children = element.textContent;\n children === defaultValue &&\n \"\" !== children &&\n null !== children &&\n (element.value = children);\n}\nfunction setTextContent(node, text) {\n if (text) {\n var firstChild = node.firstChild;\n if (\n firstChild &&\n firstChild === node.lastChild &&\n 3 === firstChild.nodeType\n ) {\n firstChild.nodeValue = text;\n return;\n }\n }\n node.textContent = text;\n}\nvar unitlessNumbers = new Set(\n \"animationIterationCount aspectRatio borderImageOutset borderImageSlice borderImageWidth boxFlex boxFlexGroup boxOrdinalGroup columnCount columns flex flexGrow flexPositive flexShrink flexNegative flexOrder gridArea gridRow gridRowEnd gridRowSpan gridRowStart gridColumn gridColumnEnd gridColumnSpan gridColumnStart fontWeight lineClamp lineHeight opacity order orphans scale tabSize widows zIndex zoom fillOpacity floodOpacity stopOpacity strokeDasharray strokeDashoffset strokeMiterlimit strokeOpacity strokeWidth MozAnimationIterationCount MozBoxFlex MozBoxFlexGroup MozLineClamp msAnimationIterationCount msFlex msZoom msFlexGrow msFlexNegative msFlexOrder msFlexPositive msFlexShrink msGridColumn msGridColumnSpan msGridRow msGridRowSpan WebkitAnimationIterationCount WebkitBoxFlex WebKitBoxFlexGroup WebkitBoxOrdinalGroup WebkitColumnCount WebkitColumns WebkitFlex WebkitFlexGrow WebkitFlexPositive WebkitFlexShrink WebkitLineClamp\".split(\n \" \"\n )\n);\nfunction setValueForStyle(style, styleName, value) {\n var isCustomProperty = 0 === styleName.indexOf(\"--\");\n null == value || \"boolean\" === typeof value || \"\" === value\n ? isCustomProperty\n ? style.setProperty(styleName, \"\")\n : \"float\" === styleName\n ? (style.cssFloat = \"\")\n : (style[styleName] = \"\")\n : isCustomProperty\n ? style.setProperty(styleName, value)\n : \"number\" !== typeof value ||\n 0 === value ||\n unitlessNumbers.has(styleName)\n ? \"float\" === styleName\n ? (style.cssFloat = value)\n : (style[styleName] = (\"\" + value).trim())\n : (style[styleName] = value + \"px\");\n}\nfunction setValueForStyles(node, styles, prevStyles) {\n if (null != styles && \"object\" !== typeof styles)\n throw Error(formatProdErrorMessage(62));\n node = node.style;\n if (null != prevStyles) {\n for (var styleName in prevStyles)\n !prevStyles.hasOwnProperty(styleName) ||\n (null != styles && styles.hasOwnProperty(styleName)) ||\n (0 === styleName.indexOf(\"--\")\n ? node.setProperty(styleName, \"\")\n : \"float\" === styleName\n ? (node.cssFloat = \"\")\n : (node[styleName] = \"\"));\n for (var styleName$16 in styles)\n (styleName = styles[styleName$16]),\n styles.hasOwnProperty(styleName$16) &&\n prevStyles[styleName$16] !== styleName &&\n setValueForStyle(node, styleName$16, styleName);\n } else\n for (var styleName$17 in styles)\n styles.hasOwnProperty(styleName$17) &&\n setValueForStyle(node, styleName$17, styles[styleName$17]);\n}\nfunction isCustomElement(tagName) {\n if (-1 === tagName.indexOf(\"-\")) return !1;\n switch (tagName) {\n case \"annotation-xml\":\n case \"color-profile\":\n case \"font-face\":\n case \"font-face-src\":\n case \"font-face-uri\":\n case \"font-face-format\":\n case \"font-face-name\":\n case \"missing-glyph\":\n return !1;\n default:\n return !0;\n }\n}\nvar aliases = new Map([\n [\"acceptCharset\", \"accept-charset\"],\n [\"htmlFor\", \"for\"],\n [\"httpEquiv\", \"http-equiv\"],\n [\"crossOrigin\", \"crossorigin\"],\n [\"accentHeight\", \"accent-height\"],\n [\"alignmentBaseline\", \"alignment-baseline\"],\n [\"arabicForm\", \"arabic-form\"],\n [\"baselineShift\", \"baseline-shift\"],\n [\"capHeight\", \"cap-height\"],\n [\"clipPath\", \"clip-path\"],\n [\"clipRule\", \"clip-rule\"],\n [\"colorInterpolation\", \"color-interpolation\"],\n [\"colorInterpolationFilters\", \"color-interpolation-filters\"],\n [\"colorProfile\", \"color-profile\"],\n [\"colorRendering\", \"color-rendering\"],\n [\"dominantBaseline\", \"dominant-baseline\"],\n [\"enableBackground\", \"enable-background\"],\n [\"fillOpacity\", \"fill-opacity\"],\n [\"fillRule\", \"fill-rule\"],\n [\"floodColor\", \"flood-color\"],\n [\"floodOpacity\", \"flood-opacity\"],\n [\"fontFamily\", \"font-family\"],\n [\"fontSize\", \"font-size\"],\n [\"fontSizeAdjust\", \"font-size-adjust\"],\n [\"fontStretch\", \"font-stretch\"],\n [\"fontStyle\", \"font-style\"],\n [\"fontVariant\", \"font-variant\"],\n [\"fontWeight\", \"font-weight\"],\n [\"glyphName\", \"glyph-name\"],\n [\"glyphOrientationHorizontal\", \"glyph-orientation-horizontal\"],\n [\"glyphOrientationVertical\", \"glyph-orientation-vertical\"],\n [\"horizAdvX\", \"horiz-adv-x\"],\n [\"horizOriginX\", \"horiz-origin-x\"],\n [\"imageRendering\", \"image-rendering\"],\n [\"letterSpacing\", \"letter-spacing\"],\n [\"lightingColor\", \"lighting-color\"],\n [\"markerEnd\", \"marker-end\"],\n [\"markerMid\", \"marker-mid\"],\n [\"markerStart\", \"marker-start\"],\n [\"overlinePosition\", \"overline-position\"],\n [\"overlineThickness\", \"overline-thickness\"],\n [\"paintOrder\", \"paint-order\"],\n [\"panose-1\", \"panose-1\"],\n [\"pointerEvents\", \"pointer-events\"],\n [\"renderingIntent\", \"rendering-intent\"],\n [\"shapeRendering\", \"shape-rendering\"],\n [\"stopColor\", \"stop-color\"],\n [\"stopOpacity\", \"stop-opacity\"],\n [\"strikethroughPosition\", \"strikethrough-position\"],\n [\"strikethroughThickness\", \"strikethrough-thickness\"],\n [\"strokeDasharray\", \"stroke-dasharray\"],\n [\"strokeDashoffset\", \"stroke-dashoffset\"],\n [\"strokeLinecap\", \"stroke-linecap\"],\n [\"strokeLinejoin\", \"stroke-linejoin\"],\n [\"strokeMiterlimit\", \"stroke-miterlimit\"],\n [\"strokeOpacity\", \"stroke-opacity\"],\n [\"strokeWidth\", \"stroke-width\"],\n [\"textAnchor\", \"text-anchor\"],\n [\"textDecoration\", \"text-decoration\"],\n [\"textRendering\", \"text-rendering\"],\n [\"transformOrigin\", \"transform-origin\"],\n [\"underlinePosition\", \"underline-position\"],\n [\"underlineThickness\", \"underline-thickness\"],\n [\"unicodeBidi\", \"unicode-bidi\"],\n [\"unicodeRange\", \"unicode-range\"],\n [\"unitsPerEm\", \"units-per-em\"],\n [\"vAlphabetic\", \"v-alphabetic\"],\n [\"vHanging\", \"v-hanging\"],\n [\"vIdeographic\", \"v-ideographic\"],\n [\"vMathematical\", \"v-mathematical\"],\n [\"vectorEffect\", \"vector-effect\"],\n [\"vertAdvY\", \"vert-adv-y\"],\n [\"vertOriginX\", \"vert-origin-x\"],\n [\"vertOriginY\", \"vert-origin-y\"],\n [\"wordSpacing\", \"word-spacing\"],\n [\"writingMode\", \"writing-mode\"],\n [\"xmlnsXlink\", \"xmlns:xlink\"],\n [\"xHeight\", \"x-height\"]\n ]),\n isJavaScriptProtocol =\n /^[\\u0000-\\u001F ]*j[\\r\\n\\t]*a[\\r\\n\\t]*v[\\r\\n\\t]*a[\\r\\n\\t]*s[\\r\\n\\t]*c[\\r\\n\\t]*r[\\r\\n\\t]*i[\\r\\n\\t]*p[\\r\\n\\t]*t[\\r\\n\\t]*:/i;\nfunction sanitizeURL(url) {\n return isJavaScriptProtocol.test(\"\" + url)\n ? \"javascript:throw new Error('React has blocked a javascript: URL as a security precaution.')\"\n : url;\n}\nvar currentReplayingEvent = null;\nfunction getEventTarget(nativeEvent) {\n nativeEvent = nativeEvent.target || nativeEvent.srcElement || window;\n nativeEvent.correspondingUseElement &&\n (nativeEvent = nativeEvent.correspondingUseElement);\n return 3 === nativeEvent.nodeType ? nativeEvent.parentNode : nativeEvent;\n}\nvar restoreTarget = null,\n restoreQueue = null;\nfunction restoreStateOfTarget(target) {\n var internalInstance = getInstanceFromNode(target);\n if (internalInstance && (target = internalInstance.stateNode)) {\n var props = target[internalPropsKey] || null;\n a: switch (((target = internalInstance.stateNode), internalInstance.type)) {\n case \"input\":\n updateInput(\n target,\n props.value,\n props.defaultValue,\n props.defaultValue,\n props.checked,\n props.defaultChecked,\n props.type,\n props.name\n );\n internalInstance = props.name;\n if (\"radio\" === props.type && null != internalInstance) {\n for (props = target; props.parentNode; ) props = props.parentNode;\n props = props.querySelectorAll(\n 'input[name=\"' +\n escapeSelectorAttributeValueInsideDoubleQuotes(\n \"\" + internalInstance\n ) +\n '\"][type=\"radio\"]'\n );\n for (\n internalInstance = 0;\n internalInstance < props.length;\n internalInstance++\n ) {\n var otherNode = props[internalInstance];\n if (otherNode !== target && otherNode.form === target.form) {\n var otherProps = otherNode[internalPropsKey] || null;\n if (!otherProps) throw Error(formatProdErrorMessage(90));\n updateInput(\n otherNode,\n otherProps.value,\n otherProps.defaultValue,\n otherProps.defaultValue,\n otherProps.checked,\n otherProps.defaultChecked,\n otherProps.type,\n otherProps.name\n );\n }\n }\n for (\n internalInstance = 0;\n internalInstance < props.length;\n internalInstance++\n )\n (otherNode = props[internalInstance]),\n otherNode.form === target.form && updateValueIfChanged(otherNode);\n }\n break a;\n case \"textarea\":\n updateTextarea(target, props.value, props.defaultValue);\n break a;\n case \"select\":\n (internalInstance = props.value),\n null != internalInstance &&\n updateOptions(target, !!props.multiple, internalInstance, !1);\n }\n }\n}\nvar isInsideEventHandler = !1;\nfunction batchedUpdates$1(fn, a, b) {\n if (isInsideEventHandler) return fn(a, b);\n isInsideEventHandler = !0;\n try {\n var JSCompiler_inline_result = fn(a);\n return JSCompiler_inline_result;\n } finally {\n if (\n ((isInsideEventHandler = !1),\n null !== restoreTarget || null !== restoreQueue)\n )\n if (\n (flushSyncWork$1(),\n restoreTarget &&\n ((a = restoreTarget),\n (fn = restoreQueue),\n (restoreQueue = restoreTarget = null),\n restoreStateOfTarget(a),\n fn))\n )\n for (a = 0; a < fn.length; a++) restoreStateOfTarget(fn[a]);\n }\n}\nfunction getListener(inst, registrationName) {\n var stateNode = inst.stateNode;\n if (null === stateNode) return null;\n var props = stateNode[internalPropsKey] || null;\n if (null === props) return null;\n stateNode = props[registrationName];\n a: switch (registrationName) {\n case \"onClick\":\n case \"onClickCapture\":\n case \"onDoubleClick\":\n case \"onDoubleClickCapture\":\n case \"onMouseDown\":\n case \"onMouseDownCapture\":\n case \"onMouseMove\":\n case \"onMouseMoveCapture\":\n case \"onMouseUp\":\n case \"onMouseUpCapture\":\n case \"onMouseEnter\":\n (props = !props.disabled) ||\n ((inst = inst.type),\n (props = !(\n \"button\" === inst ||\n \"input\" === inst ||\n \"select\" === inst ||\n \"textarea\" === inst\n )));\n inst = !props;\n break a;\n default:\n inst = !1;\n }\n if (inst) return null;\n if (stateNode && \"function\" !== typeof stateNode)\n throw Error(\n formatProdErrorMessage(231, registrationName, typeof stateNode)\n );\n return stateNode;\n}\nvar canUseDOM = !(\n \"undefined\" === typeof window ||\n \"undefined\" === typeof window.document ||\n \"undefined\" === typeof window.document.createElement\n ),\n passiveBrowserEventsSupported = !1;\nif (canUseDOM)\n try {\n var options = {};\n Object.defineProperty(options, \"passive\", {\n get: function () {\n passiveBrowserEventsSupported = !0;\n }\n });\n window.addEventListener(\"test\", options, options);\n window.removeEventListener(\"test\", options, options);\n } catch (e) {\n passiveBrowserEventsSupported = !1;\n }\nvar root = null,\n startText = null,\n fallbackText = null;\nfunction getData() {\n if (fallbackText) return fallbackText;\n var start,\n startValue = startText,\n startLength = startValue.length,\n end,\n endValue = \"value\" in root ? root.value : root.textContent,\n endLength = endValue.length;\n for (\n start = 0;\n start < startLength && startValue[start] === endValue[start];\n start++\n );\n var minEnd = startLength - start;\n for (\n end = 1;\n end <= minEnd &&\n startValue[startLength - end] === endValue[endLength - end];\n end++\n );\n return (fallbackText = endValue.slice(start, 1 < end ? 1 - end : void 0));\n}\nfunction getEventCharCode(nativeEvent) {\n var keyCode = nativeEvent.keyCode;\n \"charCode\" in nativeEvent\n ? ((nativeEvent = nativeEvent.charCode),\n 0 === nativeEvent && 13 === keyCode && (nativeEvent = 13))\n : (nativeEvent = keyCode);\n 10 === nativeEvent && (nativeEvent = 13);\n return 32 <= nativeEvent || 13 === nativeEvent ? nativeEvent : 0;\n}\nfunction functionThatReturnsTrue() {\n return !0;\n}\nfunction functionThatReturnsFalse() {\n return !1;\n}\nfunction createSyntheticEvent(Interface) {\n function SyntheticBaseEvent(\n reactName,\n reactEventType,\n targetInst,\n nativeEvent,\n nativeEventTarget\n ) {\n this._reactName = reactName;\n this._targetInst = targetInst;\n this.type = reactEventType;\n this.nativeEvent = nativeEvent;\n this.target = nativeEventTarget;\n this.currentTarget = null;\n for (var propName in Interface)\n Interface.hasOwnProperty(propName) &&\n ((reactName = Interface[propName]),\n (this[propName] = reactName\n ? reactName(nativeEvent)\n : nativeEvent[propName]));\n this.isDefaultPrevented = (\n null != nativeEvent.defaultPrevented\n ? nativeEvent.defaultPrevented\n : !1 === nativeEvent.returnValue\n )\n ? functionThatReturnsTrue\n : functionThatReturnsFalse;\n this.isPropagationStopped = functionThatReturnsFalse;\n return this;\n }\n assign(SyntheticBaseEvent.prototype, {\n preventDefault: function () {\n this.defaultPrevented = !0;\n var event = this.nativeEvent;\n event &&\n (event.preventDefault\n ? event.preventDefault()\n : \"unknown\" !== typeof event.returnValue && (event.returnValue = !1),\n (this.isDefaultPrevented = functionThatReturnsTrue));\n },\n stopPropagation: function () {\n var event = this.nativeEvent;\n event &&\n (event.stopPropagation\n ? event.stopPropagation()\n : \"unknown\" !== typeof event.cancelBubble &&\n (event.cancelBubble = !0),\n (this.isPropagationStopped = functionThatReturnsTrue));\n },\n persist: function () {},\n isPersistent: functionThatReturnsTrue\n });\n return SyntheticBaseEvent;\n}\nvar EventInterface = {\n eventPhase: 0,\n bubbles: 0,\n cancelable: 0,\n timeStamp: function (event) {\n return event.timeStamp || Date.now();\n },\n defaultPrevented: 0,\n isTrusted: 0\n },\n SyntheticEvent = createSyntheticEvent(EventInterface),\n UIEventInterface = assign({}, EventInterface, { view: 0, detail: 0 }),\n SyntheticUIEvent = createSyntheticEvent(UIEventInterface),\n lastMovementX,\n lastMovementY,\n lastMouseEvent,\n MouseEventInterface = assign({}, UIEventInterface, {\n screenX: 0,\n screenY: 0,\n clientX: 0,\n clientY: 0,\n pageX: 0,\n pageY: 0,\n ctrlKey: 0,\n shiftKey: 0,\n altKey: 0,\n metaKey: 0,\n getModifierState: getEventModifierState,\n button: 0,\n buttons: 0,\n relatedTarget: function (event) {\n return void 0 === event.relatedTarget\n ? event.fromElement === event.srcElement\n ? event.toElement\n : event.fromElement\n : event.relatedTarget;\n },\n movementX: function (event) {\n if (\"movementX\" in event) return event.movementX;\n event !== lastMouseEvent &&\n (lastMouseEvent && \"mousemove\" === event.type\n ? ((lastMovementX = event.screenX - lastMouseEvent.screenX),\n (lastMovementY = event.screenY - lastMouseEvent.screenY))\n : (lastMovementY = lastMovementX = 0),\n (lastMouseEvent = event));\n return lastMovementX;\n },\n movementY: function (event) {\n return \"movementY\" in event ? event.movementY : lastMovementY;\n }\n }),\n SyntheticMouseEvent = createSyntheticEvent(MouseEventInterface),\n DragEventInterface = assign({}, MouseEventInterface, { dataTransfer: 0 }),\n SyntheticDragEvent = createSyntheticEvent(DragEventInterface),\n FocusEventInterface = assign({}, UIEventInterface, { relatedTarget: 0 }),\n SyntheticFocusEvent = createSyntheticEvent(FocusEventInterface),\n AnimationEventInterface = assign({}, EventInterface, {\n animationName: 0,\n elapsedTime: 0,\n pseudoElement: 0\n }),\n SyntheticAnimationEvent = createSyntheticEvent(AnimationEventInterface),\n ClipboardEventInterface = assign({}, EventInterface, {\n clipboardData: function (event) {\n return \"clipboardData\" in event\n ? event.clipboardData\n : window.clipboardData;\n }\n }),\n SyntheticClipboardEvent = createSyntheticEvent(ClipboardEventInterface),\n CompositionEventInterface = assign({}, EventInterface, { data: 0 }),\n SyntheticCompositionEvent = createSyntheticEvent(CompositionEventInterface),\n normalizeKey = {\n Esc: \"Escape\",\n Spacebar: \" \",\n Left: \"ArrowLeft\",\n Up: \"ArrowUp\",\n Right: \"ArrowRight\",\n Down: \"ArrowDown\",\n Del: \"Delete\",\n Win: \"OS\",\n Menu: \"ContextMenu\",\n Apps: \"ContextMenu\",\n Scroll: \"ScrollLock\",\n MozPrintableKey: \"Unidentified\"\n },\n translateToKey = {\n 8: \"Backspace\",\n 9: \"Tab\",\n 12: \"Clear\",\n 13: \"Enter\",\n 16: \"Shift\",\n 17: \"Control\",\n 18: \"Alt\",\n 19: \"Pause\",\n 20: \"CapsLock\",\n 27: \"Escape\",\n 32: \" \",\n 33: \"PageUp\",\n 34: \"PageDown\",\n 35: \"End\",\n 36: \"Home\",\n 37: \"ArrowLeft\",\n 38: \"ArrowUp\",\n 39: \"ArrowRight\",\n 40: \"ArrowDown\",\n 45: \"Insert\",\n 46: \"Delete\",\n 112: \"F1\",\n 113: \"F2\",\n 114: \"F3\",\n 115: \"F4\",\n 116: \"F5\",\n 117: \"F6\",\n 118: \"F7\",\n 119: \"F8\",\n 120: \"F9\",\n 121: \"F10\",\n 122: \"F11\",\n 123: \"F12\",\n 144: \"NumLock\",\n 145: \"ScrollLock\",\n 224: \"Meta\"\n },\n modifierKeyToProp = {\n Alt: \"altKey\",\n Control: \"ctrlKey\",\n Meta: \"metaKey\",\n Shift: \"shiftKey\"\n };\nfunction modifierStateGetter(keyArg) {\n var nativeEvent = this.nativeEvent;\n return nativeEvent.getModifierState\n ? nativeEvent.getModifierState(keyArg)\n : (keyArg = modifierKeyToProp[keyArg])\n ? !!nativeEvent[keyArg]\n : !1;\n}\nfunction getEventModifierState() {\n return modifierStateGetter;\n}\nvar KeyboardEventInterface = assign({}, UIEventInterface, {\n key: function (nativeEvent) {\n if (nativeEvent.key) {\n var key = normalizeKey[nativeEvent.key] || nativeEvent.key;\n if (\"Unidentified\" !== key) return key;\n }\n return \"keypress\" === nativeEvent.type\n ? ((nativeEvent = getEventCharCode(nativeEvent)),\n 13 === nativeEvent ? \"Enter\" : String.fromCharCode(nativeEvent))\n : \"keydown\" === nativeEvent.type || \"keyup\" === nativeEvent.type\n ? translateToKey[nativeEvent.keyCode] || \"Unidentified\"\n : \"\";\n },\n code: 0,\n location: 0,\n ctrlKey: 0,\n shiftKey: 0,\n altKey: 0,\n metaKey: 0,\n repeat: 0,\n locale: 0,\n getModifierState: getEventModifierState,\n charCode: function (event) {\n return \"keypress\" === event.type ? getEventCharCode(event) : 0;\n },\n keyCode: function (event) {\n return \"keydown\" === event.type || \"keyup\" === event.type\n ? event.keyCode\n : 0;\n },\n which: function (event) {\n return \"keypress\" === event.type\n ? getEventCharCode(event)\n : \"keydown\" === event.type || \"keyup\" === event.type\n ? event.keyCode\n : 0;\n }\n }),\n SyntheticKeyboardEvent = createSyntheticEvent(KeyboardEventInterface),\n PointerEventInterface = assign({}, MouseEventInterface, {\n pointerId: 0,\n width: 0,\n height: 0,\n pressure: 0,\n tangentialPressure: 0,\n tiltX: 0,\n tiltY: 0,\n twist: 0,\n pointerType: 0,\n isPrimary: 0\n }),\n SyntheticPointerEvent = createSyntheticEvent(PointerEventInterface),\n TouchEventInterface = assign({}, UIEventInterface, {\n touches: 0,\n targetTouches: 0,\n changedTouches: 0,\n altKey: 0,\n metaKey: 0,\n ctrlKey: 0,\n shiftKey: 0,\n getModifierState: getEventModifierState\n }),\n SyntheticTouchEvent = createSyntheticEvent(TouchEventInterface),\n TransitionEventInterface = assign({}, EventInterface, {\n propertyName: 0,\n elapsedTime: 0,\n pseudoElement: 0\n }),\n SyntheticTransitionEvent = createSyntheticEvent(TransitionEventInterface),\n WheelEventInterface = assign({}, MouseEventInterface, {\n deltaX: function (event) {\n return \"deltaX\" in event\n ? event.deltaX\n : \"wheelDeltaX\" in event\n ? -event.wheelDeltaX\n : 0;\n },\n deltaY: function (event) {\n return \"deltaY\" in event\n ? event.deltaY\n : \"wheelDeltaY\" in event\n ? -event.wheelDeltaY\n : \"wheelDelta\" in event\n ? -event.wheelDelta\n : 0;\n },\n deltaZ: 0,\n deltaMode: 0\n }),\n SyntheticWheelEvent = createSyntheticEvent(WheelEventInterface),\n ToggleEventInterface = assign({}, EventInterface, {\n newState: 0,\n oldState: 0\n }),\n SyntheticToggleEvent = createSyntheticEvent(ToggleEventInterface),\n END_KEYCODES = [9, 13, 27, 32],\n canUseCompositionEvent = canUseDOM && \"CompositionEvent\" in window,\n documentMode = null;\ncanUseDOM &&\n \"documentMode\" in document &&\n (documentMode = document.documentMode);\nvar canUseTextInputEvent = canUseDOM && \"TextEvent\" in window && !documentMode,\n useFallbackCompositionData =\n canUseDOM &&\n (!canUseCompositionEvent ||\n (documentMode && 8 < documentMode && 11 >= documentMode)),\n SPACEBAR_CHAR = String.fromCharCode(32),\n hasSpaceKeypress = !1;\nfunction isFallbackCompositionEnd(domEventName, nativeEvent) {\n switch (domEventName) {\n case \"keyup\":\n return -1 !== END_KEYCODES.indexOf(nativeEvent.keyCode);\n case \"keydown\":\n return 229 !== nativeEvent.keyCode;\n case \"keypress\":\n case \"mousedown\":\n case \"focusout\":\n return !0;\n default:\n return !1;\n }\n}\nfunction getDataFromCustomEvent(nativeEvent) {\n nativeEvent = nativeEvent.detail;\n return \"object\" === typeof nativeEvent && \"data\" in nativeEvent\n ? nativeEvent.data\n : null;\n}\nvar isComposing = !1;\nfunction getNativeBeforeInputChars(domEventName, nativeEvent) {\n switch (domEventName) {\n case \"compositionend\":\n return getDataFromCustomEvent(nativeEvent);\n case \"keypress\":\n if (32 !== nativeEvent.which) return null;\n hasSpaceKeypress = !0;\n return SPACEBAR_CHAR;\n case \"textInput\":\n return (\n (domEventName = nativeEvent.data),\n domEventName === SPACEBAR_CHAR && hasSpaceKeypress ? null : domEventName\n );\n default:\n return null;\n }\n}\nfunction getFallbackBeforeInputChars(domEventName, nativeEvent) {\n if (isComposing)\n return \"compositionend\" === domEventName ||\n (!canUseCompositionEvent &&\n isFallbackCompositionEnd(domEventName, nativeEvent))\n ? ((domEventName = getData()),\n (fallbackText = startText = root = null),\n (isComposing = !1),\n domEventName)\n : null;\n switch (domEventName) {\n case \"paste\":\n return null;\n case \"keypress\":\n if (\n !(nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) ||\n (nativeEvent.ctrlKey && nativeEvent.altKey)\n ) {\n if (nativeEvent.char && 1 < nativeEvent.char.length)\n return nativeEvent.char;\n if (nativeEvent.which) return String.fromCharCode(nativeEvent.which);\n }\n return null;\n case \"compositionend\":\n return useFallbackCompositionData && \"ko\" !== nativeEvent.locale\n ? null\n : nativeEvent.data;\n default:\n return null;\n }\n}\nvar supportedInputTypes = {\n color: !0,\n date: !0,\n datetime: !0,\n \"datetime-local\": !0,\n email: !0,\n month: !0,\n number: !0,\n password: !0,\n range: !0,\n search: !0,\n tel: !0,\n text: !0,\n time: !0,\n url: !0,\n week: !0\n};\nfunction isTextInputElement(elem) {\n var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();\n return \"input\" === nodeName\n ? !!supportedInputTypes[elem.type]\n : \"textarea\" === nodeName\n ? !0\n : !1;\n}\nfunction createAndAccumulateChangeEvent(\n dispatchQueue,\n inst,\n nativeEvent,\n target\n) {\n restoreTarget\n ? restoreQueue\n ? restoreQueue.push(target)\n : (restoreQueue = [target])\n : (restoreTarget = target);\n inst = accumulateTwoPhaseListeners(inst, \"onChange\");\n 0 < inst.length &&\n ((nativeEvent = new SyntheticEvent(\n \"onChange\",\n \"change\",\n null,\n nativeEvent,\n target\n )),\n dispatchQueue.push({ event: nativeEvent, listeners: inst }));\n}\nvar activeElement$1 = null,\n activeElementInst$1 = null;\nfunction runEventInBatch(dispatchQueue) {\n processDispatchQueue(dispatchQueue, 0);\n}\nfunction getInstIfValueChanged(targetInst) {\n var targetNode = getNodeFromInstance(targetInst);\n if (updateValueIfChanged(targetNode)) return targetInst;\n}\nfunction getTargetInstForChangeEvent(domEventName, targetInst) {\n if (\"change\" === domEventName) return targetInst;\n}\nvar isInputEventSupported = !1;\nif (canUseDOM) {\n var JSCompiler_inline_result$jscomp$282;\n if (canUseDOM) {\n var isSupported$jscomp$inline_417 = \"oninput\" in document;\n if (!isSupported$jscomp$inline_417) {\n var element$jscomp$inline_418 = document.createElement(\"div\");\n element$jscomp$inline_418.setAttribute(\"oninput\", \"return;\");\n isSupported$jscomp$inline_417 =\n \"function\" === typeof element$jscomp$inline_418.oninput;\n }\n JSCompiler_inline_result$jscomp$282 = isSupported$jscomp$inline_417;\n } else JSCompiler_inline_result$jscomp$282 = !1;\n isInputEventSupported =\n JSCompiler_inline_result$jscomp$282 &&\n (!document.documentMode || 9 < document.documentMode);\n}\nfunction stopWatchingForValueChange() {\n activeElement$1 &&\n (activeElement$1.detachEvent(\"onpropertychange\", handlePropertyChange),\n (activeElementInst$1 = activeElement$1 = null));\n}\nfunction handlePropertyChange(nativeEvent) {\n if (\n \"value\" === nativeEvent.propertyName &&\n getInstIfValueChanged(activeElementInst$1)\n ) {\n var dispatchQueue = [];\n createAndAccumulateChangeEvent(\n dispatchQueue,\n activeElementInst$1,\n nativeEvent,\n getEventTarget(nativeEvent)\n );\n batchedUpdates$1(runEventInBatch, dispatchQueue);\n }\n}\nfunction handleEventsForInputEventPolyfill(domEventName, target, targetInst) {\n \"focusin\" === domEventName\n ? (stopWatchingForValueChange(),\n (activeElement$1 = target),\n (activeElementInst$1 = targetInst),\n activeElement$1.attachEvent(\"onpropertychange\", handlePropertyChange))\n : \"focusout\" === domEventName && stopWatchingForValueChange();\n}\nfunction getTargetInstForInputEventPolyfill(domEventName) {\n if (\n \"selectionchange\" === domEventName ||\n \"keyup\" === domEventName ||\n \"keydown\" === domEventName\n )\n return getInstIfValueChanged(activeElementInst$1);\n}\nfunction getTargetInstForClickEvent(domEventName, targetInst) {\n if (\"click\" === domEventName) return getInstIfValueChanged(targetInst);\n}\nfunction getTargetInstForInputOrChangeEvent(domEventName, targetInst) {\n if (\"input\" === domEventName || \"change\" === domEventName)\n return getInstIfValueChanged(targetInst);\n}\nfunction is(x, y) {\n return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y);\n}\nvar objectIs = \"function\" === typeof Object.is ? Object.is : is;\nfunction shallowEqual(objA, objB) {\n if (objectIs(objA, objB)) return !0;\n if (\n \"object\" !== typeof objA ||\n null === objA ||\n \"object\" !== typeof objB ||\n null === objB\n )\n return !1;\n var keysA = Object.keys(objA),\n keysB = Object.keys(objB);\n if (keysA.length !== keysB.length) return !1;\n for (keysB = 0; keysB < keysA.length; keysB++) {\n var currentKey = keysA[keysB];\n if (\n !hasOwnProperty.call(objB, currentKey) ||\n !objectIs(objA[currentKey], objB[currentKey])\n )\n return !1;\n }\n return !0;\n}\nfunction getLeafNode(node) {\n for (; node && node.firstChild; ) node = node.firstChild;\n return node;\n}\nfunction getNodeForCharacterOffset(root, offset) {\n var node = getLeafNode(root);\n root = 0;\n for (var nodeEnd; node; ) {\n if (3 === node.nodeType) {\n nodeEnd = root + node.textContent.length;\n if (root <= offset && nodeEnd >= offset)\n return { node: node, offset: offset - root };\n root = nodeEnd;\n }\n a: {\n for (; node; ) {\n if (node.nextSibling) {\n node = node.nextSibling;\n break a;\n }\n node = node.parentNode;\n }\n node = void 0;\n }\n node = getLeafNode(node);\n }\n}\nfunction containsNode(outerNode, innerNode) {\n return outerNode && innerNode\n ? outerNode === innerNode\n ? !0\n : outerNode && 3 === outerNode.nodeType\n ? !1\n : innerNode && 3 === innerNode.nodeType\n ? containsNode(outerNode, innerNode.parentNode)\n : \"contains\" in outerNode\n ? outerNode.contains(innerNode)\n : outerNode.compareDocumentPosition\n ? !!(outerNode.compareDocumentPosition(innerNode) & 16)\n : !1\n : !1;\n}\nfunction getActiveElementDeep(containerInfo) {\n containerInfo =\n null != containerInfo &&\n null != containerInfo.ownerDocument &&\n null != containerInfo.ownerDocument.defaultView\n ? containerInfo.ownerDocument.defaultView\n : window;\n for (\n var element = getActiveElement(containerInfo.document);\n element instanceof containerInfo.HTMLIFrameElement;\n\n ) {\n try {\n var JSCompiler_inline_result =\n \"string\" === typeof element.contentWindow.location.href;\n } catch (err) {\n JSCompiler_inline_result = !1;\n }\n if (JSCompiler_inline_result) containerInfo = element.contentWindow;\n else break;\n element = getActiveElement(containerInfo.document);\n }\n return element;\n}\nfunction hasSelectionCapabilities(elem) {\n var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();\n return (\n nodeName &&\n ((\"input\" === nodeName &&\n (\"text\" === elem.type ||\n \"search\" === elem.type ||\n \"tel\" === elem.type ||\n \"url\" === elem.type ||\n \"password\" === elem.type)) ||\n \"textarea\" === nodeName ||\n \"true\" === elem.contentEditable)\n );\n}\nvar skipSelectionChangeEvent =\n canUseDOM && \"documentMode\" in document && 11 >= document.documentMode,\n activeElement = null,\n activeElementInst = null,\n lastSelection = null,\n mouseDown = !1;\nfunction constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget) {\n var doc =\n nativeEventTarget.window === nativeEventTarget\n ? nativeEventTarget.document\n : 9 === nativeEventTarget.nodeType\n ? nativeEventTarget\n : nativeEventTarget.ownerDocument;\n mouseDown ||\n null == activeElement ||\n activeElement !== getActiveElement(doc) ||\n ((doc = activeElement),\n \"selectionStart\" in doc && hasSelectionCapabilities(doc)\n ? (doc = { start: doc.selectionStart, end: doc.selectionEnd })\n : ((doc = (\n (doc.ownerDocument && doc.ownerDocument.defaultView) ||\n window\n ).getSelection()),\n (doc = {\n anchorNode: doc.anchorNode,\n anchorOffset: doc.anchorOffset,\n focusNode: doc.focusNode,\n focusOffset: doc.focusOffset\n })),\n (lastSelection && shallowEqual(lastSelection, doc)) ||\n ((lastSelection = doc),\n (doc = accumulateTwoPhaseListeners(activeElementInst, \"onSelect\")),\n 0 < doc.length &&\n ((nativeEvent = new SyntheticEvent(\n \"onSelect\",\n \"select\",\n null,\n nativeEvent,\n nativeEventTarget\n )),\n dispatchQueue.push({ event: nativeEvent, listeners: doc }),\n (nativeEvent.target = activeElement))));\n}\nfunction makePrefixMap(styleProp, eventName) {\n var prefixes = {};\n prefixes[styleProp.toLowerCase()] = eventName.toLowerCase();\n prefixes[\"Webkit\" + styleProp] = \"webkit\" + eventName;\n prefixes[\"Moz\" + styleProp] = \"moz\" + eventName;\n return prefixes;\n}\nvar vendorPrefixes = {\n animationend: makePrefixMap(\"Animation\", \"AnimationEnd\"),\n animationiteration: makePrefixMap(\"Animation\", \"AnimationIteration\"),\n animationstart: makePrefixMap(\"Animation\", \"AnimationStart\"),\n transitionrun: makePrefixMap(\"Transition\", \"TransitionRun\"),\n transitionstart: makePrefixMap(\"Transition\", \"TransitionStart\"),\n transitioncancel: makePrefixMap(\"Transition\", \"TransitionCancel\"),\n transitionend: makePrefixMap(\"Transition\", \"TransitionEnd\")\n },\n prefixedEventNames = {},\n style = {};\ncanUseDOM &&\n ((style = document.createElement(\"div\").style),\n \"AnimationEvent\" in window ||\n (delete vendorPrefixes.animationend.animation,\n delete vendorPrefixes.animationiteration.animation,\n delete vendorPrefixes.animationstart.animation),\n \"TransitionEvent\" in window ||\n delete vendorPrefixes.transitionend.transition);\nfunction getVendorPrefixedEventName(eventName) {\n if (prefixedEventNames[eventName]) return prefixedEventNames[eventName];\n if (!vendorPrefixes[eventName]) return eventName;\n var prefixMap = vendorPrefixes[eventName],\n styleProp;\n for (styleProp in prefixMap)\n if (prefixMap.hasOwnProperty(styleProp) && styleProp in style)\n return (prefixedEventNames[eventName] = prefixMap[styleProp]);\n return eventName;\n}\nvar ANIMATION_END = getVendorPrefixedEventName(\"animationend\"),\n ANIMATION_ITERATION = getVendorPrefixedEventName(\"animationiteration\"),\n ANIMATION_START = getVendorPrefixedEventName(\"animationstart\"),\n TRANSITION_RUN = getVendorPrefixedEventName(\"transitionrun\"),\n TRANSITION_START = getVendorPrefixedEventName(\"transitionstart\"),\n TRANSITION_CANCEL = getVendorPrefixedEventName(\"transitioncancel\"),\n TRANSITION_END = getVendorPrefixedEventName(\"transitionend\"),\n topLevelEventsToReactNames = new Map(),\n simpleEventPluginEvents =\n \"abort auxClick beforeToggle cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel\".split(\n \" \"\n );\nsimpleEventPluginEvents.push(\"scrollEnd\");\nfunction registerSimpleEvent(domEventName, reactName) {\n topLevelEventsToReactNames.set(domEventName, reactName);\n registerTwoPhaseEvent(reactName, [domEventName]);\n}\nvar CapturedStacks = new WeakMap();\nfunction createCapturedValueAtFiber(value, source) {\n if (\"object\" === typeof value && null !== value) {\n var existing = CapturedStacks.get(value);\n if (void 0 !== existing) return existing;\n source = {\n value: value,\n source: source,\n stack: getStackByFiberInDevAndProd(source)\n };\n CapturedStacks.set(value, source);\n return source;\n }\n return {\n value: value,\n source: source,\n stack: getStackByFiberInDevAndProd(source)\n };\n}\nvar concurrentQueues = [],\n concurrentQueuesIndex = 0,\n concurrentlyUpdatedLanes = 0;\nfunction finishQueueingConcurrentUpdates() {\n for (\n var endIndex = concurrentQueuesIndex,\n i = (concurrentlyUpdatedLanes = concurrentQueuesIndex = 0);\n i < endIndex;\n\n ) {\n var fiber = concurrentQueues[i];\n concurrentQueues[i++] = null;\n var queue = concurrentQueues[i];\n concurrentQueues[i++] = null;\n var update = concurrentQueues[i];\n concurrentQueues[i++] = null;\n var lane = concurrentQueues[i];\n concurrentQueues[i++] = null;\n if (null !== queue && null !== update) {\n var pending = queue.pending;\n null === pending\n ? (update.next = update)\n : ((update.next = pending.next), (pending.next = update));\n queue.pending = update;\n }\n 0 !== lane && markUpdateLaneFromFiberToRoot(fiber, update, lane);\n }\n}\nfunction enqueueUpdate$1(fiber, queue, update, lane) {\n concurrentQueues[concurrentQueuesIndex++] = fiber;\n concurrentQueues[concurrentQueuesIndex++] = queue;\n concurrentQueues[concurrentQueuesIndex++] = update;\n concurrentQueues[concurrentQueuesIndex++] = lane;\n concurrentlyUpdatedLanes |= lane;\n fiber.lanes |= lane;\n fiber = fiber.alternate;\n null !== fiber && (fiber.lanes |= lane);\n}\nfunction enqueueConcurrentHookUpdate(fiber, queue, update, lane) {\n enqueueUpdate$1(fiber, queue, update, lane);\n return getRootForUpdatedFiber(fiber);\n}\nfunction enqueueConcurrentRenderForLane(fiber, lane) {\n enqueueUpdate$1(fiber, null, null, lane);\n return getRootForUpdatedFiber(fiber);\n}\nfunction markUpdateLaneFromFiberToRoot(sourceFiber, update, lane) {\n sourceFiber.lanes |= lane;\n var alternate = sourceFiber.alternate;\n null !== alternate && (alternate.lanes |= lane);\n for (var isHidden = !1, parent = sourceFiber.return; null !== parent; )\n (parent.childLanes |= lane),\n (alternate = parent.alternate),\n null !== alternate && (alternate.childLanes |= lane),\n 22 === parent.tag &&\n ((sourceFiber = parent.stateNode),\n null === sourceFiber || sourceFiber._visibility & 1 || (isHidden = !0)),\n (sourceFiber = parent),\n (parent = parent.return);\n return 3 === sourceFiber.tag\n ? ((parent = sourceFiber.stateNode),\n isHidden &&\n null !== update &&\n ((isHidden = 31 - clz32(lane)),\n (sourceFiber = parent.hiddenUpdates),\n (alternate = sourceFiber[isHidden]),\n null === alternate\n ? (sourceFiber[isHidden] = [update])\n : alternate.push(update),\n (update.lane = lane | 536870912)),\n parent)\n : null;\n}\nfunction getRootForUpdatedFiber(sourceFiber) {\n if (50 < nestedUpdateCount)\n throw (\n ((nestedUpdateCount = 0),\n (rootWithNestedUpdates = null),\n Error(formatProdErrorMessage(185)))\n );\n for (var parent = sourceFiber.return; null !== parent; )\n (sourceFiber = parent), (parent = sourceFiber.return);\n return 3 === sourceFiber.tag ? sourceFiber.stateNode : null;\n}\nvar emptyContextObject = {};\nfunction FiberNode(tag, pendingProps, key, mode) {\n this.tag = tag;\n this.key = key;\n this.sibling =\n this.child =\n this.return =\n this.stateNode =\n this.type =\n this.elementType =\n null;\n this.index = 0;\n this.refCleanup = this.ref = null;\n this.pendingProps = pendingProps;\n this.dependencies =\n this.memoizedState =\n this.updateQueue =\n this.memoizedProps =\n null;\n this.mode = mode;\n this.subtreeFlags = this.flags = 0;\n this.deletions = null;\n this.childLanes = this.lanes = 0;\n this.alternate = null;\n}\nfunction createFiberImplClass(tag, pendingProps, key, mode) {\n return new FiberNode(tag, pendingProps, key, mode);\n}\nfunction shouldConstruct(Component) {\n Component = Component.prototype;\n return !(!Component || !Component.isReactComponent);\n}\nfunction createWorkInProgress(current, pendingProps) {\n var workInProgress = current.alternate;\n null === workInProgress\n ? ((workInProgress = createFiberImplClass(\n current.tag,\n pendingProps,\n current.key,\n current.mode\n )),\n (workInProgress.elementType = current.elementType),\n (workInProgress.type = current.type),\n (workInProgress.stateNode = current.stateNode),\n (workInProgress.alternate = current),\n (current.alternate = workInProgress))\n : ((workInProgress.pendingProps = pendingProps),\n (workInProgress.type = current.type),\n (workInProgress.flags = 0),\n (workInProgress.subtreeFlags = 0),\n (workInProgress.deletions = null));\n workInProgress.flags = current.flags & 65011712;\n workInProgress.childLanes = current.childLanes;\n workInProgress.lanes = current.lanes;\n workInProgress.child = current.child;\n workInProgress.memoizedProps = current.memoizedProps;\n workInProgress.memoizedState = current.memoizedState;\n workInProgress.updateQueue = current.updateQueue;\n pendingProps = current.dependencies;\n workInProgress.dependencies =\n null === pendingProps\n ? null\n : { lanes: pendingProps.lanes, firstContext: pendingProps.firstContext };\n workInProgress.sibling = current.sibling;\n workInProgress.index = current.index;\n workInProgress.ref = current.ref;\n workInProgress.refCleanup = current.refCleanup;\n return workInProgress;\n}\nfunction resetWorkInProgress(workInProgress, renderLanes) {\n workInProgress.flags &= 65011714;\n var current = workInProgress.alternate;\n null === current\n ? ((workInProgress.childLanes = 0),\n (workInProgress.lanes = renderLanes),\n (workInProgress.child = null),\n (workInProgress.subtreeFlags = 0),\n (workInProgress.memoizedProps = null),\n (workInProgress.memoizedState = null),\n (workInProgress.updateQueue = null),\n (workInProgress.dependencies = null),\n (workInProgress.stateNode = null))\n : ((workInProgress.childLanes = current.childLanes),\n (workInProgress.lanes = current.lanes),\n (workInProgress.child = current.child),\n (workInProgress.subtreeFlags = 0),\n (workInProgress.deletions = null),\n (workInProgress.memoizedProps = current.memoizedProps),\n (workInProgress.memoizedState = current.memoizedState),\n (workInProgress.updateQueue = current.updateQueue),\n (workInProgress.type = current.type),\n (renderLanes = current.dependencies),\n (workInProgress.dependencies =\n null === renderLanes\n ? null\n : {\n lanes: renderLanes.lanes,\n firstContext: renderLanes.firstContext\n }));\n return workInProgress;\n}\nfunction createFiberFromTypeAndProps(\n type,\n key,\n pendingProps,\n owner,\n mode,\n lanes\n) {\n var fiberTag = 0;\n owner = type;\n if (\"function\" === typeof type) shouldConstruct(type) && (fiberTag = 1);\n else if (\"string\" === typeof type)\n fiberTag = isHostHoistableType(\n type,\n pendingProps,\n contextStackCursor.current\n )\n ? 26\n : \"html\" === type || \"head\" === type || \"body\" === type\n ? 27\n : 5;\n else\n a: switch (type) {\n case REACT_ACTIVITY_TYPE:\n return (\n (type = createFiberImplClass(31, pendingProps, key, mode)),\n (type.elementType = REACT_ACTIVITY_TYPE),\n (type.lanes = lanes),\n type\n );\n case REACT_FRAGMENT_TYPE:\n return createFiberFromFragment(pendingProps.children, mode, lanes, key);\n case REACT_STRICT_MODE_TYPE:\n fiberTag = 8;\n mode |= 24;\n break;\n case REACT_PROFILER_TYPE:\n return (\n (type = createFiberImplClass(12, pendingProps, key, mode | 2)),\n (type.elementType = REACT_PROFILER_TYPE),\n (type.lanes = lanes),\n type\n );\n case REACT_SUSPENSE_TYPE:\n return (\n (type = createFiberImplClass(13, pendingProps, key, mode)),\n (type.elementType = REACT_SUSPENSE_TYPE),\n (type.lanes = lanes),\n type\n );\n case REACT_SUSPENSE_LIST_TYPE:\n return (\n (type = createFiberImplClass(19, pendingProps, key, mode)),\n (type.elementType = REACT_SUSPENSE_LIST_TYPE),\n (type.lanes = lanes),\n type\n );\n default:\n if (\"object\" === typeof type && null !== type)\n switch (type.$$typeof) {\n case REACT_PROVIDER_TYPE:\n case REACT_CONTEXT_TYPE:\n fiberTag = 10;\n break a;\n case REACT_CONSUMER_TYPE:\n fiberTag = 9;\n break a;\n case REACT_FORWARD_REF_TYPE:\n fiberTag = 11;\n break a;\n case REACT_MEMO_TYPE:\n fiberTag = 14;\n break a;\n case REACT_LAZY_TYPE:\n fiberTag = 16;\n owner = null;\n break a;\n }\n fiberTag = 29;\n pendingProps = Error(\n formatProdErrorMessage(130, null === type ? \"null\" : typeof type, \"\")\n );\n owner = null;\n }\n key = createFiberImplClass(fiberTag, pendingProps, key, mode);\n key.elementType = type;\n key.type = owner;\n key.lanes = lanes;\n return key;\n}\nfunction createFiberFromFragment(elements, mode, lanes, key) {\n elements = createFiberImplClass(7, elements, key, mode);\n elements.lanes = lanes;\n return elements;\n}\nfunction createFiberFromText(content, mode, lanes) {\n content = createFiberImplClass(6, content, null, mode);\n content.lanes = lanes;\n return content;\n}\nfunction createFiberFromPortal(portal, mode, lanes) {\n mode = createFiberImplClass(\n 4,\n null !== portal.children ? portal.children : [],\n portal.key,\n mode\n );\n mode.lanes = lanes;\n mode.stateNode = {\n containerInfo: portal.containerInfo,\n pendingChildren: null,\n implementation: portal.implementation\n };\n return mode;\n}\nvar forkStack = [],\n forkStackIndex = 0,\n treeForkProvider = null,\n treeForkCount = 0,\n idStack = [],\n idStackIndex = 0,\n treeContextProvider = null,\n treeContextId = 1,\n treeContextOverflow = \"\";\nfunction pushTreeFork(workInProgress, totalChildren) {\n forkStack[forkStackIndex++] = treeForkCount;\n forkStack[forkStackIndex++] = treeForkProvider;\n treeForkProvider = workInProgress;\n treeForkCount = totalChildren;\n}\nfunction pushTreeId(workInProgress, totalChildren, index) {\n idStack[idStackIndex++] = treeContextId;\n idStack[idStackIndex++] = treeContextOverflow;\n idStack[idStackIndex++] = treeContextProvider;\n treeContextProvider = workInProgress;\n var baseIdWithLeadingBit = treeContextId;\n workInProgress = treeContextOverflow;\n var baseLength = 32 - clz32(baseIdWithLeadingBit) - 1;\n baseIdWithLeadingBit &= ~(1 << baseLength);\n index += 1;\n var length = 32 - clz32(totalChildren) + baseLength;\n if (30 < length) {\n var numberOfOverflowBits = baseLength - (baseLength % 5);\n length = (\n baseIdWithLeadingBit &\n ((1 << numberOfOverflowBits) - 1)\n ).toString(32);\n baseIdWithLeadingBit >>= numberOfOverflowBits;\n baseLength -= numberOfOverflowBits;\n treeContextId =\n (1 << (32 - clz32(totalChildren) + baseLength)) |\n (index << baseLength) |\n baseIdWithLeadingBit;\n treeContextOverflow = length + workInProgress;\n } else\n (treeContextId =\n (1 << length) | (index << baseLength) | baseIdWithLeadingBit),\n (treeContextOverflow = workInProgress);\n}\nfunction pushMaterializedTreeId(workInProgress) {\n null !== workInProgress.return &&\n (pushTreeFork(workInProgress, 1), pushTreeId(workInProgress, 1, 0));\n}\nfunction popTreeContext(workInProgress) {\n for (; workInProgress === treeForkProvider; )\n (treeForkProvider = forkStack[--forkStackIndex]),\n (forkStack[forkStackIndex] = null),\n (treeForkCount = forkStack[--forkStackIndex]),\n (forkStack[forkStackIndex] = null);\n for (; workInProgress === treeContextProvider; )\n (treeContextProvider = idStack[--idStackIndex]),\n (idStack[idStackIndex] = null),\n (treeContextOverflow = idStack[--idStackIndex]),\n (idStack[idStackIndex] = null),\n (treeContextId = idStack[--idStackIndex]),\n (idStack[idStackIndex] = null);\n}\nvar hydrationParentFiber = null,\n nextHydratableInstance = null,\n isHydrating = !1,\n hydrationErrors = null,\n rootOrSingletonContext = !1,\n HydrationMismatchException = Error(formatProdErrorMessage(519));\nfunction throwOnHydrationMismatch(fiber) {\n var error = Error(formatProdErrorMessage(418, \"\"));\n queueHydrationError(createCapturedValueAtFiber(error, fiber));\n throw HydrationMismatchException;\n}\nfunction prepareToHydrateHostInstance(fiber) {\n var instance = fiber.stateNode,\n type = fiber.type,\n props = fiber.memoizedProps;\n instance[internalInstanceKey] = fiber;\n instance[internalPropsKey] = props;\n switch (type) {\n case \"dialog\":\n listenToNonDelegatedEvent(\"cancel\", instance);\n listenToNonDelegatedEvent(\"close\", instance);\n break;\n case \"iframe\":\n case \"object\":\n case \"embed\":\n listenToNonDelegatedEvent(\"load\", instance);\n break;\n case \"video\":\n case \"audio\":\n for (type = 0; type < mediaEventTypes.length; type++)\n listenToNonDelegatedEvent(mediaEventTypes[type], instance);\n break;\n case \"source\":\n listenToNonDelegatedEvent(\"error\", instance);\n break;\n case \"img\":\n case \"image\":\n case \"link\":\n listenToNonDelegatedEvent(\"error\", instance);\n listenToNonDelegatedEvent(\"load\", instance);\n break;\n case \"details\":\n listenToNonDelegatedEvent(\"toggle\", instance);\n break;\n case \"input\":\n listenToNonDelegatedEvent(\"invalid\", instance);\n initInput(\n instance,\n props.value,\n props.defaultValue,\n props.checked,\n props.defaultChecked,\n props.type,\n props.name,\n !0\n );\n track(instance);\n break;\n case \"select\":\n listenToNonDelegatedEvent(\"invalid\", instance);\n break;\n case \"textarea\":\n listenToNonDelegatedEvent(\"invalid\", instance),\n initTextarea(instance, props.value, props.defaultValue, props.children),\n track(instance);\n }\n type = props.children;\n (\"string\" !== typeof type &&\n \"number\" !== typeof type &&\n \"bigint\" !== typeof type) ||\n instance.textContent === \"\" + type ||\n !0 === props.suppressHydrationWarning ||\n checkForUnmatchedText(instance.textContent, type)\n ? (null != props.popover &&\n (listenToNonDelegatedEvent(\"beforetoggle\", instance),\n listenToNonDelegatedEvent(\"toggle\", instance)),\n null != props.onScroll && listenToNonDelegatedEvent(\"scroll\", instance),\n null != props.onScrollEnd &&\n listenToNonDelegatedEvent(\"scrollend\", instance),\n null != props.onClick && (instance.onclick = noop$1),\n (instance = !0))\n : (instance = !1);\n instance || throwOnHydrationMismatch(fiber);\n}\nfunction popToNextHostParent(fiber) {\n for (hydrationParentFiber = fiber.return; hydrationParentFiber; )\n switch (hydrationParentFiber.tag) {\n case 5:\n case 13:\n rootOrSingletonContext = !1;\n return;\n case 27:\n case 3:\n rootOrSingletonContext = !0;\n return;\n default:\n hydrationParentFiber = hydrationParentFiber.return;\n }\n}\nfunction popHydrationState(fiber) {\n if (fiber !== hydrationParentFiber) return !1;\n if (!isHydrating) return popToNextHostParent(fiber), (isHydrating = !0), !1;\n var tag = fiber.tag,\n JSCompiler_temp;\n if ((JSCompiler_temp = 3 !== tag && 27 !== tag)) {\n if ((JSCompiler_temp = 5 === tag))\n (JSCompiler_temp = fiber.type),\n (JSCompiler_temp =\n !(\"form\" !== JSCompiler_temp && \"button\" !== JSCompiler_temp) ||\n shouldSetTextContent(fiber.type, fiber.memoizedProps));\n JSCompiler_temp = !JSCompiler_temp;\n }\n JSCompiler_temp && nextHydratableInstance && throwOnHydrationMismatch(fiber);\n popToNextHostParent(fiber);\n if (13 === tag) {\n fiber = fiber.memoizedState;\n fiber = null !== fiber ? fiber.dehydrated : null;\n if (!fiber) throw Error(formatProdErrorMessage(317));\n a: {\n fiber = fiber.nextSibling;\n for (tag = 0; fiber; ) {\n if (8 === fiber.nodeType)\n if (((JSCompiler_temp = fiber.data), \"/$\" === JSCompiler_temp)) {\n if (0 === tag) {\n nextHydratableInstance = getNextHydratable(fiber.nextSibling);\n break a;\n }\n tag--;\n } else\n (\"$\" !== JSCompiler_temp &&\n \"$!\" !== JSCompiler_temp &&\n \"$?\" !== JSCompiler_temp) ||\n tag++;\n fiber = fiber.nextSibling;\n }\n nextHydratableInstance = null;\n }\n } else\n 27 === tag\n ? ((tag = nextHydratableInstance),\n isSingletonScope(fiber.type)\n ? ((fiber = previousHydratableOnEnteringScopedSingleton),\n (previousHydratableOnEnteringScopedSingleton = null),\n (nextHydratableInstance = fiber))\n : (nextHydratableInstance = tag))\n : (nextHydratableInstance = hydrationParentFiber\n ? getNextHydratable(fiber.stateNode.nextSibling)\n : null);\n return !0;\n}\nfunction resetHydrationState() {\n nextHydratableInstance = hydrationParentFiber = null;\n isHydrating = !1;\n}\nfunction upgradeHydrationErrorsToRecoverable() {\n var queuedErrors = hydrationErrors;\n null !== queuedErrors &&\n (null === workInProgressRootRecoverableErrors\n ? (workInProgressRootRecoverableErrors = queuedErrors)\n : workInProgressRootRecoverableErrors.push.apply(\n workInProgressRootRecoverableErrors,\n queuedErrors\n ),\n (hydrationErrors = null));\n return queuedErrors;\n}\nfunction queueHydrationError(error) {\n null === hydrationErrors\n ? (hydrationErrors = [error])\n : hydrationErrors.push(error);\n}\nvar valueCursor = createCursor(null),\n currentlyRenderingFiber$1 = null,\n lastContextDependency = null;\nfunction pushProvider(providerFiber, context, nextValue) {\n push(valueCursor, context._currentValue);\n context._currentValue = nextValue;\n}\nfunction popProvider(context) {\n context._currentValue = valueCursor.current;\n pop(valueCursor);\n}\nfunction scheduleContextWorkOnParentPath(parent, renderLanes, propagationRoot) {\n for (; null !== parent; ) {\n var alternate = parent.alternate;\n (parent.childLanes & renderLanes) !== renderLanes\n ? ((parent.childLanes |= renderLanes),\n null !== alternate && (alternate.childLanes |= renderLanes))\n : null !== alternate &&\n (alternate.childLanes & renderLanes) !== renderLanes &&\n (alternate.childLanes |= renderLanes);\n if (parent === propagationRoot) break;\n parent = parent.return;\n }\n}\nfunction propagateContextChanges(\n workInProgress,\n contexts,\n renderLanes,\n forcePropagateEntireTree\n) {\n var fiber = workInProgress.child;\n null !== fiber && (fiber.return = workInProgress);\n for (; null !== fiber; ) {\n var list = fiber.dependencies;\n if (null !== list) {\n var nextFiber = fiber.child;\n list = list.firstContext;\n a: for (; null !== list; ) {\n var dependency = list;\n list = fiber;\n for (var i = 0; i < contexts.length; i++)\n if (dependency.context === contexts[i]) {\n list.lanes |= renderLanes;\n dependency = list.alternate;\n null !== dependency && (dependency.lanes |= renderLanes);\n scheduleContextWorkOnParentPath(\n list.return,\n renderLanes,\n workInProgress\n );\n forcePropagateEntireTree || (nextFiber = null);\n break a;\n }\n list = dependency.next;\n }\n } else if (18 === fiber.tag) {\n nextFiber = fiber.return;\n if (null === nextFiber) throw Error(formatProdErrorMessage(341));\n nextFiber.lanes |= renderLanes;\n list = nextFiber.alternate;\n null !== list && (list.lanes |= renderLanes);\n scheduleContextWorkOnParentPath(nextFiber, renderLanes, workInProgress);\n nextFiber = null;\n } else nextFiber = fiber.child;\n if (null !== nextFiber) nextFiber.return = fiber;\n else\n for (nextFiber = fiber; null !== nextFiber; ) {\n if (nextFiber === workInProgress) {\n nextFiber = null;\n break;\n }\n fiber = nextFiber.sibling;\n if (null !== fiber) {\n fiber.return = nextFiber.return;\n nextFiber = fiber;\n break;\n }\n nextFiber = nextFiber.return;\n }\n fiber = nextFiber;\n }\n}\nfunction propagateParentContextChanges(\n current,\n workInProgress,\n renderLanes,\n forcePropagateEntireTree\n) {\n current = null;\n for (\n var parent = workInProgress, isInsidePropagationBailout = !1;\n null !== parent;\n\n ) {\n if (!isInsidePropagationBailout)\n if (0 !== (parent.flags & 524288)) isInsidePropagationBailout = !0;\n else if (0 !== (parent.flags & 262144)) break;\n if (10 === parent.tag) {\n var currentParent = parent.alternate;\n if (null === currentParent) throw Error(formatProdErrorMessage(387));\n currentParent = currentParent.memoizedProps;\n if (null !== currentParent) {\n var context = parent.type;\n objectIs(parent.pendingProps.value, currentParent.value) ||\n (null !== current ? current.push(context) : (current = [context]));\n }\n } else if (parent === hostTransitionProviderCursor.current) {\n currentParent = parent.alternate;\n if (null === currentParent) throw Error(formatProdErrorMessage(387));\n currentParent.memoizedState.memoizedState !==\n parent.memoizedState.memoizedState &&\n (null !== current\n ? current.push(HostTransitionContext)\n : (current = [HostTransitionContext]));\n }\n parent = parent.return;\n }\n null !== current &&\n propagateContextChanges(\n workInProgress,\n current,\n renderLanes,\n forcePropagateEntireTree\n );\n workInProgress.flags |= 262144;\n}\nfunction checkIfContextChanged(currentDependencies) {\n for (\n currentDependencies = currentDependencies.firstContext;\n null !== currentDependencies;\n\n ) {\n if (\n !objectIs(\n currentDependencies.context._currentValue,\n currentDependencies.memoizedValue\n )\n )\n return !0;\n currentDependencies = currentDependencies.next;\n }\n return !1;\n}\nfunction prepareToReadContext(workInProgress) {\n currentlyRenderingFiber$1 = workInProgress;\n lastContextDependency = null;\n workInProgress = workInProgress.dependencies;\n null !== workInProgress && (workInProgress.firstContext = null);\n}\nfunction readContext(context) {\n return readContextForConsumer(currentlyRenderingFiber$1, context);\n}\nfunction readContextDuringReconciliation(consumer, context) {\n null === currentlyRenderingFiber$1 && prepareToReadContext(consumer);\n return readContextForConsumer(consumer, context);\n}\nfunction readContextForConsumer(consumer, context) {\n var value = context._currentValue;\n context = { context: context, memoizedValue: value, next: null };\n if (null === lastContextDependency) {\n if (null === consumer) throw Error(formatProdErrorMessage(308));\n lastContextDependency = context;\n consumer.dependencies = { lanes: 0, firstContext: context };\n consumer.flags |= 524288;\n } else lastContextDependency = lastContextDependency.next = context;\n return value;\n}\nvar AbortControllerLocal =\n \"undefined\" !== typeof AbortController\n ? AbortController\n : function () {\n var listeners = [],\n signal = (this.signal = {\n aborted: !1,\n addEventListener: function (type, listener) {\n listeners.push(listener);\n }\n });\n this.abort = function () {\n signal.aborted = !0;\n listeners.forEach(function (listener) {\n return listener();\n });\n };\n },\n scheduleCallback$2 = Scheduler.unstable_scheduleCallback,\n NormalPriority = Scheduler.unstable_NormalPriority,\n CacheContext = {\n $$typeof: REACT_CONTEXT_TYPE,\n Consumer: null,\n Provider: null,\n _currentValue: null,\n _currentValue2: null,\n _threadCount: 0\n };\nfunction createCache() {\n return {\n controller: new AbortControllerLocal(),\n data: new Map(),\n refCount: 0\n };\n}\nfunction releaseCache(cache) {\n cache.refCount--;\n 0 === cache.refCount &&\n scheduleCallback$2(NormalPriority, function () {\n cache.controller.abort();\n });\n}\nvar currentEntangledListeners = null,\n currentEntangledPendingCount = 0,\n currentEntangledLane = 0,\n currentEntangledActionThenable = null;\nfunction entangleAsyncAction(transition, thenable) {\n if (null === currentEntangledListeners) {\n var entangledListeners = (currentEntangledListeners = []);\n currentEntangledPendingCount = 0;\n currentEntangledLane = requestTransitionLane();\n currentEntangledActionThenable = {\n status: \"pending\",\n value: void 0,\n then: function (resolve) {\n entangledListeners.push(resolve);\n }\n };\n }\n currentEntangledPendingCount++;\n thenable.then(pingEngtangledActionScope, pingEngtangledActionScope);\n return thenable;\n}\nfunction pingEngtangledActionScope() {\n if (\n 0 === --currentEntangledPendingCount &&\n null !== currentEntangledListeners\n ) {\n null !== currentEntangledActionThenable &&\n (currentEntangledActionThenable.status = \"fulfilled\");\n var listeners = currentEntangledListeners;\n currentEntangledListeners = null;\n currentEntangledLane = 0;\n currentEntangledActionThenable = null;\n for (var i = 0; i < listeners.length; i++) (0, listeners[i])();\n }\n}\nfunction chainThenableValue(thenable, result) {\n var listeners = [],\n thenableWithOverride = {\n status: \"pending\",\n value: null,\n reason: null,\n then: function (resolve) {\n listeners.push(resolve);\n }\n };\n thenable.then(\n function () {\n thenableWithOverride.status = \"fulfilled\";\n thenableWithOverride.value = result;\n for (var i = 0; i < listeners.length; i++) (0, listeners[i])(result);\n },\n function (error) {\n thenableWithOverride.status = \"rejected\";\n thenableWithOverride.reason = error;\n for (error = 0; error < listeners.length; error++)\n (0, listeners[error])(void 0);\n }\n );\n return thenableWithOverride;\n}\nvar prevOnStartTransitionFinish = ReactSharedInternals.S;\nReactSharedInternals.S = function (transition, returnValue) {\n \"object\" === typeof returnValue &&\n null !== returnValue &&\n \"function\" === typeof returnValue.then &&\n entangleAsyncAction(transition, returnValue);\n null !== prevOnStartTransitionFinish &&\n prevOnStartTransitionFinish(transition, returnValue);\n};\nvar resumedCache = createCursor(null);\nfunction peekCacheFromPool() {\n var cacheResumedFromPreviousRender = resumedCache.current;\n return null !== cacheResumedFromPreviousRender\n ? cacheResumedFromPreviousRender\n : workInProgressRoot.pooledCache;\n}\nfunction pushTransition(offscreenWorkInProgress, prevCachePool) {\n null === prevCachePool\n ? push(resumedCache, resumedCache.current)\n : push(resumedCache, prevCachePool.pool);\n}\nfunction getSuspendedCache() {\n var cacheFromPool = peekCacheFromPool();\n return null === cacheFromPool\n ? null\n : { parent: CacheContext._currentValue, pool: cacheFromPool };\n}\nvar SuspenseException = Error(formatProdErrorMessage(460)),\n SuspenseyCommitException = Error(formatProdErrorMessage(474)),\n SuspenseActionException = Error(formatProdErrorMessage(542)),\n noopSuspenseyCommitThenable = { then: function () {} };\nfunction isThenableResolved(thenable) {\n thenable = thenable.status;\n return \"fulfilled\" === thenable || \"rejected\" === thenable;\n}\nfunction noop$3() {}\nfunction trackUsedThenable(thenableState, thenable, index) {\n index = thenableState[index];\n void 0 === index\n ? thenableState.push(thenable)\n : index !== thenable && (thenable.then(noop$3, noop$3), (thenable = index));\n switch (thenable.status) {\n case \"fulfilled\":\n return thenable.value;\n case \"rejected\":\n throw (\n ((thenableState = thenable.reason),\n checkIfUseWrappedInAsyncCatch(thenableState),\n thenableState)\n );\n default:\n if (\"string\" === typeof thenable.status) thenable.then(noop$3, noop$3);\n else {\n thenableState = workInProgressRoot;\n if (null !== thenableState && 100 < thenableState.shellSuspendCounter)\n throw Error(formatProdErrorMessage(482));\n thenableState = thenable;\n thenableState.status = \"pending\";\n thenableState.then(\n function (fulfilledValue) {\n if (\"pending\" === thenable.status) {\n var fulfilledThenable = thenable;\n fulfilledThenable.status = \"fulfilled\";\n fulfilledThenable.value = fulfilledValue;\n }\n },\n function (error) {\n if (\"pending\" === thenable.status) {\n var rejectedThenable = thenable;\n rejectedThenable.status = \"rejected\";\n rejectedThenable.reason = error;\n }\n }\n );\n }\n switch (thenable.status) {\n case \"fulfilled\":\n return thenable.value;\n case \"rejected\":\n throw (\n ((thenableState = thenable.reason),\n checkIfUseWrappedInAsyncCatch(thenableState),\n thenableState)\n );\n }\n suspendedThenable = thenable;\n throw SuspenseException;\n }\n}\nvar suspendedThenable = null;\nfunction getSuspendedThenable() {\n if (null === suspendedThenable) throw Error(formatProdErrorMessage(459));\n var thenable = suspendedThenable;\n suspendedThenable = null;\n return thenable;\n}\nfunction checkIfUseWrappedInAsyncCatch(rejectedReason) {\n if (\n rejectedReason === SuspenseException ||\n rejectedReason === SuspenseActionException\n )\n throw Error(formatProdErrorMessage(483));\n}\nvar hasForceUpdate = !1;\nfunction initializeUpdateQueue(fiber) {\n fiber.updateQueue = {\n baseState: fiber.memoizedState,\n firstBaseUpdate: null,\n lastBaseUpdate: null,\n shared: { pending: null, lanes: 0, hiddenCallbacks: null },\n callbacks: null\n };\n}\nfunction cloneUpdateQueue(current, workInProgress) {\n current = current.updateQueue;\n workInProgress.updateQueue === current &&\n (workInProgress.updateQueue = {\n baseState: current.baseState,\n firstBaseUpdate: current.firstBaseUpdate,\n lastBaseUpdate: current.lastBaseUpdate,\n shared: current.shared,\n callbacks: null\n });\n}\nfunction createUpdate(lane) {\n return { lane: lane, tag: 0, payload: null, callback: null, next: null };\n}\nfunction enqueueUpdate(fiber, update, lane) {\n var updateQueue = fiber.updateQueue;\n if (null === updateQueue) return null;\n updateQueue = updateQueue.shared;\n if (0 !== (executionContext & 2)) {\n var pending = updateQueue.pending;\n null === pending\n ? (update.next = update)\n : ((update.next = pending.next), (pending.next = update));\n updateQueue.pending = update;\n update = getRootForUpdatedFiber(fiber);\n markUpdateLaneFromFiberToRoot(fiber, null, lane);\n return update;\n }\n enqueueUpdate$1(fiber, updateQueue, update, lane);\n return getRootForUpdatedFiber(fiber);\n}\nfunction entangleTransitions(root, fiber, lane) {\n fiber = fiber.updateQueue;\n if (null !== fiber && ((fiber = fiber.shared), 0 !== (lane & 4194048))) {\n var queueLanes = fiber.lanes;\n queueLanes &= root.pendingLanes;\n lane |= queueLanes;\n fiber.lanes = lane;\n markRootEntangled(root, lane);\n }\n}\nfunction enqueueCapturedUpdate(workInProgress, capturedUpdate) {\n var queue = workInProgress.updateQueue,\n current = workInProgress.alternate;\n if (\n null !== current &&\n ((current = current.updateQueue), queue === current)\n ) {\n var newFirst = null,\n newLast = null;\n queue = queue.firstBaseUpdate;\n if (null !== queue) {\n do {\n var clone = {\n lane: queue.lane,\n tag: queue.tag,\n payload: queue.payload,\n callback: null,\n next: null\n };\n null === newLast\n ? (newFirst = newLast = clone)\n : (newLast = newLast.next = clone);\n queue = queue.next;\n } while (null !== queue);\n null === newLast\n ? (newFirst = newLast = capturedUpdate)\n : (newLast = newLast.next = capturedUpdate);\n } else newFirst = newLast = capturedUpdate;\n queue = {\n baseState: current.baseState,\n firstBaseUpdate: newFirst,\n lastBaseUpdate: newLast,\n shared: current.shared,\n callbacks: current.callbacks\n };\n workInProgress.updateQueue = queue;\n return;\n }\n workInProgress = queue.lastBaseUpdate;\n null === workInProgress\n ? (queue.firstBaseUpdate = capturedUpdate)\n : (workInProgress.next = capturedUpdate);\n queue.lastBaseUpdate = capturedUpdate;\n}\nvar didReadFromEntangledAsyncAction = !1;\nfunction suspendIfUpdateReadFromEntangledAsyncAction() {\n if (didReadFromEntangledAsyncAction) {\n var entangledActionThenable = currentEntangledActionThenable;\n if (null !== entangledActionThenable) throw entangledActionThenable;\n }\n}\nfunction processUpdateQueue(\n workInProgress$jscomp$0,\n props,\n instance$jscomp$0,\n renderLanes\n) {\n didReadFromEntangledAsyncAction = !1;\n var queue = workInProgress$jscomp$0.updateQueue;\n hasForceUpdate = !1;\n var firstBaseUpdate = queue.firstBaseUpdate,\n lastBaseUpdate = queue.lastBaseUpdate,\n pendingQueue = queue.shared.pending;\n if (null !== pendingQueue) {\n queue.shared.pending = null;\n var lastPendingUpdate = pendingQueue,\n firstPendingUpdate = lastPendingUpdate.next;\n lastPendingUpdate.next = null;\n null === lastBaseUpdate\n ? (firstBaseUpdate = firstPendingUpdate)\n : (lastBaseUpdate.next = firstPendingUpdate);\n lastBaseUpdate = lastPendingUpdate;\n var current = workInProgress$jscomp$0.alternate;\n null !== current &&\n ((current = current.updateQueue),\n (pendingQueue = current.lastBaseUpdate),\n pendingQueue !== lastBaseUpdate &&\n (null === pendingQueue\n ? (current.firstBaseUpdate = firstPendingUpdate)\n : (pendingQueue.next = firstPendingUpdate),\n (current.lastBaseUpdate = lastPendingUpdate)));\n }\n if (null !== firstBaseUpdate) {\n var newState = queue.baseState;\n lastBaseUpdate = 0;\n current = firstPendingUpdate = lastPendingUpdate = null;\n pendingQueue = firstBaseUpdate;\n do {\n var updateLane = pendingQueue.lane & -536870913,\n isHiddenUpdate = updateLane !== pendingQueue.lane;\n if (\n isHiddenUpdate\n ? (workInProgressRootRenderLanes & updateLane) === updateLane\n : (renderLanes & updateLane) === updateLane\n ) {\n 0 !== updateLane &&\n updateLane === currentEntangledLane &&\n (didReadFromEntangledAsyncAction = !0);\n null !== current &&\n (current = current.next =\n {\n lane: 0,\n tag: pendingQueue.tag,\n payload: pendingQueue.payload,\n callback: null,\n next: null\n });\n a: {\n var workInProgress = workInProgress$jscomp$0,\n update = pendingQueue;\n updateLane = props;\n var instance = instance$jscomp$0;\n switch (update.tag) {\n case 1:\n workInProgress = update.payload;\n if (\"function\" === typeof workInProgress) {\n newState = workInProgress.call(instance, newState, updateLane);\n break a;\n }\n newState = workInProgress;\n break a;\n case 3:\n workInProgress.flags = (workInProgress.flags & -65537) | 128;\n case 0:\n workInProgress = update.payload;\n updateLane =\n \"function\" === typeof workInProgress\n ? workInProgress.call(instance, newState, updateLane)\n : workInProgress;\n if (null === updateLane || void 0 === updateLane) break a;\n newState = assign({}, newState, updateLane);\n break a;\n case 2:\n hasForceUpdate = !0;\n }\n }\n updateLane = pendingQueue.callback;\n null !== updateLane &&\n ((workInProgress$jscomp$0.flags |= 64),\n isHiddenUpdate && (workInProgress$jscomp$0.flags |= 8192),\n (isHiddenUpdate = queue.callbacks),\n null === isHiddenUpdate\n ? (queue.callbacks = [updateLane])\n : isHiddenUpdate.push(updateLane));\n } else\n (isHiddenUpdate = {\n lane: updateLane,\n tag: pendingQueue.tag,\n payload: pendingQueue.payload,\n callback: pendingQueue.callback,\n next: null\n }),\n null === current\n ? ((firstPendingUpdate = current = isHiddenUpdate),\n (lastPendingUpdate = newState))\n : (current = current.next = isHiddenUpdate),\n (lastBaseUpdate |= updateLane);\n pendingQueue = pendingQueue.next;\n if (null === pendingQueue)\n if (((pendingQueue = queue.shared.pending), null === pendingQueue))\n break;\n else\n (isHiddenUpdate = pendingQueue),\n (pendingQueue = isHiddenUpdate.next),\n (isHiddenUpdate.next = null),\n (queue.lastBaseUpdate = isHiddenUpdate),\n (queue.shared.pending = null);\n } while (1);\n null === current && (lastPendingUpdate = newState);\n queue.baseState = lastPendingUpdate;\n queue.firstBaseUpdate = firstPendingUpdate;\n queue.lastBaseUpdate = current;\n null === firstBaseUpdate && (queue.shared.lanes = 0);\n workInProgressRootSkippedLanes |= lastBaseUpdate;\n workInProgress$jscomp$0.lanes = lastBaseUpdate;\n workInProgress$jscomp$0.memoizedState = newState;\n }\n}\nfunction callCallback(callback, context) {\n if (\"function\" !== typeof callback)\n throw Error(formatProdErrorMessage(191, callback));\n callback.call(context);\n}\nfunction commitCallbacks(updateQueue, context) {\n var callbacks = updateQueue.callbacks;\n if (null !== callbacks)\n for (\n updateQueue.callbacks = null, updateQueue = 0;\n updateQueue < callbacks.length;\n updateQueue++\n )\n callCallback(callbacks[updateQueue], context);\n}\nvar currentTreeHiddenStackCursor = createCursor(null),\n prevEntangledRenderLanesCursor = createCursor(0);\nfunction pushHiddenContext(fiber, context) {\n fiber = entangledRenderLanes;\n push(prevEntangledRenderLanesCursor, fiber);\n push(currentTreeHiddenStackCursor, context);\n entangledRenderLanes = fiber | context.baseLanes;\n}\nfunction reuseHiddenContextOnStack() {\n push(prevEntangledRenderLanesCursor, entangledRenderLanes);\n push(currentTreeHiddenStackCursor, currentTreeHiddenStackCursor.current);\n}\nfunction popHiddenContext() {\n entangledRenderLanes = prevEntangledRenderLanesCursor.current;\n pop(currentTreeHiddenStackCursor);\n pop(prevEntangledRenderLanesCursor);\n}\nvar renderLanes = 0,\n currentlyRenderingFiber = null,\n currentHook = null,\n workInProgressHook = null,\n didScheduleRenderPhaseUpdate = !1,\n didScheduleRenderPhaseUpdateDuringThisPass = !1,\n shouldDoubleInvokeUserFnsInHooksDEV = !1,\n localIdCounter = 0,\n thenableIndexCounter$1 = 0,\n thenableState$1 = null,\n globalClientIdCounter = 0;\nfunction throwInvalidHookError() {\n throw Error(formatProdErrorMessage(321));\n}\nfunction areHookInputsEqual(nextDeps, prevDeps) {\n if (null === prevDeps) return !1;\n for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++)\n if (!objectIs(nextDeps[i], prevDeps[i])) return !1;\n return !0;\n}\nfunction renderWithHooks(\n current,\n workInProgress,\n Component,\n props,\n secondArg,\n nextRenderLanes\n) {\n renderLanes = nextRenderLanes;\n currentlyRenderingFiber = workInProgress;\n workInProgress.memoizedState = null;\n workInProgress.updateQueue = null;\n workInProgress.lanes = 0;\n ReactSharedInternals.H =\n null === current || null === current.memoizedState\n ? HooksDispatcherOnMount\n : HooksDispatcherOnUpdate;\n shouldDoubleInvokeUserFnsInHooksDEV = !1;\n nextRenderLanes = Component(props, secondArg);\n shouldDoubleInvokeUserFnsInHooksDEV = !1;\n didScheduleRenderPhaseUpdateDuringThisPass &&\n (nextRenderLanes = renderWithHooksAgain(\n workInProgress,\n Component,\n props,\n secondArg\n ));\n finishRenderingHooks(current);\n return nextRenderLanes;\n}\nfunction finishRenderingHooks(current) {\n ReactSharedInternals.H = ContextOnlyDispatcher;\n var didRenderTooFewHooks = null !== currentHook && null !== currentHook.next;\n renderLanes = 0;\n workInProgressHook = currentHook = currentlyRenderingFiber = null;\n didScheduleRenderPhaseUpdate = !1;\n thenableIndexCounter$1 = 0;\n thenableState$1 = null;\n if (didRenderTooFewHooks) throw Error(formatProdErrorMessage(300));\n null === current ||\n didReceiveUpdate ||\n ((current = current.dependencies),\n null !== current &&\n checkIfContextChanged(current) &&\n (didReceiveUpdate = !0));\n}\nfunction renderWithHooksAgain(workInProgress, Component, props, secondArg) {\n currentlyRenderingFiber = workInProgress;\n var numberOfReRenders = 0;\n do {\n didScheduleRenderPhaseUpdateDuringThisPass && (thenableState$1 = null);\n thenableIndexCounter$1 = 0;\n didScheduleRenderPhaseUpdateDuringThisPass = !1;\n if (25 <= numberOfReRenders) throw Error(formatProdErrorMessage(301));\n numberOfReRenders += 1;\n workInProgressHook = currentHook = null;\n if (null != workInProgress.updateQueue) {\n var children = workInProgress.updateQueue;\n children.lastEffect = null;\n children.events = null;\n children.stores = null;\n null != children.memoCache && (children.memoCache.index = 0);\n }\n ReactSharedInternals.H = HooksDispatcherOnRerender;\n children = Component(props, secondArg);\n } while (didScheduleRenderPhaseUpdateDuringThisPass);\n return children;\n}\nfunction TransitionAwareHostComponent() {\n var dispatcher = ReactSharedInternals.H,\n maybeThenable = dispatcher.useState()[0];\n maybeThenable =\n \"function\" === typeof maybeThenable.then\n ? useThenable(maybeThenable)\n : maybeThenable;\n dispatcher = dispatcher.useState()[0];\n (null !== currentHook ? currentHook.memoizedState : null) !== dispatcher &&\n (currentlyRenderingFiber.flags |= 1024);\n return maybeThenable;\n}\nfunction checkDidRenderIdHook() {\n var didRenderIdHook = 0 !== localIdCounter;\n localIdCounter = 0;\n return didRenderIdHook;\n}\nfunction bailoutHooks(current, workInProgress, lanes) {\n workInProgress.updateQueue = current.updateQueue;\n workInProgress.flags &= -2053;\n current.lanes &= ~lanes;\n}\nfunction resetHooksOnUnwind(workInProgress) {\n if (didScheduleRenderPhaseUpdate) {\n for (\n workInProgress = workInProgress.memoizedState;\n null !== workInProgress;\n\n ) {\n var queue = workInProgress.queue;\n null !== queue && (queue.pending = null);\n workInProgress = workInProgress.next;\n }\n didScheduleRenderPhaseUpdate = !1;\n }\n renderLanes = 0;\n workInProgressHook = currentHook = currentlyRenderingFiber = null;\n didScheduleRenderPhaseUpdateDuringThisPass = !1;\n thenableIndexCounter$1 = localIdCounter = 0;\n thenableState$1 = null;\n}\nfunction mountWorkInProgressHook() {\n var hook = {\n memoizedState: null,\n baseState: null,\n baseQueue: null,\n queue: null,\n next: null\n };\n null === workInProgressHook\n ? (currentlyRenderingFiber.memoizedState = workInProgressHook = hook)\n : (workInProgressHook = workInProgressHook.next = hook);\n return workInProgressHook;\n}\nfunction updateWorkInProgressHook() {\n if (null === currentHook) {\n var nextCurrentHook = currentlyRenderingFiber.alternate;\n nextCurrentHook =\n null !== nextCurrentHook ? nextCurrentHook.memoizedState : null;\n } else nextCurrentHook = currentHook.next;\n var nextWorkInProgressHook =\n null === workInProgressHook\n ? currentlyRenderingFiber.memoizedState\n : workInProgressHook.next;\n if (null !== nextWorkInProgressHook)\n (workInProgressHook = nextWorkInProgressHook),\n (currentHook = nextCurrentHook);\n else {\n if (null === nextCurrentHook) {\n if (null === currentlyRenderingFiber.alternate)\n throw Error(formatProdErrorMessage(467));\n throw Error(formatProdErrorMessage(310));\n }\n currentHook = nextCurrentHook;\n nextCurrentHook = {\n memoizedState: currentHook.memoizedState,\n baseState: currentHook.baseState,\n baseQueue: currentHook.baseQueue,\n queue: currentHook.queue,\n next: null\n };\n null === workInProgressHook\n ? (currentlyRenderingFiber.memoizedState = workInProgressHook =\n nextCurrentHook)\n : (workInProgressHook = workInProgressHook.next = nextCurrentHook);\n }\n return workInProgressHook;\n}\nfunction createFunctionComponentUpdateQueue() {\n return { lastEffect: null, events: null, stores: null, memoCache: null };\n}\nfunction useThenable(thenable) {\n var index = thenableIndexCounter$1;\n thenableIndexCounter$1 += 1;\n null === thenableState$1 && (thenableState$1 = []);\n thenable = trackUsedThenable(thenableState$1, thenable, index);\n index = currentlyRenderingFiber;\n null ===\n (null === workInProgressHook\n ? index.memoizedState\n : workInProgressHook.next) &&\n ((index = index.alternate),\n (ReactSharedInternals.H =\n null === index || null === index.memoizedState\n ? HooksDispatcherOnMount\n : HooksDispatcherOnUpdate));\n return thenable;\n}\nfunction use(usable) {\n if (null !== usable && \"object\" === typeof usable) {\n if (\"function\" === typeof usable.then) return useThenable(usable);\n if (usable.$$typeof === REACT_CONTEXT_TYPE) return readContext(usable);\n }\n throw Error(formatProdErrorMessage(438, String(usable)));\n}\nfunction useMemoCache(size) {\n var memoCache = null,\n updateQueue = currentlyRenderingFiber.updateQueue;\n null !== updateQueue && (memoCache = updateQueue.memoCache);\n if (null == memoCache) {\n var current = currentlyRenderingFiber.alternate;\n null !== current &&\n ((current = current.updateQueue),\n null !== current &&\n ((current = current.memoCache),\n null != current &&\n (memoCache = {\n data: current.data.map(function (array) {\n return array.slice();\n }),\n index: 0\n })));\n }\n null == memoCache && (memoCache = { data: [], index: 0 });\n null === updateQueue &&\n ((updateQueue = createFunctionComponentUpdateQueue()),\n (currentlyRenderingFiber.updateQueue = updateQueue));\n updateQueue.memoCache = memoCache;\n updateQueue = memoCache.data[memoCache.index];\n if (void 0 === updateQueue)\n for (\n updateQueue = memoCache.data[memoCache.index] = Array(size), current = 0;\n current < size;\n current++\n )\n updateQueue[current] = REACT_MEMO_CACHE_SENTINEL;\n memoCache.index++;\n return updateQueue;\n}\nfunction basicStateReducer(state, action) {\n return \"function\" === typeof action ? action(state) : action;\n}\nfunction updateReducer(reducer) {\n var hook = updateWorkInProgressHook();\n return updateReducerImpl(hook, currentHook, reducer);\n}\nfunction updateReducerImpl(hook, current, reducer) {\n var queue = hook.queue;\n if (null === queue) throw Error(formatProdErrorMessage(311));\n queue.lastRenderedReducer = reducer;\n var baseQueue = hook.baseQueue,\n pendingQueue = queue.pending;\n if (null !== pendingQueue) {\n if (null !== baseQueue) {\n var baseFirst = baseQueue.next;\n baseQueue.next = pendingQueue.next;\n pendingQueue.next = baseFirst;\n }\n current.baseQueue = baseQueue = pendingQueue;\n queue.pending = null;\n }\n pendingQueue = hook.baseState;\n if (null === baseQueue) hook.memoizedState = pendingQueue;\n else {\n current = baseQueue.next;\n var newBaseQueueFirst = (baseFirst = null),\n newBaseQueueLast = null,\n update = current,\n didReadFromEntangledAsyncAction$32 = !1;\n do {\n var updateLane = update.lane & -536870913;\n if (\n updateLane !== update.lane\n ? (workInProgressRootRenderLanes & updateLane) === updateLane\n : (renderLanes & updateLane) === updateLane\n ) {\n var revertLane = update.revertLane;\n if (0 === revertLane)\n null !== newBaseQueueLast &&\n (newBaseQueueLast = newBaseQueueLast.next =\n {\n lane: 0,\n revertLane: 0,\n action: update.action,\n hasEagerState: update.hasEagerState,\n eagerState: update.eagerState,\n next: null\n }),\n updateLane === currentEntangledLane &&\n (didReadFromEntangledAsyncAction$32 = !0);\n else if ((renderLanes & revertLane) === revertLane) {\n update = update.next;\n revertLane === currentEntangledLane &&\n (didReadFromEntangledAsyncAction$32 = !0);\n continue;\n } else\n (updateLane = {\n lane: 0,\n revertLane: update.revertLane,\n action: update.action,\n hasEagerState: update.hasEagerState,\n eagerState: update.eagerState,\n next: null\n }),\n null === newBaseQueueLast\n ? ((newBaseQueueFirst = newBaseQueueLast = updateLane),\n (baseFirst = pendingQueue))\n : (newBaseQueueLast = newBaseQueueLast.next = updateLane),\n (currentlyRenderingFiber.lanes |= revertLane),\n (workInProgressRootSkippedLanes |= revertLane);\n updateLane = update.action;\n shouldDoubleInvokeUserFnsInHooksDEV &&\n reducer(pendingQueue, updateLane);\n pendingQueue = update.hasEagerState\n ? update.eagerState\n : reducer(pendingQueue, updateLane);\n } else\n (revertLane = {\n lane: updateLane,\n revertLane: update.revertLane,\n action: update.action,\n hasEagerState: update.hasEagerState,\n eagerState: update.eagerState,\n next: null\n }),\n null === newBaseQueueLast\n ? ((newBaseQueueFirst = newBaseQueueLast = revertLane),\n (baseFirst = pendingQueue))\n : (newBaseQueueLast = newBaseQueueLast.next = revertLane),\n (currentlyRenderingFiber.lanes |= updateLane),\n (workInProgressRootSkippedLanes |= updateLane);\n update = update.next;\n } while (null !== update && update !== current);\n null === newBaseQueueLast\n ? (baseFirst = pendingQueue)\n : (newBaseQueueLast.next = newBaseQueueFirst);\n if (\n !objectIs(pendingQueue, hook.memoizedState) &&\n ((didReceiveUpdate = !0),\n didReadFromEntangledAsyncAction$32 &&\n ((reducer = currentEntangledActionThenable), null !== reducer))\n )\n throw reducer;\n hook.memoizedState = pendingQueue;\n hook.baseState = baseFirst;\n hook.baseQueue = newBaseQueueLast;\n queue.lastRenderedState = pendingQueue;\n }\n null === baseQueue && (queue.lanes = 0);\n return [hook.memoizedState, queue.dispatch];\n}\nfunction rerenderReducer(reducer) {\n var hook = updateWorkInProgressHook(),\n queue = hook.queue;\n if (null === queue) throw Error(formatProdErrorMessage(311));\n queue.lastRenderedReducer = reducer;\n var dispatch = queue.dispatch,\n lastRenderPhaseUpdate = queue.pending,\n newState = hook.memoizedState;\n if (null !== lastRenderPhaseUpdate) {\n queue.pending = null;\n var update = (lastRenderPhaseUpdate = lastRenderPhaseUpdate.next);\n do (newState = reducer(newState, update.action)), (update = update.next);\n while (update !== lastRenderPhaseUpdate);\n objectIs(newState, hook.memoizedState) || (didReceiveUpdate = !0);\n hook.memoizedState = newState;\n null === hook.baseQueue && (hook.baseState = newState);\n queue.lastRenderedState = newState;\n }\n return [newState, dispatch];\n}\nfunction updateSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) {\n var fiber = currentlyRenderingFiber,\n hook = updateWorkInProgressHook(),\n isHydrating$jscomp$0 = isHydrating;\n if (isHydrating$jscomp$0) {\n if (void 0 === getServerSnapshot) throw Error(formatProdErrorMessage(407));\n getServerSnapshot = getServerSnapshot();\n } else getServerSnapshot = getSnapshot();\n var snapshotChanged = !objectIs(\n (currentHook || hook).memoizedState,\n getServerSnapshot\n );\n snapshotChanged &&\n ((hook.memoizedState = getServerSnapshot), (didReceiveUpdate = !0));\n hook = hook.queue;\n var create = subscribeToStore.bind(null, fiber, hook, subscribe);\n updateEffectImpl(2048, 8, create, [subscribe]);\n if (\n hook.getSnapshot !== getSnapshot ||\n snapshotChanged ||\n (null !== workInProgressHook && workInProgressHook.memoizedState.tag & 1)\n ) {\n fiber.flags |= 2048;\n pushSimpleEffect(\n 9,\n createEffectInstance(),\n updateStoreInstance.bind(\n null,\n fiber,\n hook,\n getServerSnapshot,\n getSnapshot\n ),\n null\n );\n if (null === workInProgressRoot) throw Error(formatProdErrorMessage(349));\n isHydrating$jscomp$0 ||\n 0 !== (renderLanes & 124) ||\n pushStoreConsistencyCheck(fiber, getSnapshot, getServerSnapshot);\n }\n return getServerSnapshot;\n}\nfunction pushStoreConsistencyCheck(fiber, getSnapshot, renderedSnapshot) {\n fiber.flags |= 16384;\n fiber = { getSnapshot: getSnapshot, value: renderedSnapshot };\n getSnapshot = currentlyRenderingFiber.updateQueue;\n null === getSnapshot\n ? ((getSnapshot = createFunctionComponentUpdateQueue()),\n (currentlyRenderingFiber.updateQueue = getSnapshot),\n (getSnapshot.stores = [fiber]))\n : ((renderedSnapshot = getSnapshot.stores),\n null === renderedSnapshot\n ? (getSnapshot.stores = [fiber])\n : renderedSnapshot.push(fiber));\n}\nfunction updateStoreInstance(fiber, inst, nextSnapshot, getSnapshot) {\n inst.value = nextSnapshot;\n inst.getSnapshot = getSnapshot;\n checkIfSnapshotChanged(inst) && forceStoreRerender(fiber);\n}\nfunction subscribeToStore(fiber, inst, subscribe) {\n return subscribe(function () {\n checkIfSnapshotChanged(inst) && forceStoreRerender(fiber);\n });\n}\nfunction checkIfSnapshotChanged(inst) {\n var latestGetSnapshot = inst.getSnapshot;\n inst = inst.value;\n try {\n var nextValue = latestGetSnapshot();\n return !objectIs(inst, nextValue);\n } catch (error) {\n return !0;\n }\n}\nfunction forceStoreRerender(fiber) {\n var root = enqueueConcurrentRenderForLane(fiber, 2);\n null !== root && scheduleUpdateOnFiber(root, fiber, 2);\n}\nfunction mountStateImpl(initialState) {\n var hook = mountWorkInProgressHook();\n if (\"function\" === typeof initialState) {\n var initialStateInitializer = initialState;\n initialState = initialStateInitializer();\n if (shouldDoubleInvokeUserFnsInHooksDEV) {\n setIsStrictModeForDevtools(!0);\n try {\n initialStateInitializer();\n } finally {\n setIsStrictModeForDevtools(!1);\n }\n }\n }\n hook.memoizedState = hook.baseState = initialState;\n hook.queue = {\n pending: null,\n lanes: 0,\n dispatch: null,\n lastRenderedReducer: basicStateReducer,\n lastRenderedState: initialState\n };\n return hook;\n}\nfunction updateOptimisticImpl(hook, current, passthrough, reducer) {\n hook.baseState = passthrough;\n return updateReducerImpl(\n hook,\n currentHook,\n \"function\" === typeof reducer ? reducer : basicStateReducer\n );\n}\nfunction dispatchActionState(\n fiber,\n actionQueue,\n setPendingState,\n setState,\n payload\n) {\n if (isRenderPhaseUpdate(fiber)) throw Error(formatProdErrorMessage(485));\n fiber = actionQueue.action;\n if (null !== fiber) {\n var actionNode = {\n payload: payload,\n action: fiber,\n next: null,\n isTransition: !0,\n status: \"pending\",\n value: null,\n reason: null,\n listeners: [],\n then: function (listener) {\n actionNode.listeners.push(listener);\n }\n };\n null !== ReactSharedInternals.T\n ? setPendingState(!0)\n : (actionNode.isTransition = !1);\n setState(actionNode);\n setPendingState = actionQueue.pending;\n null === setPendingState\n ? ((actionNode.next = actionQueue.pending = actionNode),\n runActionStateAction(actionQueue, actionNode))\n : ((actionNode.next = setPendingState.next),\n (actionQueue.pending = setPendingState.next = actionNode));\n }\n}\nfunction runActionStateAction(actionQueue, node) {\n var action = node.action,\n payload = node.payload,\n prevState = actionQueue.state;\n if (node.isTransition) {\n var prevTransition = ReactSharedInternals.T,\n currentTransition = {};\n ReactSharedInternals.T = currentTransition;\n try {\n var returnValue = action(prevState, payload),\n onStartTransitionFinish = ReactSharedInternals.S;\n null !== onStartTransitionFinish &&\n onStartTransitionFinish(currentTransition, returnValue);\n handleActionReturnValue(actionQueue, node, returnValue);\n } catch (error) {\n onActionError(actionQueue, node, error);\n } finally {\n ReactSharedInternals.T = prevTransition;\n }\n } else\n try {\n (prevTransition = action(prevState, payload)),\n handleActionReturnValue(actionQueue, node, prevTransition);\n } catch (error$38) {\n onActionError(actionQueue, node, error$38);\n }\n}\nfunction handleActionReturnValue(actionQueue, node, returnValue) {\n null !== returnValue &&\n \"object\" === typeof returnValue &&\n \"function\" === typeof returnValue.then\n ? returnValue.then(\n function (nextState) {\n onActionSuccess(actionQueue, node, nextState);\n },\n function (error) {\n return onActionError(actionQueue, node, error);\n }\n )\n : onActionSuccess(actionQueue, node, returnValue);\n}\nfunction onActionSuccess(actionQueue, actionNode, nextState) {\n actionNode.status = \"fulfilled\";\n actionNode.value = nextState;\n notifyActionListeners(actionNode);\n actionQueue.state = nextState;\n actionNode = actionQueue.pending;\n null !== actionNode &&\n ((nextState = actionNode.next),\n nextState === actionNode\n ? (actionQueue.pending = null)\n : ((nextState = nextState.next),\n (actionNode.next = nextState),\n runActionStateAction(actionQueue, nextState)));\n}\nfunction onActionError(actionQueue, actionNode, error) {\n var last = actionQueue.pending;\n actionQueue.pending = null;\n if (null !== last) {\n last = last.next;\n do\n (actionNode.status = \"rejected\"),\n (actionNode.reason = error),\n notifyActionListeners(actionNode),\n (actionNode = actionNode.next);\n while (actionNode !== last);\n }\n actionQueue.action = null;\n}\nfunction notifyActionListeners(actionNode) {\n actionNode = actionNode.listeners;\n for (var i = 0; i < actionNode.length; i++) (0, actionNode[i])();\n}\nfunction actionStateReducer(oldState, newState) {\n return newState;\n}\nfunction mountActionState(action, initialStateProp) {\n if (isHydrating) {\n var ssrFormState = workInProgressRoot.formState;\n if (null !== ssrFormState) {\n a: {\n var JSCompiler_inline_result = currentlyRenderingFiber;\n if (isHydrating) {\n if (nextHydratableInstance) {\n b: {\n var JSCompiler_inline_result$jscomp$0 = nextHydratableInstance;\n for (\n var inRootOrSingleton = rootOrSingletonContext;\n 8 !== JSCompiler_inline_result$jscomp$0.nodeType;\n\n ) {\n if (!inRootOrSingleton) {\n JSCompiler_inline_result$jscomp$0 = null;\n break b;\n }\n JSCompiler_inline_result$jscomp$0 = getNextHydratable(\n JSCompiler_inline_result$jscomp$0.nextSibling\n );\n if (null === JSCompiler_inline_result$jscomp$0) {\n JSCompiler_inline_result$jscomp$0 = null;\n break b;\n }\n }\n inRootOrSingleton = JSCompiler_inline_result$jscomp$0.data;\n JSCompiler_inline_result$jscomp$0 =\n \"F!\" === inRootOrSingleton || \"F\" === inRootOrSingleton\n ? JSCompiler_inline_result$jscomp$0\n : null;\n }\n if (JSCompiler_inline_result$jscomp$0) {\n nextHydratableInstance = getNextHydratable(\n JSCompiler_inline_result$jscomp$0.nextSibling\n );\n JSCompiler_inline_result =\n \"F!\" === JSCompiler_inline_result$jscomp$0.data;\n break a;\n }\n }\n throwOnHydrationMismatch(JSCompiler_inline_result);\n }\n JSCompiler_inline_result = !1;\n }\n JSCompiler_inline_result && (initialStateProp = ssrFormState[0]);\n }\n }\n ssrFormState = mountWorkInProgressHook();\n ssrFormState.memoizedState = ssrFormState.baseState = initialStateProp;\n JSCompiler_inline_result = {\n pending: null,\n lanes: 0,\n dispatch: null,\n lastRenderedReducer: actionStateReducer,\n lastRenderedState: initialStateProp\n };\n ssrFormState.queue = JSCompiler_inline_result;\n ssrFormState = dispatchSetState.bind(\n null,\n currentlyRenderingFiber,\n JSCompiler_inline_result\n );\n JSCompiler_inline_result.dispatch = ssrFormState;\n JSCompiler_inline_result = mountStateImpl(!1);\n inRootOrSingleton = dispatchOptimisticSetState.bind(\n null,\n currentlyRenderingFiber,\n !1,\n JSCompiler_inline_result.queue\n );\n JSCompiler_inline_result = mountWorkInProgressHook();\n JSCompiler_inline_result$jscomp$0 = {\n state: initialStateProp,\n dispatch: null,\n action: action,\n pending: null\n };\n JSCompiler_inline_result.queue = JSCompiler_inline_result$jscomp$0;\n ssrFormState = dispatchActionState.bind(\n null,\n currentlyRenderingFiber,\n JSCompiler_inline_result$jscomp$0,\n inRootOrSingleton,\n ssrFormState\n );\n JSCompiler_inline_result$jscomp$0.dispatch = ssrFormState;\n JSCompiler_inline_result.memoizedState = action;\n return [initialStateProp, ssrFormState, !1];\n}\nfunction updateActionState(action) {\n var stateHook = updateWorkInProgressHook();\n return updateActionStateImpl(stateHook, currentHook, action);\n}\nfunction updateActionStateImpl(stateHook, currentStateHook, action) {\n currentStateHook = updateReducerImpl(\n stateHook,\n currentStateHook,\n actionStateReducer\n )[0];\n stateHook = updateReducer(basicStateReducer)[0];\n if (\n \"object\" === typeof currentStateHook &&\n null !== currentStateHook &&\n \"function\" === typeof currentStateHook.then\n )\n try {\n var state = useThenable(currentStateHook);\n } catch (x) {\n if (x === SuspenseException) throw SuspenseActionException;\n throw x;\n }\n else state = currentStateHook;\n currentStateHook = updateWorkInProgressHook();\n var actionQueue = currentStateHook.queue,\n dispatch = actionQueue.dispatch;\n action !== currentStateHook.memoizedState &&\n ((currentlyRenderingFiber.flags |= 2048),\n pushSimpleEffect(\n 9,\n createEffectInstance(),\n actionStateActionEffect.bind(null, actionQueue, action),\n null\n ));\n return [state, dispatch, stateHook];\n}\nfunction actionStateActionEffect(actionQueue, action) {\n actionQueue.action = action;\n}\nfunction rerenderActionState(action) {\n var stateHook = updateWorkInProgressHook(),\n currentStateHook = currentHook;\n if (null !== currentStateHook)\n return updateActionStateImpl(stateHook, currentStateHook, action);\n updateWorkInProgressHook();\n stateHook = stateHook.memoizedState;\n currentStateHook = updateWorkInProgressHook();\n var dispatch = currentStateHook.queue.dispatch;\n currentStateHook.memoizedState = action;\n return [stateHook, dispatch, !1];\n}\nfunction pushSimpleEffect(tag, inst, create, createDeps) {\n tag = { tag: tag, create: create, deps: createDeps, inst: inst, next: null };\n inst = currentlyRenderingFiber.updateQueue;\n null === inst &&\n ((inst = createFunctionComponentUpdateQueue()),\n (currentlyRenderingFiber.updateQueue = inst));\n create = inst.lastEffect;\n null === create\n ? (inst.lastEffect = tag.next = tag)\n : ((createDeps = create.next),\n (create.next = tag),\n (tag.next = createDeps),\n (inst.lastEffect = tag));\n return tag;\n}\nfunction createEffectInstance() {\n return { destroy: void 0, resource: void 0 };\n}\nfunction updateRef() {\n return updateWorkInProgressHook().memoizedState;\n}\nfunction mountEffectImpl(fiberFlags, hookFlags, create, createDeps) {\n var hook = mountWorkInProgressHook();\n createDeps = void 0 === createDeps ? null : createDeps;\n currentlyRenderingFiber.flags |= fiberFlags;\n hook.memoizedState = pushSimpleEffect(\n 1 | hookFlags,\n createEffectInstance(),\n create,\n createDeps\n );\n}\nfunction updateEffectImpl(fiberFlags, hookFlags, create, deps) {\n var hook = updateWorkInProgressHook();\n deps = void 0 === deps ? null : deps;\n var inst = hook.memoizedState.inst;\n null !== currentHook &&\n null !== deps &&\n areHookInputsEqual(deps, currentHook.memoizedState.deps)\n ? (hook.memoizedState = pushSimpleEffect(hookFlags, inst, create, deps))\n : ((currentlyRenderingFiber.flags |= fiberFlags),\n (hook.memoizedState = pushSimpleEffect(\n 1 | hookFlags,\n inst,\n create,\n deps\n )));\n}\nfunction mountEffect(create, createDeps) {\n mountEffectImpl(8390656, 8, create, createDeps);\n}\nfunction updateEffect(create, createDeps) {\n updateEffectImpl(2048, 8, create, createDeps);\n}\nfunction updateInsertionEffect(create, deps) {\n return updateEffectImpl(4, 2, create, deps);\n}\nfunction updateLayoutEffect(create, deps) {\n return updateEffectImpl(4, 4, create, deps);\n}\nfunction imperativeHandleEffect(create, ref) {\n if (\"function\" === typeof ref) {\n create = create();\n var refCleanup = ref(create);\n return function () {\n \"function\" === typeof refCleanup ? refCleanup() : ref(null);\n };\n }\n if (null !== ref && void 0 !== ref)\n return (\n (create = create()),\n (ref.current = create),\n function () {\n ref.current = null;\n }\n );\n}\nfunction updateImperativeHandle(ref, create, deps) {\n deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null;\n updateEffectImpl(4, 4, imperativeHandleEffect.bind(null, create, ref), deps);\n}\nfunction mountDebugValue() {}\nfunction updateCallback(callback, deps) {\n var hook = updateWorkInProgressHook();\n deps = void 0 === deps ? null : deps;\n var prevState = hook.memoizedState;\n if (null !== deps && areHookInputsEqual(deps, prevState[1]))\n return prevState[0];\n hook.memoizedState = [callback, deps];\n return callback;\n}\nfunction updateMemo(nextCreate, deps) {\n var hook = updateWorkInProgressHook();\n deps = void 0 === deps ? null : deps;\n var prevState = hook.memoizedState;\n if (null !== deps && areHookInputsEqual(deps, prevState[1]))\n return prevState[0];\n prevState = nextCreate();\n if (shouldDoubleInvokeUserFnsInHooksDEV) {\n setIsStrictModeForDevtools(!0);\n try {\n nextCreate();\n } finally {\n setIsStrictModeForDevtools(!1);\n }\n }\n hook.memoizedState = [prevState, deps];\n return prevState;\n}\nfunction mountDeferredValueImpl(hook, value, initialValue) {\n if (void 0 === initialValue || 0 !== (renderLanes & 1073741824))\n return (hook.memoizedState = value);\n hook.memoizedState = initialValue;\n hook = requestDeferredLane();\n currentlyRenderingFiber.lanes |= hook;\n workInProgressRootSkippedLanes |= hook;\n return initialValue;\n}\nfunction updateDeferredValueImpl(hook, prevValue, value, initialValue) {\n if (objectIs(value, prevValue)) return value;\n if (null !== currentTreeHiddenStackCursor.current)\n return (\n (hook = mountDeferredValueImpl(hook, value, initialValue)),\n objectIs(hook, prevValue) || (didReceiveUpdate = !0),\n hook\n );\n if (0 === (renderLanes & 42))\n return (didReceiveUpdate = !0), (hook.memoizedState = value);\n hook = requestDeferredLane();\n currentlyRenderingFiber.lanes |= hook;\n workInProgressRootSkippedLanes |= hook;\n return prevValue;\n}\nfunction startTransition(fiber, queue, pendingState, finishedState, callback) {\n var previousPriority = ReactDOMSharedInternals.p;\n ReactDOMSharedInternals.p =\n 0 !== previousPriority && 8 > previousPriority ? previousPriority : 8;\n var prevTransition = ReactSharedInternals.T,\n currentTransition = {};\n ReactSharedInternals.T = currentTransition;\n dispatchOptimisticSetState(fiber, !1, queue, pendingState);\n try {\n var returnValue = callback(),\n onStartTransitionFinish = ReactSharedInternals.S;\n null !== onStartTransitionFinish &&\n onStartTransitionFinish(currentTransition, returnValue);\n if (\n null !== returnValue &&\n \"object\" === typeof returnValue &&\n \"function\" === typeof returnValue.then\n ) {\n var thenableForFinishedState = chainThenableValue(\n returnValue,\n finishedState\n );\n dispatchSetStateInternal(\n fiber,\n queue,\n thenableForFinishedState,\n requestUpdateLane(fiber)\n );\n } else\n dispatchSetStateInternal(\n fiber,\n queue,\n finishedState,\n requestUpdateLane(fiber)\n );\n } catch (error) {\n dispatchSetStateInternal(\n fiber,\n queue,\n { then: function () {}, status: \"rejected\", reason: error },\n requestUpdateLane()\n );\n } finally {\n (ReactDOMSharedInternals.p = previousPriority),\n (ReactSharedInternals.T = prevTransition);\n }\n}\nfunction noop$2() {}\nfunction startHostTransition(formFiber, pendingState, action, formData) {\n if (5 !== formFiber.tag) throw Error(formatProdErrorMessage(476));\n var queue = ensureFormComponentIsStateful(formFiber).queue;\n startTransition(\n formFiber,\n queue,\n pendingState,\n sharedNotPendingObject,\n null === action\n ? noop$2\n : function () {\n requestFormReset$1(formFiber);\n return action(formData);\n }\n );\n}\nfunction ensureFormComponentIsStateful(formFiber) {\n var existingStateHook = formFiber.memoizedState;\n if (null !== existingStateHook) return existingStateHook;\n existingStateHook = {\n memoizedState: sharedNotPendingObject,\n baseState: sharedNotPendingObject,\n baseQueue: null,\n queue: {\n pending: null,\n lanes: 0,\n dispatch: null,\n lastRenderedReducer: basicStateReducer,\n lastRenderedState: sharedNotPendingObject\n },\n next: null\n };\n var initialResetState = {};\n existingStateHook.next = {\n memoizedState: initialResetState,\n baseState: initialResetState,\n baseQueue: null,\n queue: {\n pending: null,\n lanes: 0,\n dispatch: null,\n lastRenderedReducer: basicStateReducer,\n lastRenderedState: initialResetState\n },\n next: null\n };\n formFiber.memoizedState = existingStateHook;\n formFiber = formFiber.alternate;\n null !== formFiber && (formFiber.memoizedState = existingStateHook);\n return existingStateHook;\n}\nfunction requestFormReset$1(formFiber) {\n var resetStateQueue = ensureFormComponentIsStateful(formFiber).next.queue;\n dispatchSetStateInternal(formFiber, resetStateQueue, {}, requestUpdateLane());\n}\nfunction useHostTransitionStatus() {\n return readContext(HostTransitionContext);\n}\nfunction updateId() {\n return updateWorkInProgressHook().memoizedState;\n}\nfunction updateRefresh() {\n return updateWorkInProgressHook().memoizedState;\n}\nfunction refreshCache(fiber) {\n for (var provider = fiber.return; null !== provider; ) {\n switch (provider.tag) {\n case 24:\n case 3:\n var lane = requestUpdateLane();\n fiber = createUpdate(lane);\n var root$41 = enqueueUpdate(provider, fiber, lane);\n null !== root$41 &&\n (scheduleUpdateOnFiber(root$41, provider, lane),\n entangleTransitions(root$41, provider, lane));\n provider = { cache: createCache() };\n fiber.payload = provider;\n return;\n }\n provider = provider.return;\n }\n}\nfunction dispatchReducerAction(fiber, queue, action) {\n var lane = requestUpdateLane();\n action = {\n lane: lane,\n revertLane: 0,\n action: action,\n hasEagerState: !1,\n eagerState: null,\n next: null\n };\n isRenderPhaseUpdate(fiber)\n ? enqueueRenderPhaseUpdate(queue, action)\n : ((action = enqueueConcurrentHookUpdate(fiber, queue, action, lane)),\n null !== action &&\n (scheduleUpdateOnFiber(action, fiber, lane),\n entangleTransitionUpdate(action, queue, lane)));\n}\nfunction dispatchSetState(fiber, queue, action) {\n var lane = requestUpdateLane();\n dispatchSetStateInternal(fiber, queue, action, lane);\n}\nfunction dispatchSetStateInternal(fiber, queue, action, lane) {\n var update = {\n lane: lane,\n revertLane: 0,\n action: action,\n hasEagerState: !1,\n eagerState: null,\n next: null\n };\n if (isRenderPhaseUpdate(fiber)) enqueueRenderPhaseUpdate(queue, update);\n else {\n var alternate = fiber.alternate;\n if (\n 0 === fiber.lanes &&\n (null === alternate || 0 === alternate.lanes) &&\n ((alternate = queue.lastRenderedReducer), null !== alternate)\n )\n try {\n var currentState = queue.lastRenderedState,\n eagerState = alternate(currentState, action);\n update.hasEagerState = !0;\n update.eagerState = eagerState;\n if (objectIs(eagerState, currentState))\n return (\n enqueueUpdate$1(fiber, queue, update, 0),\n null === workInProgressRoot && finishQueueingConcurrentUpdates(),\n !1\n );\n } catch (error) {\n } finally {\n }\n action = enqueueConcurrentHookUpdate(fiber, queue, update, lane);\n if (null !== action)\n return (\n scheduleUpdateOnFiber(action, fiber, lane),\n entangleTransitionUpdate(action, queue, lane),\n !0\n );\n }\n return !1;\n}\nfunction dispatchOptimisticSetState(fiber, throwIfDuringRender, queue, action) {\n action = {\n lane: 2,\n revertLane: requestTransitionLane(),\n action: action,\n hasEagerState: !1,\n eagerState: null,\n next: null\n };\n if (isRenderPhaseUpdate(fiber)) {\n if (throwIfDuringRender) throw Error(formatProdErrorMessage(479));\n } else\n (throwIfDuringRender = enqueueConcurrentHookUpdate(\n fiber,\n queue,\n action,\n 2\n )),\n null !== throwIfDuringRender &&\n scheduleUpdateOnFiber(throwIfDuringRender, fiber, 2);\n}\nfunction isRenderPhaseUpdate(fiber) {\n var alternate = fiber.alternate;\n return (\n fiber === currentlyRenderingFiber ||\n (null !== alternate && alternate === currentlyRenderingFiber)\n );\n}\nfunction enqueueRenderPhaseUpdate(queue, update) {\n didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate =\n !0;\n var pending = queue.pending;\n null === pending\n ? (update.next = update)\n : ((update.next = pending.next), (pending.next = update));\n queue.pending = update;\n}\nfunction entangleTransitionUpdate(root, queue, lane) {\n if (0 !== (lane & 4194048)) {\n var queueLanes = queue.lanes;\n queueLanes &= root.pendingLanes;\n lane |= queueLanes;\n queue.lanes = lane;\n markRootEntangled(root, lane);\n }\n}\nvar ContextOnlyDispatcher = {\n readContext: readContext,\n use: use,\n useCallback: throwInvalidHookError,\n useContext: throwInvalidHookError,\n useEffect: throwInvalidHookError,\n useImperativeHandle: throwInvalidHookError,\n useLayoutEffect: throwInvalidHookError,\n useInsertionEffect: throwInvalidHookError,\n useMemo: throwInvalidHookError,\n useReducer: throwInvalidHookError,\n useRef: throwInvalidHookError,\n useState: throwInvalidHookError,\n useDebugValue: throwInvalidHookError,\n useDeferredValue: throwInvalidHookError,\n useTransition: throwInvalidHookError,\n useSyncExternalStore: throwInvalidHookError,\n useId: throwInvalidHookError,\n useHostTransitionStatus: throwInvalidHookError,\n useFormState: throwInvalidHookError,\n useActionState: throwInvalidHookError,\n useOptimistic: throwInvalidHookError,\n useMemoCache: throwInvalidHookError,\n useCacheRefresh: throwInvalidHookError\n },\n HooksDispatcherOnMount = {\n readContext: readContext,\n use: use,\n useCallback: function (callback, deps) {\n mountWorkInProgressHook().memoizedState = [\n callback,\n void 0 === deps ? null : deps\n ];\n return callback;\n },\n useContext: readContext,\n useEffect: mountEffect,\n useImperativeHandle: function (ref, create, deps) {\n deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null;\n mountEffectImpl(\n 4194308,\n 4,\n imperativeHandleEffect.bind(null, create, ref),\n deps\n );\n },\n useLayoutEffect: function (create, deps) {\n return mountEffectImpl(4194308, 4, create, deps);\n },\n useInsertionEffect: function (create, deps) {\n mountEffectImpl(4, 2, create, deps);\n },\n useMemo: function (nextCreate, deps) {\n var hook = mountWorkInProgressHook();\n deps = void 0 === deps ? null : deps;\n var nextValue = nextCreate();\n if (shouldDoubleInvokeUserFnsInHooksDEV) {\n setIsStrictModeForDevtools(!0);\n try {\n nextCreate();\n } finally {\n setIsStrictModeForDevtools(!1);\n }\n }\n hook.memoizedState = [nextValue, deps];\n return nextValue;\n },\n useReducer: function (reducer, initialArg, init) {\n var hook = mountWorkInProgressHook();\n if (void 0 !== init) {\n var initialState = init(initialArg);\n if (shouldDoubleInvokeUserFnsInHooksDEV) {\n setIsStrictModeForDevtools(!0);\n try {\n init(initialArg);\n } finally {\n setIsStrictModeForDevtools(!1);\n }\n }\n } else initialState = initialArg;\n hook.memoizedState = hook.baseState = initialState;\n reducer = {\n pending: null,\n lanes: 0,\n dispatch: null,\n lastRenderedReducer: reducer,\n lastRenderedState: initialState\n };\n hook.queue = reducer;\n reducer = reducer.dispatch = dispatchReducerAction.bind(\n null,\n currentlyRenderingFiber,\n reducer\n );\n return [hook.memoizedState, reducer];\n },\n useRef: function (initialValue) {\n var hook = mountWorkInProgressHook();\n initialValue = { current: initialValue };\n return (hook.memoizedState = initialValue);\n },\n useState: function (initialState) {\n initialState = mountStateImpl(initialState);\n var queue = initialState.queue,\n dispatch = dispatchSetState.bind(null, currentlyRenderingFiber, queue);\n queue.dispatch = dispatch;\n return [initialState.memoizedState, dispatch];\n },\n useDebugValue: mountDebugValue,\n useDeferredValue: function (value, initialValue) {\n var hook = mountWorkInProgressHook();\n return mountDeferredValueImpl(hook, value, initialValue);\n },\n useTransition: function () {\n var stateHook = mountStateImpl(!1);\n stateHook = startTransition.bind(\n null,\n currentlyRenderingFiber,\n stateHook.queue,\n !0,\n !1\n );\n mountWorkInProgressHook().memoizedState = stateHook;\n return [!1, stateHook];\n },\n useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {\n var fiber = currentlyRenderingFiber,\n hook = mountWorkInProgressHook();\n if (isHydrating) {\n if (void 0 === getServerSnapshot)\n throw Error(formatProdErrorMessage(407));\n getServerSnapshot = getServerSnapshot();\n } else {\n getServerSnapshot = getSnapshot();\n if (null === workInProgressRoot)\n throw Error(formatProdErrorMessage(349));\n 0 !== (workInProgressRootRenderLanes & 124) ||\n pushStoreConsistencyCheck(fiber, getSnapshot, getServerSnapshot);\n }\n hook.memoizedState = getServerSnapshot;\n var inst = { value: getServerSnapshot, getSnapshot: getSnapshot };\n hook.queue = inst;\n mountEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [\n subscribe\n ]);\n fiber.flags |= 2048;\n pushSimpleEffect(\n 9,\n createEffectInstance(),\n updateStoreInstance.bind(\n null,\n fiber,\n inst,\n getServerSnapshot,\n getSnapshot\n ),\n null\n );\n return getServerSnapshot;\n },\n useId: function () {\n var hook = mountWorkInProgressHook(),\n identifierPrefix = workInProgressRoot.identifierPrefix;\n if (isHydrating) {\n var JSCompiler_inline_result = treeContextOverflow;\n var idWithLeadingBit = treeContextId;\n JSCompiler_inline_result =\n (\n idWithLeadingBit & ~(1 << (32 - clz32(idWithLeadingBit) - 1))\n ).toString(32) + JSCompiler_inline_result;\n identifierPrefix =\n \"\\u00ab\" + identifierPrefix + \"R\" + JSCompiler_inline_result;\n JSCompiler_inline_result = localIdCounter++;\n 0 < JSCompiler_inline_result &&\n (identifierPrefix += \"H\" + JSCompiler_inline_result.toString(32));\n identifierPrefix += \"\\u00bb\";\n } else\n (JSCompiler_inline_result = globalClientIdCounter++),\n (identifierPrefix =\n \"\\u00ab\" +\n identifierPrefix +\n \"r\" +\n JSCompiler_inline_result.toString(32) +\n \"\\u00bb\");\n return (hook.memoizedState = identifierPrefix);\n },\n useHostTransitionStatus: useHostTransitionStatus,\n useFormState: mountActionState,\n useActionState: mountActionState,\n useOptimistic: function (passthrough) {\n var hook = mountWorkInProgressHook();\n hook.memoizedState = hook.baseState = passthrough;\n var queue = {\n pending: null,\n lanes: 0,\n dispatch: null,\n lastRenderedReducer: null,\n lastRenderedState: null\n };\n hook.queue = queue;\n hook = dispatchOptimisticSetState.bind(\n null,\n currentlyRenderingFiber,\n !0,\n queue\n );\n queue.dispatch = hook;\n return [passthrough, hook];\n },\n useMemoCache: useMemoCache,\n useCacheRefresh: function () {\n return (mountWorkInProgressHook().memoizedState = refreshCache.bind(\n null,\n currentlyRenderingFiber\n ));\n }\n },\n HooksDispatcherOnUpdate = {\n readContext: readContext,\n use: use,\n useCallback: updateCallback,\n useContext: readContext,\n useEffect: updateEffect,\n useImperativeHandle: updateImperativeHandle,\n useInsertionEffect: updateInsertionEffect,\n useLayoutEffect: updateLayoutEffect,\n useMemo: updateMemo,\n useReducer: updateReducer,\n useRef: updateRef,\n useState: function () {\n return updateReducer(basicStateReducer);\n },\n useDebugValue: mountDebugValue,\n useDeferredValue: function (value, initialValue) {\n var hook = updateWorkInProgressHook();\n return updateDeferredValueImpl(\n hook,\n currentHook.memoizedState,\n value,\n initialValue\n );\n },\n useTransition: function () {\n var booleanOrThenable = updateReducer(basicStateReducer)[0],\n start = updateWorkInProgressHook().memoizedState;\n return [\n \"boolean\" === typeof booleanOrThenable\n ? booleanOrThenable\n : useThenable(booleanOrThenable),\n start\n ];\n },\n useSyncExternalStore: updateSyncExternalStore,\n useId: updateId,\n useHostTransitionStatus: useHostTransitionStatus,\n useFormState: updateActionState,\n useActionState: updateActionState,\n useOptimistic: function (passthrough, reducer) {\n var hook = updateWorkInProgressHook();\n return updateOptimisticImpl(hook, currentHook, passthrough, reducer);\n },\n useMemoCache: useMemoCache,\n useCacheRefresh: updateRefresh\n },\n HooksDispatcherOnRerender = {\n readContext: readContext,\n use: use,\n useCallback: updateCallback,\n useContext: readContext,\n useEffect: updateEffect,\n useImperativeHandle: updateImperativeHandle,\n useInsertionEffect: updateInsertionEffect,\n useLayoutEffect: updateLayoutEffect,\n useMemo: updateMemo,\n useReducer: rerenderReducer,\n useRef: updateRef,\n useState: function () {\n return rerenderReducer(basicStateReducer);\n },\n useDebugValue: mountDebugValue,\n useDeferredValue: function (value, initialValue) {\n var hook = updateWorkInProgressHook();\n return null === currentHook\n ? mountDeferredValueImpl(hook, value, initialValue)\n : updateDeferredValueImpl(\n hook,\n currentHook.memoizedState,\n value,\n initialValue\n );\n },\n useTransition: function () {\n var booleanOrThenable = rerenderReducer(basicStateReducer)[0],\n start = updateWorkInProgressHook().memoizedState;\n return [\n \"boolean\" === typeof booleanOrThenable\n ? booleanOrThenable\n : useThenable(booleanOrThenable),\n start\n ];\n },\n useSyncExternalStore: updateSyncExternalStore,\n useId: updateId,\n useHostTransitionStatus: useHostTransitionStatus,\n useFormState: rerenderActionState,\n useActionState: rerenderActionState,\n useOptimistic: function (passthrough, reducer) {\n var hook = updateWorkInProgressHook();\n if (null !== currentHook)\n return updateOptimisticImpl(hook, currentHook, passthrough, reducer);\n hook.baseState = passthrough;\n return [passthrough, hook.queue.dispatch];\n },\n useMemoCache: useMemoCache,\n useCacheRefresh: updateRefresh\n },\n thenableState = null,\n thenableIndexCounter = 0;\nfunction unwrapThenable(thenable) {\n var index = thenableIndexCounter;\n thenableIndexCounter += 1;\n null === thenableState && (thenableState = []);\n return trackUsedThenable(thenableState, thenable, index);\n}\nfunction coerceRef(workInProgress, element) {\n element = element.props.ref;\n workInProgress.ref = void 0 !== element ? element : null;\n}\nfunction throwOnInvalidObjectType(returnFiber, newChild) {\n if (newChild.$$typeof === REACT_LEGACY_ELEMENT_TYPE)\n throw Error(formatProdErrorMessage(525));\n returnFiber = Object.prototype.toString.call(newChild);\n throw Error(\n formatProdErrorMessage(\n 31,\n \"[object Object]\" === returnFiber\n ? \"object with keys {\" + Object.keys(newChild).join(\", \") + \"}\"\n : returnFiber\n )\n );\n}\nfunction resolveLazy(lazyType) {\n var init = lazyType._init;\n return init(lazyType._payload);\n}\nfunction createChildReconciler(shouldTrackSideEffects) {\n function deleteChild(returnFiber, childToDelete) {\n if (shouldTrackSideEffects) {\n var deletions = returnFiber.deletions;\n null === deletions\n ? ((returnFiber.deletions = [childToDelete]), (returnFiber.flags |= 16))\n : deletions.push(childToDelete);\n }\n }\n function deleteRemainingChildren(returnFiber, currentFirstChild) {\n if (!shouldTrackSideEffects) return null;\n for (; null !== currentFirstChild; )\n deleteChild(returnFiber, currentFirstChild),\n (currentFirstChild = currentFirstChild.sibling);\n return null;\n }\n function mapRemainingChildren(currentFirstChild) {\n for (var existingChildren = new Map(); null !== currentFirstChild; )\n null !== currentFirstChild.key\n ? existingChildren.set(currentFirstChild.key, currentFirstChild)\n : existingChildren.set(currentFirstChild.index, currentFirstChild),\n (currentFirstChild = currentFirstChild.sibling);\n return existingChildren;\n }\n function useFiber(fiber, pendingProps) {\n fiber = createWorkInProgress(fiber, pendingProps);\n fiber.index = 0;\n fiber.sibling = null;\n return fiber;\n }\n function placeChild(newFiber, lastPlacedIndex, newIndex) {\n newFiber.index = newIndex;\n if (!shouldTrackSideEffects)\n return (newFiber.flags |= 1048576), lastPlacedIndex;\n newIndex = newFiber.alternate;\n if (null !== newIndex)\n return (\n (newIndex = newIndex.index),\n newIndex < lastPlacedIndex\n ? ((newFiber.flags |= 67108866), lastPlacedIndex)\n : newIndex\n );\n newFiber.flags |= 67108866;\n return lastPlacedIndex;\n }\n function placeSingleChild(newFiber) {\n shouldTrackSideEffects &&\n null === newFiber.alternate &&\n (newFiber.flags |= 67108866);\n return newFiber;\n }\n function updateTextNode(returnFiber, current, textContent, lanes) {\n if (null === current || 6 !== current.tag)\n return (\n (current = createFiberFromText(textContent, returnFiber.mode, lanes)),\n (current.return = returnFiber),\n current\n );\n current = useFiber(current, textContent);\n current.return = returnFiber;\n return current;\n }\n function updateElement(returnFiber, current, element, lanes) {\n var elementType = element.type;\n if (elementType === REACT_FRAGMENT_TYPE)\n return updateFragment(\n returnFiber,\n current,\n element.props.children,\n lanes,\n element.key\n );\n if (\n null !== current &&\n (current.elementType === elementType ||\n (\"object\" === typeof elementType &&\n null !== elementType &&\n elementType.$$typeof === REACT_LAZY_TYPE &&\n resolveLazy(elementType) === current.type))\n )\n return (\n (current = useFiber(current, element.props)),\n coerceRef(current, element),\n (current.return = returnFiber),\n current\n );\n current = createFiberFromTypeAndProps(\n element.type,\n element.key,\n element.props,\n null,\n returnFiber.mode,\n lanes\n );\n coerceRef(current, element);\n current.return = returnFiber;\n return current;\n }\n function updatePortal(returnFiber, current, portal, lanes) {\n if (\n null === current ||\n 4 !== current.tag ||\n current.stateNode.containerInfo !== portal.containerInfo ||\n current.stateNode.implementation !== portal.implementation\n )\n return (\n (current = createFiberFromPortal(portal, returnFiber.mode, lanes)),\n (current.return = returnFiber),\n current\n );\n current = useFiber(current, portal.children || []);\n current.return = returnFiber;\n return current;\n }\n function updateFragment(returnFiber, current, fragment, lanes, key) {\n if (null === current || 7 !== current.tag)\n return (\n (current = createFiberFromFragment(\n fragment,\n returnFiber.mode,\n lanes,\n key\n )),\n (current.return = returnFiber),\n current\n );\n current = useFiber(current, fragment);\n current.return = returnFiber;\n return current;\n }\n function createChild(returnFiber, newChild, lanes) {\n if (\n (\"string\" === typeof newChild && \"\" !== newChild) ||\n \"number\" === typeof newChild ||\n \"bigint\" === typeof newChild\n )\n return (\n (newChild = createFiberFromText(\n \"\" + newChild,\n returnFiber.mode,\n lanes\n )),\n (newChild.return = returnFiber),\n newChild\n );\n if (\"object\" === typeof newChild && null !== newChild) {\n switch (newChild.$$typeof) {\n case REACT_ELEMENT_TYPE:\n return (\n (lanes = createFiberFromTypeAndProps(\n newChild.type,\n newChild.key,\n newChild.props,\n null,\n returnFiber.mode,\n lanes\n )),\n coerceRef(lanes, newChild),\n (lanes.return = returnFiber),\n lanes\n );\n case REACT_PORTAL_TYPE:\n return (\n (newChild = createFiberFromPortal(\n newChild,\n returnFiber.mode,\n lanes\n )),\n (newChild.return = returnFiber),\n newChild\n );\n case REACT_LAZY_TYPE:\n var init = newChild._init;\n newChild = init(newChild._payload);\n return createChild(returnFiber, newChild, lanes);\n }\n if (isArrayImpl(newChild) || getIteratorFn(newChild))\n return (\n (newChild = createFiberFromFragment(\n newChild,\n returnFiber.mode,\n lanes,\n null\n )),\n (newChild.return = returnFiber),\n newChild\n );\n if (\"function\" === typeof newChild.then)\n return createChild(returnFiber, unwrapThenable(newChild), lanes);\n if (newChild.$$typeof === REACT_CONTEXT_TYPE)\n return createChild(\n returnFiber,\n readContextDuringReconciliation(returnFiber, newChild),\n lanes\n );\n throwOnInvalidObjectType(returnFiber, newChild);\n }\n return null;\n }\n function updateSlot(returnFiber, oldFiber, newChild, lanes) {\n var key = null !== oldFiber ? oldFiber.key : null;\n if (\n (\"string\" === typeof newChild && \"\" !== newChild) ||\n \"number\" === typeof newChild ||\n \"bigint\" === typeof newChild\n )\n return null !== key\n ? null\n : updateTextNode(returnFiber, oldFiber, \"\" + newChild, lanes);\n if (\"object\" === typeof newChild && null !== newChild) {\n switch (newChild.$$typeof) {\n case REACT_ELEMENT_TYPE:\n return newChild.key === key\n ? updateElement(returnFiber, oldFiber, newChild, lanes)\n : null;\n case REACT_PORTAL_TYPE:\n return newChild.key === key\n ? updatePortal(returnFiber, oldFiber, newChild, lanes)\n : null;\n case REACT_LAZY_TYPE:\n return (\n (key = newChild._init),\n (newChild = key(newChild._payload)),\n updateSlot(returnFiber, oldFiber, newChild, lanes)\n );\n }\n if (isArrayImpl(newChild) || getIteratorFn(newChild))\n return null !== key\n ? null\n : updateFragment(returnFiber, oldFiber, newChild, lanes, null);\n if (\"function\" === typeof newChild.then)\n return updateSlot(\n returnFiber,\n oldFiber,\n unwrapThenable(newChild),\n lanes\n );\n if (newChild.$$typeof === REACT_CONTEXT_TYPE)\n return updateSlot(\n returnFiber,\n oldFiber,\n readContextDuringReconciliation(returnFiber, newChild),\n lanes\n );\n throwOnInvalidObjectType(returnFiber, newChild);\n }\n return null;\n }\n function updateFromMap(\n existingChildren,\n returnFiber,\n newIdx,\n newChild,\n lanes\n ) {\n if (\n (\"string\" === typeof newChild && \"\" !== newChild) ||\n \"number\" === typeof newChild ||\n \"bigint\" === typeof newChild\n )\n return (\n (existingChildren = existingChildren.get(newIdx) || null),\n updateTextNode(returnFiber, existingChildren, \"\" + newChild, lanes)\n );\n if (\"object\" === typeof newChild && null !== newChild) {\n switch (newChild.$$typeof) {\n case REACT_ELEMENT_TYPE:\n return (\n (existingChildren =\n existingChildren.get(\n null === newChild.key ? newIdx : newChild.key\n ) || null),\n updateElement(returnFiber, existingChildren, newChild, lanes)\n );\n case REACT_PORTAL_TYPE:\n return (\n (existingChildren =\n existingChildren.get(\n null === newChild.key ? newIdx : newChild.key\n ) || null),\n updatePortal(returnFiber, existingChildren, newChild, lanes)\n );\n case REACT_LAZY_TYPE:\n var init = newChild._init;\n newChild = init(newChild._payload);\n return updateFromMap(\n existingChildren,\n returnFiber,\n newIdx,\n newChild,\n lanes\n );\n }\n if (isArrayImpl(newChild) || getIteratorFn(newChild))\n return (\n (existingChildren = existingChildren.get(newIdx) || null),\n updateFragment(returnFiber, existingChildren, newChild, lanes, null)\n );\n if (\"function\" === typeof newChild.then)\n return updateFromMap(\n existingChildren,\n returnFiber,\n newIdx,\n unwrapThenable(newChild),\n lanes\n );\n if (newChild.$$typeof === REACT_CONTEXT_TYPE)\n return updateFromMap(\n existingChildren,\n returnFiber,\n newIdx,\n readContextDuringReconciliation(returnFiber, newChild),\n lanes\n );\n throwOnInvalidObjectType(returnFiber, newChild);\n }\n return null;\n }\n function reconcileChildrenArray(\n returnFiber,\n currentFirstChild,\n newChildren,\n lanes\n ) {\n for (\n var resultingFirstChild = null,\n previousNewFiber = null,\n oldFiber = currentFirstChild,\n newIdx = (currentFirstChild = 0),\n nextOldFiber = null;\n null !== oldFiber && newIdx < newChildren.length;\n newIdx++\n ) {\n oldFiber.index > newIdx\n ? ((nextOldFiber = oldFiber), (oldFiber = null))\n : (nextOldFiber = oldFiber.sibling);\n var newFiber = updateSlot(\n returnFiber,\n oldFiber,\n newChildren[newIdx],\n lanes\n );\n if (null === newFiber) {\n null === oldFiber && (oldFiber = nextOldFiber);\n break;\n }\n shouldTrackSideEffects &&\n oldFiber &&\n null === newFiber.alternate &&\n deleteChild(returnFiber, oldFiber);\n currentFirstChild = placeChild(newFiber, currentFirstChild, newIdx);\n null === previousNewFiber\n ? (resultingFirstChild = newFiber)\n : (previousNewFiber.sibling = newFiber);\n previousNewFiber = newFiber;\n oldFiber = nextOldFiber;\n }\n if (newIdx === newChildren.length)\n return (\n deleteRemainingChildren(returnFiber, oldFiber),\n isHydrating && pushTreeFork(returnFiber, newIdx),\n resultingFirstChild\n );\n if (null === oldFiber) {\n for (; newIdx < newChildren.length; newIdx++)\n (oldFiber = createChild(returnFiber, newChildren[newIdx], lanes)),\n null !== oldFiber &&\n ((currentFirstChild = placeChild(\n oldFiber,\n currentFirstChild,\n newIdx\n )),\n null === previousNewFiber\n ? (resultingFirstChild = oldFiber)\n : (previousNewFiber.sibling = oldFiber),\n (previousNewFiber = oldFiber));\n isHydrating && pushTreeFork(returnFiber, newIdx);\n return resultingFirstChild;\n }\n for (\n oldFiber = mapRemainingChildren(oldFiber);\n newIdx < newChildren.length;\n newIdx++\n )\n (nextOldFiber = updateFromMap(\n oldFiber,\n returnFiber,\n newIdx,\n newChildren[newIdx],\n lanes\n )),\n null !== nextOldFiber &&\n (shouldTrackSideEffects &&\n null !== nextOldFiber.alternate &&\n oldFiber.delete(\n null === nextOldFiber.key ? newIdx : nextOldFiber.key\n ),\n (currentFirstChild = placeChild(\n nextOldFiber,\n currentFirstChild,\n newIdx\n )),\n null === previousNewFiber\n ? (resultingFirstChild = nextOldFiber)\n : (previousNewFiber.sibling = nextOldFiber),\n (previousNewFiber = nextOldFiber));\n shouldTrackSideEffects &&\n oldFiber.forEach(function (child) {\n return deleteChild(returnFiber, child);\n });\n isHydrating && pushTreeFork(returnFiber, newIdx);\n return resultingFirstChild;\n }\n function reconcileChildrenIterator(\n returnFiber,\n currentFirstChild,\n newChildren,\n lanes\n ) {\n if (null == newChildren) throw Error(formatProdErrorMessage(151));\n for (\n var resultingFirstChild = null,\n previousNewFiber = null,\n oldFiber = currentFirstChild,\n newIdx = (currentFirstChild = 0),\n nextOldFiber = null,\n step = newChildren.next();\n null !== oldFiber && !step.done;\n newIdx++, step = newChildren.next()\n ) {\n oldFiber.index > newIdx\n ? ((nextOldFiber = oldFiber), (oldFiber = null))\n : (nextOldFiber = oldFiber.sibling);\n var newFiber = updateSlot(returnFiber, oldFiber, step.value, lanes);\n if (null === newFiber) {\n null === oldFiber && (oldFiber = nextOldFiber);\n break;\n }\n shouldTrackSideEffects &&\n oldFiber &&\n null === newFiber.alternate &&\n deleteChild(returnFiber, oldFiber);\n currentFirstChild = placeChild(newFiber, currentFirstChild, newIdx);\n null === previousNewFiber\n ? (resultingFirstChild = newFiber)\n : (previousNewFiber.sibling = newFiber);\n previousNewFiber = newFiber;\n oldFiber = nextOldFiber;\n }\n if (step.done)\n return (\n deleteRemainingChildren(returnFiber, oldFiber),\n isHydrating && pushTreeFork(returnFiber, newIdx),\n resultingFirstChild\n );\n if (null === oldFiber) {\n for (; !step.done; newIdx++, step = newChildren.next())\n (step = createChild(returnFiber, step.value, lanes)),\n null !== step &&\n ((currentFirstChild = placeChild(step, currentFirstChild, newIdx)),\n null === previousNewFiber\n ? (resultingFirstChild = step)\n : (previousNewFiber.sibling = step),\n (previousNewFiber = step));\n isHydrating && pushTreeFork(returnFiber, newIdx);\n return resultingFirstChild;\n }\n for (\n oldFiber = mapRemainingChildren(oldFiber);\n !step.done;\n newIdx++, step = newChildren.next()\n )\n (step = updateFromMap(oldFiber, returnFiber, newIdx, step.value, lanes)),\n null !== step &&\n (shouldTrackSideEffects &&\n null !== step.alternate &&\n oldFiber.delete(null === step.key ? newIdx : step.key),\n (currentFirstChild = placeChild(step, currentFirstChild, newIdx)),\n null === previousNewFiber\n ? (resultingFirstChild = step)\n : (previousNewFiber.sibling = step),\n (previousNewFiber = step));\n shouldTrackSideEffects &&\n oldFiber.forEach(function (child) {\n return deleteChild(returnFiber, child);\n });\n isHydrating && pushTreeFork(returnFiber, newIdx);\n return resultingFirstChild;\n }\n function reconcileChildFibersImpl(\n returnFiber,\n currentFirstChild,\n newChild,\n lanes\n ) {\n \"object\" === typeof newChild &&\n null !== newChild &&\n newChild.type === REACT_FRAGMENT_TYPE &&\n null === newChild.key &&\n (newChild = newChild.props.children);\n if (\"object\" === typeof newChild && null !== newChild) {\n switch (newChild.$$typeof) {\n case REACT_ELEMENT_TYPE:\n a: {\n for (var key = newChild.key; null !== currentFirstChild; ) {\n if (currentFirstChild.key === key) {\n key = newChild.type;\n if (key === REACT_FRAGMENT_TYPE) {\n if (7 === currentFirstChild.tag) {\n deleteRemainingChildren(\n returnFiber,\n currentFirstChild.sibling\n );\n lanes = useFiber(\n currentFirstChild,\n newChild.props.children\n );\n lanes.return = returnFiber;\n returnFiber = lanes;\n break a;\n }\n } else if (\n currentFirstChild.elementType === key ||\n (\"object\" === typeof key &&\n null !== key &&\n key.$$typeof === REACT_LAZY_TYPE &&\n resolveLazy(key) === currentFirstChild.type)\n ) {\n deleteRemainingChildren(\n returnFiber,\n currentFirstChild.sibling\n );\n lanes = useFiber(currentFirstChild, newChild.props);\n coerceRef(lanes, newChild);\n lanes.return = returnFiber;\n returnFiber = lanes;\n break a;\n }\n deleteRemainingChildren(returnFiber, currentFirstChild);\n break;\n } else deleteChild(returnFiber, currentFirstChild);\n currentFirstChild = currentFirstChild.sibling;\n }\n newChild.type === REACT_FRAGMENT_TYPE\n ? ((lanes = createFiberFromFragment(\n newChild.props.children,\n returnFiber.mode,\n lanes,\n newChild.key\n )),\n (lanes.return = returnFiber),\n (returnFiber = lanes))\n : ((lanes = createFiberFromTypeAndProps(\n newChild.type,\n newChild.key,\n newChild.props,\n null,\n returnFiber.mode,\n lanes\n )),\n coerceRef(lanes, newChild),\n (lanes.return = returnFiber),\n (returnFiber = lanes));\n }\n return placeSingleChild(returnFiber);\n case REACT_PORTAL_TYPE:\n a: {\n for (key = newChild.key; null !== currentFirstChild; ) {\n if (currentFirstChild.key === key)\n if (\n 4 === currentFirstChild.tag &&\n currentFirstChild.stateNode.containerInfo ===\n newChild.containerInfo &&\n currentFirstChild.stateNode.implementation ===\n newChild.implementation\n ) {\n deleteRemainingChildren(\n returnFiber,\n currentFirstChild.sibling\n );\n lanes = useFiber(currentFirstChild, newChild.children || []);\n lanes.return = returnFiber;\n returnFiber = lanes;\n break a;\n } else {\n deleteRemainingChildren(returnFiber, currentFirstChild);\n break;\n }\n else deleteChild(returnFiber, currentFirstChild);\n currentFirstChild = currentFirstChild.sibling;\n }\n lanes = createFiberFromPortal(newChild, returnFiber.mode, lanes);\n lanes.return = returnFiber;\n returnFiber = lanes;\n }\n return placeSingleChild(returnFiber);\n case REACT_LAZY_TYPE:\n return (\n (key = newChild._init),\n (newChild = key(newChild._payload)),\n reconcileChildFibersImpl(\n returnFiber,\n currentFirstChild,\n newChild,\n lanes\n )\n );\n }\n if (isArrayImpl(newChild))\n return reconcileChildrenArray(\n returnFiber,\n currentFirstChild,\n newChild,\n lanes\n );\n if (getIteratorFn(newChild)) {\n key = getIteratorFn(newChild);\n if (\"function\" !== typeof key) throw Error(formatProdErrorMessage(150));\n newChild = key.call(newChild);\n return reconcileChildrenIterator(\n returnFiber,\n currentFirstChild,\n newChild,\n lanes\n );\n }\n if (\"function\" === typeof newChild.then)\n return reconcileChildFibersImpl(\n returnFiber,\n currentFirstChild,\n unwrapThenable(newChild),\n lanes\n );\n if (newChild.$$typeof === REACT_CONTEXT_TYPE)\n return reconcileChildFibersImpl(\n returnFiber,\n currentFirstChild,\n readContextDuringReconciliation(returnFiber, newChild),\n lanes\n );\n throwOnInvalidObjectType(returnFiber, newChild);\n }\n return (\"string\" === typeof newChild && \"\" !== newChild) ||\n \"number\" === typeof newChild ||\n \"bigint\" === typeof newChild\n ? ((newChild = \"\" + newChild),\n null !== currentFirstChild && 6 === currentFirstChild.tag\n ? (deleteRemainingChildren(returnFiber, currentFirstChild.sibling),\n (lanes = useFiber(currentFirstChild, newChild)),\n (lanes.return = returnFiber),\n (returnFiber = lanes))\n : (deleteRemainingChildren(returnFiber, currentFirstChild),\n (lanes = createFiberFromText(newChild, returnFiber.mode, lanes)),\n (lanes.return = returnFiber),\n (returnFiber = lanes)),\n placeSingleChild(returnFiber))\n : deleteRemainingChildren(returnFiber, currentFirstChild);\n }\n return function (returnFiber, currentFirstChild, newChild, lanes) {\n try {\n thenableIndexCounter = 0;\n var firstChildFiber = reconcileChildFibersImpl(\n returnFiber,\n currentFirstChild,\n newChild,\n lanes\n );\n thenableState = null;\n return firstChildFiber;\n } catch (x) {\n if (x === SuspenseException || x === SuspenseActionException) throw x;\n var fiber = createFiberImplClass(29, x, null, returnFiber.mode);\n fiber.lanes = lanes;\n fiber.return = returnFiber;\n return fiber;\n } finally {\n }\n };\n}\nvar reconcileChildFibers = createChildReconciler(!0),\n mountChildFibers = createChildReconciler(!1),\n suspenseHandlerStackCursor = createCursor(null),\n shellBoundary = null;\nfunction pushPrimaryTreeSuspenseHandler(handler) {\n var current = handler.alternate;\n push(suspenseStackCursor, suspenseStackCursor.current & 1);\n push(suspenseHandlerStackCursor, handler);\n null === shellBoundary &&\n (null === current || null !== currentTreeHiddenStackCursor.current\n ? (shellBoundary = handler)\n : null !== current.memoizedState && (shellBoundary = handler));\n}\nfunction pushOffscreenSuspenseHandler(fiber) {\n if (22 === fiber.tag) {\n if (\n (push(suspenseStackCursor, suspenseStackCursor.current),\n push(suspenseHandlerStackCursor, fiber),\n null === shellBoundary)\n ) {\n var current = fiber.alternate;\n null !== current &&\n null !== current.memoizedState &&\n (shellBoundary = fiber);\n }\n } else reuseSuspenseHandlerOnStack(fiber);\n}\nfunction reuseSuspenseHandlerOnStack() {\n push(suspenseStackCursor, suspenseStackCursor.current);\n push(suspenseHandlerStackCursor, suspenseHandlerStackCursor.current);\n}\nfunction popSuspenseHandler(fiber) {\n pop(suspenseHandlerStackCursor);\n shellBoundary === fiber && (shellBoundary = null);\n pop(suspenseStackCursor);\n}\nvar suspenseStackCursor = createCursor(0);\nfunction findFirstSuspended(row) {\n for (var node = row; null !== node; ) {\n if (13 === node.tag) {\n var state = node.memoizedState;\n if (\n null !== state &&\n ((state = state.dehydrated),\n null === state ||\n \"$?\" === state.data ||\n isSuspenseInstanceFallback(state))\n )\n return node;\n } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) {\n if (0 !== (node.flags & 128)) return node;\n } else if (null !== node.child) {\n node.child.return = node;\n node = node.child;\n continue;\n }\n if (node === row) break;\n for (; null === node.sibling; ) {\n if (null === node.return || node.return === row) return null;\n node = node.return;\n }\n node.sibling.return = node.return;\n node = node.sibling;\n }\n return null;\n}\nfunction applyDerivedStateFromProps(\n workInProgress,\n ctor,\n getDerivedStateFromProps,\n nextProps\n) {\n ctor = workInProgress.memoizedState;\n getDerivedStateFromProps = getDerivedStateFromProps(nextProps, ctor);\n getDerivedStateFromProps =\n null === getDerivedStateFromProps || void 0 === getDerivedStateFromProps\n ? ctor\n : assign({}, ctor, getDerivedStateFromProps);\n workInProgress.memoizedState = getDerivedStateFromProps;\n 0 === workInProgress.lanes &&\n (workInProgress.updateQueue.baseState = getDerivedStateFromProps);\n}\nvar classComponentUpdater = {\n enqueueSetState: function (inst, payload, callback) {\n inst = inst._reactInternals;\n var lane = requestUpdateLane(),\n update = createUpdate(lane);\n update.payload = payload;\n void 0 !== callback && null !== callback && (update.callback = callback);\n payload = enqueueUpdate(inst, update, lane);\n null !== payload &&\n (scheduleUpdateOnFiber(payload, inst, lane),\n entangleTransitions(payload, inst, lane));\n },\n enqueueReplaceState: function (inst, payload, callback) {\n inst = inst._reactInternals;\n var lane = requestUpdateLane(),\n update = createUpdate(lane);\n update.tag = 1;\n update.payload = payload;\n void 0 !== callback && null !== callback && (update.callback = callback);\n payload = enqueueUpdate(inst, update, lane);\n null !== payload &&\n (scheduleUpdateOnFiber(payload, inst, lane),\n entangleTransitions(payload, inst, lane));\n },\n enqueueForceUpdate: function (inst, callback) {\n inst = inst._reactInternals;\n var lane = requestUpdateLane(),\n update = createUpdate(lane);\n update.tag = 2;\n void 0 !== callback && null !== callback && (update.callback = callback);\n callback = enqueueUpdate(inst, update, lane);\n null !== callback &&\n (scheduleUpdateOnFiber(callback, inst, lane),\n entangleTransitions(callback, inst, lane));\n }\n};\nfunction checkShouldComponentUpdate(\n workInProgress,\n ctor,\n oldProps,\n newProps,\n oldState,\n newState,\n nextContext\n) {\n workInProgress = workInProgress.stateNode;\n return \"function\" === typeof workInProgress.shouldComponentUpdate\n ? workInProgress.shouldComponentUpdate(newProps, newState, nextContext)\n : ctor.prototype && ctor.prototype.isPureReactComponent\n ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState)\n : !0;\n}\nfunction callComponentWillReceiveProps(\n workInProgress,\n instance,\n newProps,\n nextContext\n) {\n workInProgress = instance.state;\n \"function\" === typeof instance.componentWillReceiveProps &&\n instance.componentWillReceiveProps(newProps, nextContext);\n \"function\" === typeof instance.UNSAFE_componentWillReceiveProps &&\n instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);\n instance.state !== workInProgress &&\n classComponentUpdater.enqueueReplaceState(instance, instance.state, null);\n}\nfunction resolveClassComponentProps(Component, baseProps) {\n var newProps = baseProps;\n if (\"ref\" in baseProps) {\n newProps = {};\n for (var propName in baseProps)\n \"ref\" !== propName && (newProps[propName] = baseProps[propName]);\n }\n if ((Component = Component.defaultProps)) {\n newProps === baseProps && (newProps = assign({}, newProps));\n for (var propName$73 in Component)\n void 0 === newProps[propName$73] &&\n (newProps[propName$73] = Component[propName$73]);\n }\n return newProps;\n}\nvar reportGlobalError =\n \"function\" === typeof reportError\n ? reportError\n : function (error) {\n if (\n \"object\" === typeof window &&\n \"function\" === typeof window.ErrorEvent\n ) {\n var event = new window.ErrorEvent(\"error\", {\n bubbles: !0,\n cancelable: !0,\n message:\n \"object\" === typeof error &&\n null !== error &&\n \"string\" === typeof error.message\n ? String(error.message)\n : String(error),\n error: error\n });\n if (!window.dispatchEvent(event)) return;\n } else if (\n \"object\" === typeof process &&\n \"function\" === typeof process.emit\n ) {\n process.emit(\"uncaughtException\", error);\n return;\n }\n console.error(error);\n };\nfunction defaultOnUncaughtError(error) {\n reportGlobalError(error);\n}\nfunction defaultOnCaughtError(error) {\n console.error(error);\n}\nfunction defaultOnRecoverableError(error) {\n reportGlobalError(error);\n}\nfunction logUncaughtError(root, errorInfo) {\n try {\n var onUncaughtError = root.onUncaughtError;\n onUncaughtError(errorInfo.value, { componentStack: errorInfo.stack });\n } catch (e$74) {\n setTimeout(function () {\n throw e$74;\n });\n }\n}\nfunction logCaughtError(root, boundary, errorInfo) {\n try {\n var onCaughtError = root.onCaughtError;\n onCaughtError(errorInfo.value, {\n componentStack: errorInfo.stack,\n errorBoundary: 1 === boundary.tag ? boundary.stateNode : null\n });\n } catch (e$75) {\n setTimeout(function () {\n throw e$75;\n });\n }\n}\nfunction createRootErrorUpdate(root, errorInfo, lane) {\n lane = createUpdate(lane);\n lane.tag = 3;\n lane.payload = { element: null };\n lane.callback = function () {\n logUncaughtError(root, errorInfo);\n };\n return lane;\n}\nfunction createClassErrorUpdate(lane) {\n lane = createUpdate(lane);\n lane.tag = 3;\n return lane;\n}\nfunction initializeClassErrorUpdate(update, root, fiber, errorInfo) {\n var getDerivedStateFromError = fiber.type.getDerivedStateFromError;\n if (\"function\" === typeof getDerivedStateFromError) {\n var error = errorInfo.value;\n update.payload = function () {\n return getDerivedStateFromError(error);\n };\n update.callback = function () {\n logCaughtError(root, fiber, errorInfo);\n };\n }\n var inst = fiber.stateNode;\n null !== inst &&\n \"function\" === typeof inst.componentDidCatch &&\n (update.callback = function () {\n logCaughtError(root, fiber, errorInfo);\n \"function\" !== typeof getDerivedStateFromError &&\n (null === legacyErrorBoundariesThatAlreadyFailed\n ? (legacyErrorBoundariesThatAlreadyFailed = new Set([this]))\n : legacyErrorBoundariesThatAlreadyFailed.add(this));\n var stack = errorInfo.stack;\n this.componentDidCatch(errorInfo.value, {\n componentStack: null !== stack ? stack : \"\"\n });\n });\n}\nfunction throwException(\n root,\n returnFiber,\n sourceFiber,\n value,\n rootRenderLanes\n) {\n sourceFiber.flags |= 32768;\n if (\n null !== value &&\n \"object\" === typeof value &&\n \"function\" === typeof value.then\n ) {\n returnFiber = sourceFiber.alternate;\n null !== returnFiber &&\n propagateParentContextChanges(\n returnFiber,\n sourceFiber,\n rootRenderLanes,\n !0\n );\n sourceFiber = suspenseHandlerStackCursor.current;\n if (null !== sourceFiber) {\n switch (sourceFiber.tag) {\n case 13:\n return (\n null === shellBoundary\n ? renderDidSuspendDelayIfPossible()\n : null === sourceFiber.alternate &&\n 0 === workInProgressRootExitStatus &&\n (workInProgressRootExitStatus = 3),\n (sourceFiber.flags &= -257),\n (sourceFiber.flags |= 65536),\n (sourceFiber.lanes = rootRenderLanes),\n value === noopSuspenseyCommitThenable\n ? (sourceFiber.flags |= 16384)\n : ((returnFiber = sourceFiber.updateQueue),\n null === returnFiber\n ? (sourceFiber.updateQueue = new Set([value]))\n : returnFiber.add(value),\n attachPingListener(root, value, rootRenderLanes)),\n !1\n );\n case 22:\n return (\n (sourceFiber.flags |= 65536),\n value === noopSuspenseyCommitThenable\n ? (sourceFiber.flags |= 16384)\n : ((returnFiber = sourceFiber.updateQueue),\n null === returnFiber\n ? ((returnFiber = {\n transitions: null,\n markerInstances: null,\n retryQueue: new Set([value])\n }),\n (sourceFiber.updateQueue = returnFiber))\n : ((sourceFiber = returnFiber.retryQueue),\n null === sourceFiber\n ? (returnFiber.retryQueue = new Set([value]))\n : sourceFiber.add(value)),\n attachPingListener(root, value, rootRenderLanes)),\n !1\n );\n }\n throw Error(formatProdErrorMessage(435, sourceFiber.tag));\n }\n attachPingListener(root, value, rootRenderLanes);\n renderDidSuspendDelayIfPossible();\n return !1;\n }\n if (isHydrating)\n return (\n (returnFiber = suspenseHandlerStackCursor.current),\n null !== returnFiber\n ? (0 === (returnFiber.flags & 65536) && (returnFiber.flags |= 256),\n (returnFiber.flags |= 65536),\n (returnFiber.lanes = rootRenderLanes),\n value !== HydrationMismatchException &&\n ((root = Error(formatProdErrorMessage(422), { cause: value })),\n queueHydrationError(createCapturedValueAtFiber(root, sourceFiber))))\n : (value !== HydrationMismatchException &&\n ((returnFiber = Error(formatProdErrorMessage(423), {\n cause: value\n })),\n queueHydrationError(\n createCapturedValueAtFiber(returnFiber, sourceFiber)\n )),\n (root = root.current.alternate),\n (root.flags |= 65536),\n (rootRenderLanes &= -rootRenderLanes),\n (root.lanes |= rootRenderLanes),\n (value = createCapturedValueAtFiber(value, sourceFiber)),\n (rootRenderLanes = createRootErrorUpdate(\n root.stateNode,\n value,\n rootRenderLanes\n )),\n enqueueCapturedUpdate(root, rootRenderLanes),\n 4 !== workInProgressRootExitStatus &&\n (workInProgressRootExitStatus = 2)),\n !1\n );\n var wrapperError = Error(formatProdErrorMessage(520), { cause: value });\n wrapperError = createCapturedValueAtFiber(wrapperError, sourceFiber);\n null === workInProgressRootConcurrentErrors\n ? (workInProgressRootConcurrentErrors = [wrapperError])\n : workInProgressRootConcurrentErrors.push(wrapperError);\n 4 !== workInProgressRootExitStatus && (workInProgressRootExitStatus = 2);\n if (null === returnFiber) return !0;\n value = createCapturedValueAtFiber(value, sourceFiber);\n sourceFiber = returnFiber;\n do {\n switch (sourceFiber.tag) {\n case 3:\n return (\n (sourceFiber.flags |= 65536),\n (root = rootRenderLanes & -rootRenderLanes),\n (sourceFiber.lanes |= root),\n (root = createRootErrorUpdate(sourceFiber.stateNode, value, root)),\n enqueueCapturedUpdate(sourceFiber, root),\n !1\n );\n case 1:\n if (\n ((returnFiber = sourceFiber.type),\n (wrapperError = sourceFiber.stateNode),\n 0 === (sourceFiber.flags & 128) &&\n (\"function\" === typeof returnFiber.getDerivedStateFromError ||\n (null !== wrapperError &&\n \"function\" === typeof wrapperError.componentDidCatch &&\n (null === legacyErrorBoundariesThatAlreadyFailed ||\n !legacyErrorBoundariesThatAlreadyFailed.has(wrapperError)))))\n )\n return (\n (sourceFiber.flags |= 65536),\n (rootRenderLanes &= -rootRenderLanes),\n (sourceFiber.lanes |= rootRenderLanes),\n (rootRenderLanes = createClassErrorUpdate(rootRenderLanes)),\n initializeClassErrorUpdate(\n rootRenderLanes,\n root,\n sourceFiber,\n value\n ),\n enqueueCapturedUpdate(sourceFiber, rootRenderLanes),\n !1\n );\n }\n sourceFiber = sourceFiber.return;\n } while (null !== sourceFiber);\n return !1;\n}\nvar SelectiveHydrationException = Error(formatProdErrorMessage(461)),\n didReceiveUpdate = !1;\nfunction reconcileChildren(current, workInProgress, nextChildren, renderLanes) {\n workInProgress.child =\n null === current\n ? mountChildFibers(workInProgress, null, nextChildren, renderLanes)\n : reconcileChildFibers(\n workInProgress,\n current.child,\n nextChildren,\n renderLanes\n );\n}\nfunction updateForwardRef(\n current,\n workInProgress,\n Component,\n nextProps,\n renderLanes\n) {\n Component = Component.render;\n var ref = workInProgress.ref;\n if (\"ref\" in nextProps) {\n var propsWithoutRef = {};\n for (var key in nextProps)\n \"ref\" !== key && (propsWithoutRef[key] = nextProps[key]);\n } else propsWithoutRef = nextProps;\n prepareToReadContext(workInProgress);\n nextProps = renderWithHooks(\n current,\n workInProgress,\n Component,\n propsWithoutRef,\n ref,\n renderLanes\n );\n key = checkDidRenderIdHook();\n if (null !== current && !didReceiveUpdate)\n return (\n bailoutHooks(current, workInProgress, renderLanes),\n bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes)\n );\n isHydrating && key && pushMaterializedTreeId(workInProgress);\n workInProgress.flags |= 1;\n reconcileChildren(current, workInProgress, nextProps, renderLanes);\n return workInProgress.child;\n}\nfunction updateMemoComponent(\n current,\n workInProgress,\n Component,\n nextProps,\n renderLanes\n) {\n if (null === current) {\n var type = Component.type;\n if (\n \"function\" === typeof type &&\n !shouldConstruct(type) &&\n void 0 === type.defaultProps &&\n null === Component.compare\n )\n return (\n (workInProgress.tag = 15),\n (workInProgress.type = type),\n updateSimpleMemoComponent(\n current,\n workInProgress,\n type,\n nextProps,\n renderLanes\n )\n );\n current = createFiberFromTypeAndProps(\n Component.type,\n null,\n nextProps,\n workInProgress,\n workInProgress.mode,\n renderLanes\n );\n current.ref = workInProgress.ref;\n current.return = workInProgress;\n return (workInProgress.child = current);\n }\n type = current.child;\n if (!checkScheduledUpdateOrContext(current, renderLanes)) {\n var prevProps = type.memoizedProps;\n Component = Component.compare;\n Component = null !== Component ? Component : shallowEqual;\n if (Component(prevProps, nextProps) && current.ref === workInProgress.ref)\n return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);\n }\n workInProgress.flags |= 1;\n current = createWorkInProgress(type, nextProps);\n current.ref = workInProgress.ref;\n current.return = workInProgress;\n return (workInProgress.child = current);\n}\nfunction updateSimpleMemoComponent(\n current,\n workInProgress,\n Component,\n nextProps,\n renderLanes\n) {\n if (null !== current) {\n var prevProps = current.memoizedProps;\n if (\n shallowEqual(prevProps, nextProps) &&\n current.ref === workInProgress.ref\n )\n if (\n ((didReceiveUpdate = !1),\n (workInProgress.pendingProps = nextProps = prevProps),\n checkScheduledUpdateOrContext(current, renderLanes))\n )\n 0 !== (current.flags & 131072) && (didReceiveUpdate = !0);\n else\n return (\n (workInProgress.lanes = current.lanes),\n bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes)\n );\n }\n return updateFunctionComponent(\n current,\n workInProgress,\n Component,\n nextProps,\n renderLanes\n );\n}\nfunction updateOffscreenComponent(current, workInProgress, renderLanes) {\n var nextProps = workInProgress.pendingProps,\n nextChildren = nextProps.children,\n prevState = null !== current ? current.memoizedState : null;\n if (\"hidden\" === nextProps.mode) {\n if (0 !== (workInProgress.flags & 128)) {\n nextProps =\n null !== prevState ? prevState.baseLanes | renderLanes : renderLanes;\n if (null !== current) {\n nextChildren = workInProgress.child = current.child;\n for (prevState = 0; null !== nextChildren; )\n (prevState =\n prevState | nextChildren.lanes | nextChildren.childLanes),\n (nextChildren = nextChildren.sibling);\n workInProgress.childLanes = prevState & ~nextProps;\n } else (workInProgress.childLanes = 0), (workInProgress.child = null);\n return deferHiddenOffscreenComponent(\n current,\n workInProgress,\n nextProps,\n renderLanes\n );\n }\n if (0 !== (renderLanes & 536870912))\n (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }),\n null !== current &&\n pushTransition(\n workInProgress,\n null !== prevState ? prevState.cachePool : null\n ),\n null !== prevState\n ? pushHiddenContext(workInProgress, prevState)\n : reuseHiddenContextOnStack(),\n pushOffscreenSuspenseHandler(workInProgress);\n else\n return (\n (workInProgress.lanes = workInProgress.childLanes = 536870912),\n deferHiddenOffscreenComponent(\n current,\n workInProgress,\n null !== prevState ? prevState.baseLanes | renderLanes : renderLanes,\n renderLanes\n )\n );\n } else\n null !== prevState\n ? (pushTransition(workInProgress, prevState.cachePool),\n pushHiddenContext(workInProgress, prevState),\n reuseSuspenseHandlerOnStack(workInProgress),\n (workInProgress.memoizedState = null))\n : (null !== current && pushTransition(workInProgress, null),\n reuseHiddenContextOnStack(),\n reuseSuspenseHandlerOnStack(workInProgress));\n reconcileChildren(current, workInProgress, nextChildren, renderLanes);\n return workInProgress.child;\n}\nfunction deferHiddenOffscreenComponent(\n current,\n workInProgress,\n nextBaseLanes,\n renderLanes\n) {\n var JSCompiler_inline_result = peekCacheFromPool();\n JSCompiler_inline_result =\n null === JSCompiler_inline_result\n ? null\n : { parent: CacheContext._currentValue, pool: JSCompiler_inline_result };\n workInProgress.memoizedState = {\n baseLanes: nextBaseLanes,\n cachePool: JSCompiler_inline_result\n };\n null !== current && pushTransition(workInProgress, null);\n reuseHiddenContextOnStack();\n pushOffscreenSuspenseHandler(workInProgress);\n null !== current &&\n propagateParentContextChanges(current, workInProgress, renderLanes, !0);\n return null;\n}\nfunction markRef(current, workInProgress) {\n var ref = workInProgress.ref;\n if (null === ref)\n null !== current &&\n null !== current.ref &&\n (workInProgress.flags |= 4194816);\n else {\n if (\"function\" !== typeof ref && \"object\" !== typeof ref)\n throw Error(formatProdErrorMessage(284));\n if (null === current || current.ref !== ref)\n workInProgress.flags |= 4194816;\n }\n}\nfunction updateFunctionComponent(\n current,\n workInProgress,\n Component,\n nextProps,\n renderLanes\n) {\n prepareToReadContext(workInProgress);\n Component = renderWithHooks(\n current,\n workInProgress,\n Component,\n nextProps,\n void 0,\n renderLanes\n );\n nextProps = checkDidRenderIdHook();\n if (null !== current && !didReceiveUpdate)\n return (\n bailoutHooks(current, workInProgress, renderLanes),\n bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes)\n );\n isHydrating && nextProps && pushMaterializedTreeId(workInProgress);\n workInProgress.flags |= 1;\n reconcileChildren(current, workInProgress, Component, renderLanes);\n return workInProgress.child;\n}\nfunction replayFunctionComponent(\n current,\n workInProgress,\n nextProps,\n Component,\n secondArg,\n renderLanes\n) {\n prepareToReadContext(workInProgress);\n workInProgress.updateQueue = null;\n nextProps = renderWithHooksAgain(\n workInProgress,\n Component,\n nextProps,\n secondArg\n );\n finishRenderingHooks(current);\n Component = checkDidRenderIdHook();\n if (null !== current && !didReceiveUpdate)\n return (\n bailoutHooks(current, workInProgress, renderLanes),\n bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes)\n );\n isHydrating && Component && pushMaterializedTreeId(workInProgress);\n workInProgress.flags |= 1;\n reconcileChildren(current, workInProgress, nextProps, renderLanes);\n return workInProgress.child;\n}\nfunction updateClassComponent(\n current,\n workInProgress,\n Component,\n nextProps,\n renderLanes\n) {\n prepareToReadContext(workInProgress);\n if (null === workInProgress.stateNode) {\n var context = emptyContextObject,\n contextType = Component.contextType;\n \"object\" === typeof contextType &&\n null !== contextType &&\n (context = readContext(contextType));\n context = new Component(nextProps, context);\n workInProgress.memoizedState =\n null !== context.state && void 0 !== context.state ? context.state : null;\n context.updater = classComponentUpdater;\n workInProgress.stateNode = context;\n context._reactInternals = workInProgress;\n context = workInProgress.stateNode;\n context.props = nextProps;\n context.state = workInProgress.memoizedState;\n context.refs = {};\n initializeUpdateQueue(workInProgress);\n contextType = Component.contextType;\n context.context =\n \"object\" === typeof contextType && null !== contextType\n ? readContext(contextType)\n : emptyContextObject;\n context.state = workInProgress.memoizedState;\n contextType = Component.getDerivedStateFromProps;\n \"function\" === typeof contextType &&\n (applyDerivedStateFromProps(\n workInProgress,\n Component,\n contextType,\n nextProps\n ),\n (context.state = workInProgress.memoizedState));\n \"function\" === typeof Component.getDerivedStateFromProps ||\n \"function\" === typeof context.getSnapshotBeforeUpdate ||\n (\"function\" !== typeof context.UNSAFE_componentWillMount &&\n \"function\" !== typeof context.componentWillMount) ||\n ((contextType = context.state),\n \"function\" === typeof context.componentWillMount &&\n context.componentWillMount(),\n \"function\" === typeof context.UNSAFE_componentWillMount &&\n context.UNSAFE_componentWillMount(),\n contextType !== context.state &&\n classComponentUpdater.enqueueReplaceState(context, context.state, null),\n processUpdateQueue(workInProgress, nextProps, context, renderLanes),\n suspendIfUpdateReadFromEntangledAsyncAction(),\n (context.state = workInProgress.memoizedState));\n \"function\" === typeof context.componentDidMount &&\n (workInProgress.flags |= 4194308);\n nextProps = !0;\n } else if (null === current) {\n context = workInProgress.stateNode;\n var unresolvedOldProps = workInProgress.memoizedProps,\n oldProps = resolveClassComponentProps(Component, unresolvedOldProps);\n context.props = oldProps;\n var oldContext = context.context,\n contextType$jscomp$0 = Component.contextType;\n contextType = emptyContextObject;\n \"object\" === typeof contextType$jscomp$0 &&\n null !== contextType$jscomp$0 &&\n (contextType = readContext(contextType$jscomp$0));\n var getDerivedStateFromProps = Component.getDerivedStateFromProps;\n contextType$jscomp$0 =\n \"function\" === typeof getDerivedStateFromProps ||\n \"function\" === typeof context.getSnapshotBeforeUpdate;\n unresolvedOldProps = workInProgress.pendingProps !== unresolvedOldProps;\n contextType$jscomp$0 ||\n (\"function\" !== typeof context.UNSAFE_componentWillReceiveProps &&\n \"function\" !== typeof context.componentWillReceiveProps) ||\n ((unresolvedOldProps || oldContext !== contextType) &&\n callComponentWillReceiveProps(\n workInProgress,\n context,\n nextProps,\n contextType\n ));\n hasForceUpdate = !1;\n var oldState = workInProgress.memoizedState;\n context.state = oldState;\n processUpdateQueue(workInProgress, nextProps, context, renderLanes);\n suspendIfUpdateReadFromEntangledAsyncAction();\n oldContext = workInProgress.memoizedState;\n unresolvedOldProps || oldState !== oldContext || hasForceUpdate\n ? (\"function\" === typeof getDerivedStateFromProps &&\n (applyDerivedStateFromProps(\n workInProgress,\n Component,\n getDerivedStateFromProps,\n nextProps\n ),\n (oldContext = workInProgress.memoizedState)),\n (oldProps =\n hasForceUpdate ||\n checkShouldComponentUpdate(\n workInProgress,\n Component,\n oldProps,\n nextProps,\n oldState,\n oldContext,\n contextType\n ))\n ? (contextType$jscomp$0 ||\n (\"function\" !== typeof context.UNSAFE_componentWillMount &&\n \"function\" !== typeof context.componentWillMount) ||\n (\"function\" === typeof context.componentWillMount &&\n context.componentWillMount(),\n \"function\" === typeof context.UNSAFE_componentWillMount &&\n context.UNSAFE_componentWillMount()),\n \"function\" === typeof context.componentDidMount &&\n (workInProgress.flags |= 4194308))\n : (\"function\" === typeof context.componentDidMount &&\n (workInProgress.flags |= 4194308),\n (workInProgress.memoizedProps = nextProps),\n (workInProgress.memoizedState = oldContext)),\n (context.props = nextProps),\n (context.state = oldContext),\n (context.context = contextType),\n (nextProps = oldProps))\n : (\"function\" === typeof context.componentDidMount &&\n (workInProgress.flags |= 4194308),\n (nextProps = !1));\n } else {\n context = workInProgress.stateNode;\n cloneUpdateQueue(current, workInProgress);\n contextType = workInProgress.memoizedProps;\n contextType$jscomp$0 = resolveClassComponentProps(Component, contextType);\n context.props = contextType$jscomp$0;\n getDerivedStateFromProps = workInProgress.pendingProps;\n oldState = context.context;\n oldContext = Component.contextType;\n oldProps = emptyContextObject;\n \"object\" === typeof oldContext &&\n null !== oldContext &&\n (oldProps = readContext(oldContext));\n unresolvedOldProps = Component.getDerivedStateFromProps;\n (oldContext =\n \"function\" === typeof unresolvedOldProps ||\n \"function\" === typeof context.getSnapshotBeforeUpdate) ||\n (\"function\" !== typeof context.UNSAFE_componentWillReceiveProps &&\n \"function\" !== typeof context.componentWillReceiveProps) ||\n ((contextType !== getDerivedStateFromProps || oldState !== oldProps) &&\n callComponentWillReceiveProps(\n workInProgress,\n context,\n nextProps,\n oldProps\n ));\n hasForceUpdate = !1;\n oldState = workInProgress.memoizedState;\n context.state = oldState;\n processUpdateQueue(workInProgress, nextProps, context, renderLanes);\n suspendIfUpdateReadFromEntangledAsyncAction();\n var newState = workInProgress.memoizedState;\n contextType !== getDerivedStateFromProps ||\n oldState !== newState ||\n hasForceUpdate ||\n (null !== current &&\n null !== current.dependencies &&\n checkIfContextChanged(current.dependencies))\n ? (\"function\" === typeof unresolvedOldProps &&\n (applyDerivedStateFromProps(\n workInProgress,\n Component,\n unresolvedOldProps,\n nextProps\n ),\n (newState = workInProgress.memoizedState)),\n (contextType$jscomp$0 =\n hasForceUpdate ||\n checkShouldComponentUpdate(\n workInProgress,\n Component,\n contextType$jscomp$0,\n nextProps,\n oldState,\n newState,\n oldProps\n ) ||\n (null !== current &&\n null !== current.dependencies &&\n checkIfContextChanged(current.dependencies)))\n ? (oldContext ||\n (\"function\" !== typeof context.UNSAFE_componentWillUpdate &&\n \"function\" !== typeof context.componentWillUpdate) ||\n (\"function\" === typeof context.componentWillUpdate &&\n context.componentWillUpdate(nextProps, newState, oldProps),\n \"function\" === typeof context.UNSAFE_componentWillUpdate &&\n context.UNSAFE_componentWillUpdate(\n nextProps,\n newState,\n oldProps\n )),\n \"function\" === typeof context.componentDidUpdate &&\n (workInProgress.flags |= 4),\n \"function\" === typeof context.getSnapshotBeforeUpdate &&\n (workInProgress.flags |= 1024))\n : (\"function\" !== typeof context.componentDidUpdate ||\n (contextType === current.memoizedProps &&\n oldState === current.memoizedState) ||\n (workInProgress.flags |= 4),\n \"function\" !== typeof context.getSnapshotBeforeUpdate ||\n (contextType === current.memoizedProps &&\n oldState === current.memoizedState) ||\n (workInProgress.flags |= 1024),\n (workInProgress.memoizedProps = nextProps),\n (workInProgress.memoizedState = newState)),\n (context.props = nextProps),\n (context.state = newState),\n (context.context = oldProps),\n (nextProps = contextType$jscomp$0))\n : (\"function\" !== typeof context.componentDidUpdate ||\n (contextType === current.memoizedProps &&\n oldState === current.memoizedState) ||\n (workInProgress.flags |= 4),\n \"function\" !== typeof context.getSnapshotBeforeUpdate ||\n (contextType === current.memoizedProps &&\n oldState === current.memoizedState) ||\n (workInProgress.flags |= 1024),\n (nextProps = !1));\n }\n context = nextProps;\n markRef(current, workInProgress);\n nextProps = 0 !== (workInProgress.flags & 128);\n context || nextProps\n ? ((context = workInProgress.stateNode),\n (Component =\n nextProps && \"function\" !== typeof Component.getDerivedStateFromError\n ? null\n : context.render()),\n (workInProgress.flags |= 1),\n null !== current && nextProps\n ? ((workInProgress.child = reconcileChildFibers(\n workInProgress,\n current.child,\n null,\n renderLanes\n )),\n (workInProgress.child = reconcileChildFibers(\n workInProgress,\n null,\n Component,\n renderLanes\n )))\n : reconcileChildren(current, workInProgress, Component, renderLanes),\n (workInProgress.memoizedState = context.state),\n (current = workInProgress.child))\n : (current = bailoutOnAlreadyFinishedWork(\n current,\n workInProgress,\n renderLanes\n ));\n return current;\n}\nfunction mountHostRootWithoutHydrating(\n current,\n workInProgress,\n nextChildren,\n renderLanes\n) {\n resetHydrationState();\n workInProgress.flags |= 256;\n reconcileChildren(current, workInProgress, nextChildren, renderLanes);\n return workInProgress.child;\n}\nvar SUSPENDED_MARKER = {\n dehydrated: null,\n treeContext: null,\n retryLane: 0,\n hydrationErrors: null\n};\nfunction mountSuspenseOffscreenState(renderLanes) {\n return { baseLanes: renderLanes, cachePool: getSuspendedCache() };\n}\nfunction getRemainingWorkInPrimaryTree(\n current,\n primaryTreeDidDefer,\n renderLanes\n) {\n current = null !== current ? current.childLanes & ~renderLanes : 0;\n primaryTreeDidDefer && (current |= workInProgressDeferredLane);\n return current;\n}\nfunction updateSuspenseComponent(current, workInProgress, renderLanes) {\n var nextProps = workInProgress.pendingProps,\n showFallback = !1,\n didSuspend = 0 !== (workInProgress.flags & 128),\n JSCompiler_temp;\n (JSCompiler_temp = didSuspend) ||\n (JSCompiler_temp =\n null !== current && null === current.memoizedState\n ? !1\n : 0 !== (suspenseStackCursor.current & 2));\n JSCompiler_temp && ((showFallback = !0), (workInProgress.flags &= -129));\n JSCompiler_temp = 0 !== (workInProgress.flags & 32);\n workInProgress.flags &= -33;\n if (null === current) {\n if (isHydrating) {\n showFallback\n ? pushPrimaryTreeSuspenseHandler(workInProgress)\n : reuseSuspenseHandlerOnStack(workInProgress);\n if (isHydrating) {\n var nextInstance = nextHydratableInstance,\n JSCompiler_temp$jscomp$0;\n if ((JSCompiler_temp$jscomp$0 = nextInstance)) {\n c: {\n JSCompiler_temp$jscomp$0 = nextInstance;\n for (\n nextInstance = rootOrSingletonContext;\n 8 !== JSCompiler_temp$jscomp$0.nodeType;\n\n ) {\n if (!nextInstance) {\n nextInstance = null;\n break c;\n }\n JSCompiler_temp$jscomp$0 = getNextHydratable(\n JSCompiler_temp$jscomp$0.nextSibling\n );\n if (null === JSCompiler_temp$jscomp$0) {\n nextInstance = null;\n break c;\n }\n }\n nextInstance = JSCompiler_temp$jscomp$0;\n }\n null !== nextInstance\n ? ((workInProgress.memoizedState = {\n dehydrated: nextInstance,\n treeContext:\n null !== treeContextProvider\n ? { id: treeContextId, overflow: treeContextOverflow }\n : null,\n retryLane: 536870912,\n hydrationErrors: null\n }),\n (JSCompiler_temp$jscomp$0 = createFiberImplClass(\n 18,\n null,\n null,\n 0\n )),\n (JSCompiler_temp$jscomp$0.stateNode = nextInstance),\n (JSCompiler_temp$jscomp$0.return = workInProgress),\n (workInProgress.child = JSCompiler_temp$jscomp$0),\n (hydrationParentFiber = workInProgress),\n (nextHydratableInstance = null),\n (JSCompiler_temp$jscomp$0 = !0))\n : (JSCompiler_temp$jscomp$0 = !1);\n }\n JSCompiler_temp$jscomp$0 || throwOnHydrationMismatch(workInProgress);\n }\n nextInstance = workInProgress.memoizedState;\n if (\n null !== nextInstance &&\n ((nextInstance = nextInstance.dehydrated), null !== nextInstance)\n )\n return (\n isSuspenseInstanceFallback(nextInstance)\n ? (workInProgress.lanes = 32)\n : (workInProgress.lanes = 536870912),\n null\n );\n popSuspenseHandler(workInProgress);\n }\n nextInstance = nextProps.children;\n nextProps = nextProps.fallback;\n if (showFallback)\n return (\n reuseSuspenseHandlerOnStack(workInProgress),\n (showFallback = workInProgress.mode),\n (nextInstance = mountWorkInProgressOffscreenFiber(\n { mode: \"hidden\", children: nextInstance },\n showFallback\n )),\n (nextProps = createFiberFromFragment(\n nextProps,\n showFallback,\n renderLanes,\n null\n )),\n (nextInstance.return = workInProgress),\n (nextProps.return = workInProgress),\n (nextInstance.sibling = nextProps),\n (workInProgress.child = nextInstance),\n (showFallback = workInProgress.child),\n (showFallback.memoizedState = mountSuspenseOffscreenState(renderLanes)),\n (showFallback.childLanes = getRemainingWorkInPrimaryTree(\n current,\n JSCompiler_temp,\n renderLanes\n )),\n (workInProgress.memoizedState = SUSPENDED_MARKER),\n nextProps\n );\n pushPrimaryTreeSuspenseHandler(workInProgress);\n return mountSuspensePrimaryChildren(workInProgress, nextInstance);\n }\n JSCompiler_temp$jscomp$0 = current.memoizedState;\n if (\n null !== JSCompiler_temp$jscomp$0 &&\n ((nextInstance = JSCompiler_temp$jscomp$0.dehydrated),\n null !== nextInstance)\n ) {\n if (didSuspend)\n workInProgress.flags & 256\n ? (pushPrimaryTreeSuspenseHandler(workInProgress),\n (workInProgress.flags &= -257),\n (workInProgress = retrySuspenseComponentWithoutHydrating(\n current,\n workInProgress,\n renderLanes\n )))\n : null !== workInProgress.memoizedState\n ? (reuseSuspenseHandlerOnStack(workInProgress),\n (workInProgress.child = current.child),\n (workInProgress.flags |= 128),\n (workInProgress = null))\n : (reuseSuspenseHandlerOnStack(workInProgress),\n (showFallback = nextProps.fallback),\n (nextInstance = workInProgress.mode),\n (nextProps = mountWorkInProgressOffscreenFiber(\n { mode: \"visible\", children: nextProps.children },\n nextInstance\n )),\n (showFallback = createFiberFromFragment(\n showFallback,\n nextInstance,\n renderLanes,\n null\n )),\n (showFallback.flags |= 2),\n (nextProps.return = workInProgress),\n (showFallback.return = workInProgress),\n (nextProps.sibling = showFallback),\n (workInProgress.child = nextProps),\n reconcileChildFibers(\n workInProgress,\n current.child,\n null,\n renderLanes\n ),\n (nextProps = workInProgress.child),\n (nextProps.memoizedState =\n mountSuspenseOffscreenState(renderLanes)),\n (nextProps.childLanes = getRemainingWorkInPrimaryTree(\n current,\n JSCompiler_temp,\n renderLanes\n )),\n (workInProgress.memoizedState = SUSPENDED_MARKER),\n (workInProgress = showFallback));\n else if (\n (pushPrimaryTreeSuspenseHandler(workInProgress),\n isSuspenseInstanceFallback(nextInstance))\n ) {\n JSCompiler_temp =\n nextInstance.nextSibling && nextInstance.nextSibling.dataset;\n if (JSCompiler_temp) var digest = JSCompiler_temp.dgst;\n JSCompiler_temp = digest;\n nextProps = Error(formatProdErrorMessage(419));\n nextProps.stack = \"\";\n nextProps.digest = JSCompiler_temp;\n queueHydrationError({ value: nextProps, source: null, stack: null });\n workInProgress = retrySuspenseComponentWithoutHydrating(\n current,\n workInProgress,\n renderLanes\n );\n } else if (\n (didReceiveUpdate ||\n propagateParentContextChanges(current, workInProgress, renderLanes, !1),\n (JSCompiler_temp = 0 !== (renderLanes & current.childLanes)),\n didReceiveUpdate || JSCompiler_temp)\n ) {\n JSCompiler_temp = workInProgressRoot;\n if (\n null !== JSCompiler_temp &&\n ((nextProps = renderLanes & -renderLanes),\n (nextProps =\n 0 !== (nextProps & 42)\n ? 1\n : getBumpedLaneForHydrationByLane(nextProps)),\n (nextProps =\n 0 !== (nextProps & (JSCompiler_temp.suspendedLanes | renderLanes))\n ? 0\n : nextProps),\n 0 !== nextProps && nextProps !== JSCompiler_temp$jscomp$0.retryLane)\n )\n throw (\n ((JSCompiler_temp$jscomp$0.retryLane = nextProps),\n enqueueConcurrentRenderForLane(current, nextProps),\n scheduleUpdateOnFiber(JSCompiler_temp, current, nextProps),\n SelectiveHydrationException)\n );\n \"$?\" === nextInstance.data || renderDidSuspendDelayIfPossible();\n workInProgress = retrySuspenseComponentWithoutHydrating(\n current,\n workInProgress,\n renderLanes\n );\n } else\n \"$?\" === nextInstance.data\n ? ((workInProgress.flags |= 192),\n (workInProgress.child = current.child),\n (workInProgress = null))\n : ((current = JSCompiler_temp$jscomp$0.treeContext),\n (nextHydratableInstance = getNextHydratable(\n nextInstance.nextSibling\n )),\n (hydrationParentFiber = workInProgress),\n (isHydrating = !0),\n (hydrationErrors = null),\n (rootOrSingletonContext = !1),\n null !== current &&\n ((idStack[idStackIndex++] = treeContextId),\n (idStack[idStackIndex++] = treeContextOverflow),\n (idStack[idStackIndex++] = treeContextProvider),\n (treeContextId = current.id),\n (treeContextOverflow = current.overflow),\n (treeContextProvider = workInProgress)),\n (workInProgress = mountSuspensePrimaryChildren(\n workInProgress,\n nextProps.children\n )),\n (workInProgress.flags |= 4096));\n return workInProgress;\n }\n if (showFallback)\n return (\n reuseSuspenseHandlerOnStack(workInProgress),\n (showFallback = nextProps.fallback),\n (nextInstance = workInProgress.mode),\n (JSCompiler_temp$jscomp$0 = current.child),\n (digest = JSCompiler_temp$jscomp$0.sibling),\n (nextProps = createWorkInProgress(JSCompiler_temp$jscomp$0, {\n mode: \"hidden\",\n children: nextProps.children\n })),\n (nextProps.subtreeFlags =\n JSCompiler_temp$jscomp$0.subtreeFlags & 65011712),\n null !== digest\n ? (showFallback = createWorkInProgress(digest, showFallback))\n : ((showFallback = createFiberFromFragment(\n showFallback,\n nextInstance,\n renderLanes,\n null\n )),\n (showFallback.flags |= 2)),\n (showFallback.return = workInProgress),\n (nextProps.return = workInProgress),\n (nextProps.sibling = showFallback),\n (workInProgress.child = nextProps),\n (nextProps = showFallback),\n (showFallback = workInProgress.child),\n (nextInstance = current.child.memoizedState),\n null === nextInstance\n ? (nextInstance = mountSuspenseOffscreenState(renderLanes))\n : ((JSCompiler_temp$jscomp$0 = nextInstance.cachePool),\n null !== JSCompiler_temp$jscomp$0\n ? ((digest = CacheContext._currentValue),\n (JSCompiler_temp$jscomp$0 =\n JSCompiler_temp$jscomp$0.parent !== digest\n ? { parent: digest, pool: digest }\n : JSCompiler_temp$jscomp$0))\n : (JSCompiler_temp$jscomp$0 = getSuspendedCache()),\n (nextInstance = {\n baseLanes: nextInstance.baseLanes | renderLanes,\n cachePool: JSCompiler_temp$jscomp$0\n })),\n (showFallback.memoizedState = nextInstance),\n (showFallback.childLanes = getRemainingWorkInPrimaryTree(\n current,\n JSCompiler_temp,\n renderLanes\n )),\n (workInProgress.memoizedState = SUSPENDED_MARKER),\n nextProps\n );\n pushPrimaryTreeSuspenseHandler(workInProgress);\n renderLanes = current.child;\n current = renderLanes.sibling;\n renderLanes = createWorkInProgress(renderLanes, {\n mode: \"visible\",\n children: nextProps.children\n });\n renderLanes.return = workInProgress;\n renderLanes.sibling = null;\n null !== current &&\n ((JSCompiler_temp = workInProgress.deletions),\n null === JSCompiler_temp\n ? ((workInProgress.deletions = [current]), (workInProgress.flags |= 16))\n : JSCompiler_temp.push(current));\n workInProgress.child = renderLanes;\n workInProgress.memoizedState = null;\n return renderLanes;\n}\nfunction mountSuspensePrimaryChildren(workInProgress, primaryChildren) {\n primaryChildren = mountWorkInProgressOffscreenFiber(\n { mode: \"visible\", children: primaryChildren },\n workInProgress.mode\n );\n primaryChildren.return = workInProgress;\n return (workInProgress.child = primaryChildren);\n}\nfunction mountWorkInProgressOffscreenFiber(offscreenProps, mode) {\n offscreenProps = createFiberImplClass(22, offscreenProps, null, mode);\n offscreenProps.lanes = 0;\n offscreenProps.stateNode = {\n _visibility: 1,\n _pendingMarkers: null,\n _retryCache: null,\n _transitions: null\n };\n return offscreenProps;\n}\nfunction retrySuspenseComponentWithoutHydrating(\n current,\n workInProgress,\n renderLanes\n) {\n reconcileChildFibers(workInProgress, current.child, null, renderLanes);\n current = mountSuspensePrimaryChildren(\n workInProgress,\n workInProgress.pendingProps.children\n );\n current.flags |= 2;\n workInProgress.memoizedState = null;\n return current;\n}\nfunction scheduleSuspenseWorkOnFiber(fiber, renderLanes, propagationRoot) {\n fiber.lanes |= renderLanes;\n var alternate = fiber.alternate;\n null !== alternate && (alternate.lanes |= renderLanes);\n scheduleContextWorkOnParentPath(fiber.return, renderLanes, propagationRoot);\n}\nfunction initSuspenseListRenderState(\n workInProgress,\n isBackwards,\n tail,\n lastContentRow,\n tailMode\n) {\n var renderState = workInProgress.memoizedState;\n null === renderState\n ? (workInProgress.memoizedState = {\n isBackwards: isBackwards,\n rendering: null,\n renderingStartTime: 0,\n last: lastContentRow,\n tail: tail,\n tailMode: tailMode\n })\n : ((renderState.isBackwards = isBackwards),\n (renderState.rendering = null),\n (renderState.renderingStartTime = 0),\n (renderState.last = lastContentRow),\n (renderState.tail = tail),\n (renderState.tailMode = tailMode));\n}\nfunction updateSuspenseListComponent(current, workInProgress, renderLanes) {\n var nextProps = workInProgress.pendingProps,\n revealOrder = nextProps.revealOrder,\n tailMode = nextProps.tail;\n reconcileChildren(current, workInProgress, nextProps.children, renderLanes);\n nextProps = suspenseStackCursor.current;\n if (0 !== (nextProps & 2))\n (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 128);\n else {\n if (null !== current && 0 !== (current.flags & 128))\n a: for (current = workInProgress.child; null !== current; ) {\n if (13 === current.tag)\n null !== current.memoizedState &&\n scheduleSuspenseWorkOnFiber(current, renderLanes, workInProgress);\n else if (19 === current.tag)\n scheduleSuspenseWorkOnFiber(current, renderLanes, workInProgress);\n else if (null !== current.child) {\n current.child.return = current;\n current = current.child;\n continue;\n }\n if (current === workInProgress) break a;\n for (; null === current.sibling; ) {\n if (null === current.return || current.return === workInProgress)\n break a;\n current = current.return;\n }\n current.sibling.return = current.return;\n current = current.sibling;\n }\n nextProps &= 1;\n }\n push(suspenseStackCursor, nextProps);\n switch (revealOrder) {\n case \"forwards\":\n renderLanes = workInProgress.child;\n for (revealOrder = null; null !== renderLanes; )\n (current = renderLanes.alternate),\n null !== current &&\n null === findFirstSuspended(current) &&\n (revealOrder = renderLanes),\n (renderLanes = renderLanes.sibling);\n renderLanes = revealOrder;\n null === renderLanes\n ? ((revealOrder = workInProgress.child), (workInProgress.child = null))\n : ((revealOrder = renderLanes.sibling), (renderLanes.sibling = null));\n initSuspenseListRenderState(\n workInProgress,\n !1,\n revealOrder,\n renderLanes,\n tailMode\n );\n break;\n case \"backwards\":\n renderLanes = null;\n revealOrder = workInProgress.child;\n for (workInProgress.child = null; null !== revealOrder; ) {\n current = revealOrder.alternate;\n if (null !== current && null === findFirstSuspended(current)) {\n workInProgress.child = revealOrder;\n break;\n }\n current = revealOrder.sibling;\n revealOrder.sibling = renderLanes;\n renderLanes = revealOrder;\n revealOrder = current;\n }\n initSuspenseListRenderState(\n workInProgress,\n !0,\n renderLanes,\n null,\n tailMode\n );\n break;\n case \"together\":\n initSuspenseListRenderState(workInProgress, !1, null, null, void 0);\n break;\n default:\n workInProgress.memoizedState = null;\n }\n return workInProgress.child;\n}\nfunction bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) {\n null !== current && (workInProgress.dependencies = current.dependencies);\n workInProgressRootSkippedLanes |= workInProgress.lanes;\n if (0 === (renderLanes & workInProgress.childLanes))\n if (null !== current) {\n if (\n (propagateParentContextChanges(\n current,\n workInProgress,\n renderLanes,\n !1\n ),\n 0 === (renderLanes & workInProgress.childLanes))\n )\n return null;\n } else return null;\n if (null !== current && workInProgress.child !== current.child)\n throw Error(formatProdErrorMessage(153));\n if (null !== workInProgress.child) {\n current = workInProgress.child;\n renderLanes = createWorkInProgress(current, current.pendingProps);\n workInProgress.child = renderLanes;\n for (renderLanes.return = workInProgress; null !== current.sibling; )\n (current = current.sibling),\n (renderLanes = renderLanes.sibling =\n createWorkInProgress(current, current.pendingProps)),\n (renderLanes.return = workInProgress);\n renderLanes.sibling = null;\n }\n return workInProgress.child;\n}\nfunction checkScheduledUpdateOrContext(current, renderLanes) {\n if (0 !== (current.lanes & renderLanes)) return !0;\n current = current.dependencies;\n return null !== current && checkIfContextChanged(current) ? !0 : !1;\n}\nfunction attemptEarlyBailoutIfNoScheduledUpdate(\n current,\n workInProgress,\n renderLanes\n) {\n switch (workInProgress.tag) {\n case 3:\n pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);\n pushProvider(workInProgress, CacheContext, current.memoizedState.cache);\n resetHydrationState();\n break;\n case 27:\n case 5:\n pushHostContext(workInProgress);\n break;\n case 4:\n pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);\n break;\n case 10:\n pushProvider(\n workInProgress,\n workInProgress.type,\n workInProgress.memoizedProps.value\n );\n break;\n case 13:\n var state = workInProgress.memoizedState;\n if (null !== state) {\n if (null !== state.dehydrated)\n return (\n pushPrimaryTreeSuspenseHandler(workInProgress),\n (workInProgress.flags |= 128),\n null\n );\n if (0 !== (renderLanes & workInProgress.child.childLanes))\n return updateSuspenseComponent(current, workInProgress, renderLanes);\n pushPrimaryTreeSuspenseHandler(workInProgress);\n current = bailoutOnAlreadyFinishedWork(\n current,\n workInProgress,\n renderLanes\n );\n return null !== current ? current.sibling : null;\n }\n pushPrimaryTreeSuspenseHandler(workInProgress);\n break;\n case 19:\n var didSuspendBefore = 0 !== (current.flags & 128);\n state = 0 !== (renderLanes & workInProgress.childLanes);\n state ||\n (propagateParentContextChanges(\n current,\n workInProgress,\n renderLanes,\n !1\n ),\n (state = 0 !== (renderLanes & workInProgress.childLanes)));\n if (didSuspendBefore) {\n if (state)\n return updateSuspenseListComponent(\n current,\n workInProgress,\n renderLanes\n );\n workInProgress.flags |= 128;\n }\n didSuspendBefore = workInProgress.memoizedState;\n null !== didSuspendBefore &&\n ((didSuspendBefore.rendering = null),\n (didSuspendBefore.tail = null),\n (didSuspendBefore.lastEffect = null));\n push(suspenseStackCursor, suspenseStackCursor.current);\n if (state) break;\n else return null;\n case 22:\n case 23:\n return (\n (workInProgress.lanes = 0),\n updateOffscreenComponent(current, workInProgress, renderLanes)\n );\n case 24:\n pushProvider(workInProgress, CacheContext, current.memoizedState.cache);\n }\n return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);\n}\nfunction beginWork(current, workInProgress, renderLanes) {\n if (null !== current)\n if (current.memoizedProps !== workInProgress.pendingProps)\n didReceiveUpdate = !0;\n else {\n if (\n !checkScheduledUpdateOrContext(current, renderLanes) &&\n 0 === (workInProgress.flags & 128)\n )\n return (\n (didReceiveUpdate = !1),\n attemptEarlyBailoutIfNoScheduledUpdate(\n current,\n workInProgress,\n renderLanes\n )\n );\n didReceiveUpdate = 0 !== (current.flags & 131072) ? !0 : !1;\n }\n else\n (didReceiveUpdate = !1),\n isHydrating &&\n 0 !== (workInProgress.flags & 1048576) &&\n pushTreeId(workInProgress, treeForkCount, workInProgress.index);\n workInProgress.lanes = 0;\n switch (workInProgress.tag) {\n case 16:\n a: {\n current = workInProgress.pendingProps;\n var lazyComponent = workInProgress.elementType,\n init = lazyComponent._init;\n lazyComponent = init(lazyComponent._payload);\n workInProgress.type = lazyComponent;\n if (\"function\" === typeof lazyComponent)\n shouldConstruct(lazyComponent)\n ? ((current = resolveClassComponentProps(lazyComponent, current)),\n (workInProgress.tag = 1),\n (workInProgress = updateClassComponent(\n null,\n workInProgress,\n lazyComponent,\n current,\n renderLanes\n )))\n : ((workInProgress.tag = 0),\n (workInProgress = updateFunctionComponent(\n null,\n workInProgress,\n lazyComponent,\n current,\n renderLanes\n )));\n else {\n if (void 0 !== lazyComponent && null !== lazyComponent)\n if (\n ((init = lazyComponent.$$typeof), init === REACT_FORWARD_REF_TYPE)\n ) {\n workInProgress.tag = 11;\n workInProgress = updateForwardRef(\n null,\n workInProgress,\n lazyComponent,\n current,\n renderLanes\n );\n break a;\n } else if (init === REACT_MEMO_TYPE) {\n workInProgress.tag = 14;\n workInProgress = updateMemoComponent(\n null,\n workInProgress,\n lazyComponent,\n current,\n renderLanes\n );\n break a;\n }\n workInProgress =\n getComponentNameFromType(lazyComponent) || lazyComponent;\n throw Error(formatProdErrorMessage(306, workInProgress, \"\"));\n }\n }\n return workInProgress;\n case 0:\n return updateFunctionComponent(\n current,\n workInProgress,\n workInProgress.type,\n workInProgress.pendingProps,\n renderLanes\n );\n case 1:\n return (\n (lazyComponent = workInProgress.type),\n (init = resolveClassComponentProps(\n lazyComponent,\n workInProgress.pendingProps\n )),\n updateClassComponent(\n current,\n workInProgress,\n lazyComponent,\n init,\n renderLanes\n )\n );\n case 3:\n a: {\n pushHostContainer(\n workInProgress,\n workInProgress.stateNode.containerInfo\n );\n if (null === current) throw Error(formatProdErrorMessage(387));\n lazyComponent = workInProgress.pendingProps;\n var prevState = workInProgress.memoizedState;\n init = prevState.element;\n cloneUpdateQueue(current, workInProgress);\n processUpdateQueue(workInProgress, lazyComponent, null, renderLanes);\n var nextState = workInProgress.memoizedState;\n lazyComponent = nextState.cache;\n pushProvider(workInProgress, CacheContext, lazyComponent);\n lazyComponent !== prevState.cache &&\n propagateContextChanges(\n workInProgress,\n [CacheContext],\n renderLanes,\n !0\n );\n suspendIfUpdateReadFromEntangledAsyncAction();\n lazyComponent = nextState.element;\n if (prevState.isDehydrated)\n if (\n ((prevState = {\n element: lazyComponent,\n isDehydrated: !1,\n cache: nextState.cache\n }),\n (workInProgress.updateQueue.baseState = prevState),\n (workInProgress.memoizedState = prevState),\n workInProgress.flags & 256)\n ) {\n workInProgress = mountHostRootWithoutHydrating(\n current,\n workInProgress,\n lazyComponent,\n renderLanes\n );\n break a;\n } else if (lazyComponent !== init) {\n init = createCapturedValueAtFiber(\n Error(formatProdErrorMessage(424)),\n workInProgress\n );\n queueHydrationError(init);\n workInProgress = mountHostRootWithoutHydrating(\n current,\n workInProgress,\n lazyComponent,\n renderLanes\n );\n break a;\n } else {\n current = workInProgress.stateNode.containerInfo;\n switch (current.nodeType) {\n case 9:\n current = current.body;\n break;\n default:\n current =\n \"HTML\" === current.nodeName\n ? current.ownerDocument.body\n : current;\n }\n nextHydratableInstance = getNextHydratable(current.firstChild);\n hydrationParentFiber = workInProgress;\n isHydrating = !0;\n hydrationErrors = null;\n rootOrSingletonContext = !0;\n renderLanes = mountChildFibers(\n workInProgress,\n null,\n lazyComponent,\n renderLanes\n );\n for (workInProgress.child = renderLanes; renderLanes; )\n (renderLanes.flags = (renderLanes.flags & -3) | 4096),\n (renderLanes = renderLanes.sibling);\n }\n else {\n resetHydrationState();\n if (lazyComponent === init) {\n workInProgress = bailoutOnAlreadyFinishedWork(\n current,\n workInProgress,\n renderLanes\n );\n break a;\n }\n reconcileChildren(\n current,\n workInProgress,\n lazyComponent,\n renderLanes\n );\n }\n workInProgress = workInProgress.child;\n }\n return workInProgress;\n case 26:\n return (\n markRef(current, workInProgress),\n null === current\n ? (renderLanes = getResource(\n workInProgress.type,\n null,\n workInProgress.pendingProps,\n null\n ))\n ? (workInProgress.memoizedState = renderLanes)\n : isHydrating ||\n ((renderLanes = workInProgress.type),\n (current = workInProgress.pendingProps),\n (lazyComponent = getOwnerDocumentFromRootContainer(\n rootInstanceStackCursor.current\n ).createElement(renderLanes)),\n (lazyComponent[internalInstanceKey] = workInProgress),\n (lazyComponent[internalPropsKey] = current),\n setInitialProperties(lazyComponent, renderLanes, current),\n markNodeAsHoistable(lazyComponent),\n (workInProgress.stateNode = lazyComponent))\n : (workInProgress.memoizedState = getResource(\n workInProgress.type,\n current.memoizedProps,\n workInProgress.pendingProps,\n current.memoizedState\n )),\n null\n );\n case 27:\n return (\n pushHostContext(workInProgress),\n null === current &&\n isHydrating &&\n ((lazyComponent = workInProgress.stateNode =\n resolveSingletonInstance(\n workInProgress.type,\n workInProgress.pendingProps,\n rootInstanceStackCursor.current\n )),\n (hydrationParentFiber = workInProgress),\n (rootOrSingletonContext = !0),\n (init = nextHydratableInstance),\n isSingletonScope(workInProgress.type)\n ? ((previousHydratableOnEnteringScopedSingleton = init),\n (nextHydratableInstance = getNextHydratable(\n lazyComponent.firstChild\n )))\n : (nextHydratableInstance = init)),\n reconcileChildren(\n current,\n workInProgress,\n workInProgress.pendingProps.children,\n renderLanes\n ),\n markRef(current, workInProgress),\n null === current && (workInProgress.flags |= 4194304),\n workInProgress.child\n );\n case 5:\n if (null === current && isHydrating) {\n if ((init = lazyComponent = nextHydratableInstance))\n (lazyComponent = canHydrateInstance(\n lazyComponent,\n workInProgress.type,\n workInProgress.pendingProps,\n rootOrSingletonContext\n )),\n null !== lazyComponent\n ? ((workInProgress.stateNode = lazyComponent),\n (hydrationParentFiber = workInProgress),\n (nextHydratableInstance = getNextHydratable(\n lazyComponent.firstChild\n )),\n (rootOrSingletonContext = !1),\n (init = !0))\n : (init = !1);\n init || throwOnHydrationMismatch(workInProgress);\n }\n pushHostContext(workInProgress);\n init = workInProgress.type;\n prevState = workInProgress.pendingProps;\n nextState = null !== current ? current.memoizedProps : null;\n lazyComponent = prevState.children;\n shouldSetTextContent(init, prevState)\n ? (lazyComponent = null)\n : null !== nextState &&\n shouldSetTextContent(init, nextState) &&\n (workInProgress.flags |= 32);\n null !== workInProgress.memoizedState &&\n ((init = renderWithHooks(\n current,\n workInProgress,\n TransitionAwareHostComponent,\n null,\n null,\n renderLanes\n )),\n (HostTransitionContext._currentValue = init));\n markRef(current, workInProgress);\n reconcileChildren(current, workInProgress, lazyComponent, renderLanes);\n return workInProgress.child;\n case 6:\n if (null === current && isHydrating) {\n if ((current = renderLanes = nextHydratableInstance))\n (renderLanes = canHydrateTextInstance(\n renderLanes,\n workInProgress.pendingProps,\n rootOrSingletonContext\n )),\n null !== renderLanes\n ? ((workInProgress.stateNode = renderLanes),\n (hydrationParentFiber = workInProgress),\n (nextHydratableInstance = null),\n (current = !0))\n : (current = !1);\n current || throwOnHydrationMismatch(workInProgress);\n }\n return null;\n case 13:\n return updateSuspenseComponent(current, workInProgress, renderLanes);\n case 4:\n return (\n pushHostContainer(\n workInProgress,\n workInProgress.stateNode.containerInfo\n ),\n (lazyComponent = workInProgress.pendingProps),\n null === current\n ? (workInProgress.child = reconcileChildFibers(\n workInProgress,\n null,\n lazyComponent,\n renderLanes\n ))\n : reconcileChildren(\n current,\n workInProgress,\n lazyComponent,\n renderLanes\n ),\n workInProgress.child\n );\n case 11:\n return updateForwardRef(\n current,\n workInProgress,\n workInProgress.type,\n workInProgress.pendingProps,\n renderLanes\n );\n case 7:\n return (\n reconcileChildren(\n current,\n workInProgress,\n workInProgress.pendingProps,\n renderLanes\n ),\n workInProgress.child\n );\n case 8:\n return (\n reconcileChildren(\n current,\n workInProgress,\n workInProgress.pendingProps.children,\n renderLanes\n ),\n workInProgress.child\n );\n case 12:\n return (\n reconcileChildren(\n current,\n workInProgress,\n workInProgress.pendingProps.children,\n renderLanes\n ),\n workInProgress.child\n );\n case 10:\n return (\n (lazyComponent = workInProgress.pendingProps),\n pushProvider(workInProgress, workInProgress.type, lazyComponent.value),\n reconcileChildren(\n current,\n workInProgress,\n lazyComponent.children,\n renderLanes\n ),\n workInProgress.child\n );\n case 9:\n return (\n (init = workInProgress.type._context),\n (lazyComponent = workInProgress.pendingProps.children),\n prepareToReadContext(workInProgress),\n (init = readContext(init)),\n (lazyComponent = lazyComponent(init)),\n (workInProgress.flags |= 1),\n reconcileChildren(current, workInProgress, lazyComponent, renderLanes),\n workInProgress.child\n );\n case 14:\n return updateMemoComponent(\n current,\n workInProgress,\n workInProgress.type,\n workInProgress.pendingProps,\n renderLanes\n );\n case 15:\n return updateSimpleMemoComponent(\n current,\n workInProgress,\n workInProgress.type,\n workInProgress.pendingProps,\n renderLanes\n );\n case 19:\n return updateSuspenseListComponent(current, workInProgress, renderLanes);\n case 31:\n return (\n (lazyComponent = workInProgress.pendingProps),\n (renderLanes = workInProgress.mode),\n (lazyComponent = {\n mode: lazyComponent.mode,\n children: lazyComponent.children\n }),\n null === current\n ? ((renderLanes = mountWorkInProgressOffscreenFiber(\n lazyComponent,\n renderLanes\n )),\n (renderLanes.ref = workInProgress.ref),\n (workInProgress.child = renderLanes),\n (renderLanes.return = workInProgress),\n (workInProgress = renderLanes))\n : ((renderLanes = createWorkInProgress(current.child, lazyComponent)),\n (renderLanes.ref = workInProgress.ref),\n (workInProgress.child = renderLanes),\n (renderLanes.return = workInProgress),\n (workInProgress = renderLanes)),\n workInProgress\n );\n case 22:\n return updateOffscreenComponent(current, workInProgress, renderLanes);\n case 24:\n return (\n prepareToReadContext(workInProgress),\n (lazyComponent = readContext(CacheContext)),\n null === current\n ? ((init = peekCacheFromPool()),\n null === init &&\n ((init = workInProgressRoot),\n (prevState = createCache()),\n (init.pooledCache = prevState),\n prevState.refCount++,\n null !== prevState && (init.pooledCacheLanes |= renderLanes),\n (init = prevState)),\n (workInProgress.memoizedState = {\n parent: lazyComponent,\n cache: init\n }),\n initializeUpdateQueue(workInProgress),\n pushProvider(workInProgress, CacheContext, init))\n : (0 !== (current.lanes & renderLanes) &&\n (cloneUpdateQueue(current, workInProgress),\n processUpdateQueue(workInProgress, null, null, renderLanes),\n suspendIfUpdateReadFromEntangledAsyncAction()),\n (init = current.memoizedState),\n (prevState = workInProgress.memoizedState),\n init.parent !== lazyComponent\n ? ((init = { parent: lazyComponent, cache: lazyComponent }),\n (workInProgress.memoizedState = init),\n 0 === workInProgress.lanes &&\n (workInProgress.memoizedState =\n workInProgress.updateQueue.baseState =\n init),\n pushProvider(workInProgress, CacheContext, lazyComponent))\n : ((lazyComponent = prevState.cache),\n pushProvider(workInProgress, CacheContext, lazyComponent),\n lazyComponent !== init.cache &&\n propagateContextChanges(\n workInProgress,\n [CacheContext],\n renderLanes,\n !0\n ))),\n reconcileChildren(\n current,\n workInProgress,\n workInProgress.pendingProps.children,\n renderLanes\n ),\n workInProgress.child\n );\n case 29:\n throw workInProgress.pendingProps;\n }\n throw Error(formatProdErrorMessage(156, workInProgress.tag));\n}\nfunction markUpdate(workInProgress) {\n workInProgress.flags |= 4;\n}\nfunction preloadResourceAndSuspendIfNeeded(workInProgress, resource) {\n if (\"stylesheet\" !== resource.type || 0 !== (resource.state.loading & 4))\n workInProgress.flags &= -16777217;\n else if (((workInProgress.flags |= 16777216), !preloadResource(resource))) {\n resource = suspenseHandlerStackCursor.current;\n if (\n null !== resource &&\n ((workInProgressRootRenderLanes & 4194048) ===\n workInProgressRootRenderLanes\n ? null !== shellBoundary\n : ((workInProgressRootRenderLanes & 62914560) !==\n workInProgressRootRenderLanes &&\n 0 === (workInProgressRootRenderLanes & 536870912)) ||\n resource !== shellBoundary)\n )\n throw (\n ((suspendedThenable = noopSuspenseyCommitThenable),\n SuspenseyCommitException)\n );\n workInProgress.flags |= 8192;\n }\n}\nfunction scheduleRetryEffect(workInProgress, retryQueue) {\n null !== retryQueue && (workInProgress.flags |= 4);\n workInProgress.flags & 16384 &&\n ((retryQueue =\n 22 !== workInProgress.tag ? claimNextRetryLane() : 536870912),\n (workInProgress.lanes |= retryQueue),\n (workInProgressSuspendedRetryLanes |= retryQueue));\n}\nfunction cutOffTailIfNeeded(renderState, hasRenderedATailFallback) {\n if (!isHydrating)\n switch (renderState.tailMode) {\n case \"hidden\":\n hasRenderedATailFallback = renderState.tail;\n for (var lastTailNode = null; null !== hasRenderedATailFallback; )\n null !== hasRenderedATailFallback.alternate &&\n (lastTailNode = hasRenderedATailFallback),\n (hasRenderedATailFallback = hasRenderedATailFallback.sibling);\n null === lastTailNode\n ? (renderState.tail = null)\n : (lastTailNode.sibling = null);\n break;\n case \"collapsed\":\n lastTailNode = renderState.tail;\n for (var lastTailNode$113 = null; null !== lastTailNode; )\n null !== lastTailNode.alternate && (lastTailNode$113 = lastTailNode),\n (lastTailNode = lastTailNode.sibling);\n null === lastTailNode$113\n ? hasRenderedATailFallback || null === renderState.tail\n ? (renderState.tail = null)\n : (renderState.tail.sibling = null)\n : (lastTailNode$113.sibling = null);\n }\n}\nfunction bubbleProperties(completedWork) {\n var didBailout =\n null !== completedWork.alternate &&\n completedWork.alternate.child === completedWork.child,\n newChildLanes = 0,\n subtreeFlags = 0;\n if (didBailout)\n for (var child$114 = completedWork.child; null !== child$114; )\n (newChildLanes |= child$114.lanes | child$114.childLanes),\n (subtreeFlags |= child$114.subtreeFlags & 65011712),\n (subtreeFlags |= child$114.flags & 65011712),\n (child$114.return = completedWork),\n (child$114 = child$114.sibling);\n else\n for (child$114 = completedWork.child; null !== child$114; )\n (newChildLanes |= child$114.lanes | child$114.childLanes),\n (subtreeFlags |= child$114.subtreeFlags),\n (subtreeFlags |= child$114.flags),\n (child$114.return = completedWork),\n (child$114 = child$114.sibling);\n completedWork.subtreeFlags |= subtreeFlags;\n completedWork.childLanes = newChildLanes;\n return didBailout;\n}\nfunction completeWork(current, workInProgress, renderLanes) {\n var newProps = workInProgress.pendingProps;\n popTreeContext(workInProgress);\n switch (workInProgress.tag) {\n case 31:\n case 16:\n case 15:\n case 0:\n case 11:\n case 7:\n case 8:\n case 12:\n case 9:\n case 14:\n return bubbleProperties(workInProgress), null;\n case 1:\n return bubbleProperties(workInProgress), null;\n case 3:\n renderLanes = workInProgress.stateNode;\n newProps = null;\n null !== current && (newProps = current.memoizedState.cache);\n workInProgress.memoizedState.cache !== newProps &&\n (workInProgress.flags |= 2048);\n popProvider(CacheContext);\n popHostContainer();\n renderLanes.pendingContext &&\n ((renderLanes.context = renderLanes.pendingContext),\n (renderLanes.pendingContext = null));\n if (null === current || null === current.child)\n popHydrationState(workInProgress)\n ? markUpdate(workInProgress)\n : null === current ||\n (current.memoizedState.isDehydrated &&\n 0 === (workInProgress.flags & 256)) ||\n ((workInProgress.flags |= 1024),\n upgradeHydrationErrorsToRecoverable());\n bubbleProperties(workInProgress);\n return null;\n case 26:\n return (\n (renderLanes = workInProgress.memoizedState),\n null === current\n ? (markUpdate(workInProgress),\n null !== renderLanes\n ? (bubbleProperties(workInProgress),\n preloadResourceAndSuspendIfNeeded(workInProgress, renderLanes))\n : (bubbleProperties(workInProgress),\n (workInProgress.flags &= -16777217)))\n : renderLanes\n ? renderLanes !== current.memoizedState\n ? (markUpdate(workInProgress),\n bubbleProperties(workInProgress),\n preloadResourceAndSuspendIfNeeded(workInProgress, renderLanes))\n : (bubbleProperties(workInProgress),\n (workInProgress.flags &= -16777217))\n : (current.memoizedProps !== newProps && markUpdate(workInProgress),\n bubbleProperties(workInProgress),\n (workInProgress.flags &= -16777217)),\n null\n );\n case 27:\n popHostContext(workInProgress);\n renderLanes = rootInstanceStackCursor.current;\n var type = workInProgress.type;\n if (null !== current && null != workInProgress.stateNode)\n current.memoizedProps !== newProps && markUpdate(workInProgress);\n else {\n if (!newProps) {\n if (null === workInProgress.stateNode)\n throw Error(formatProdErrorMessage(166));\n bubbleProperties(workInProgress);\n return null;\n }\n current = contextStackCursor.current;\n popHydrationState(workInProgress)\n ? prepareToHydrateHostInstance(workInProgress, current)\n : ((current = resolveSingletonInstance(type, newProps, renderLanes)),\n (workInProgress.stateNode = current),\n markUpdate(workInProgress));\n }\n bubbleProperties(workInProgress);\n return null;\n case 5:\n popHostContext(workInProgress);\n renderLanes = workInProgress.type;\n if (null !== current && null != workInProgress.stateNode)\n current.memoizedProps !== newProps && markUpdate(workInProgress);\n else {\n if (!newProps) {\n if (null === workInProgress.stateNode)\n throw Error(formatProdErrorMessage(166));\n bubbleProperties(workInProgress);\n return null;\n }\n current = contextStackCursor.current;\n if (popHydrationState(workInProgress))\n prepareToHydrateHostInstance(workInProgress, current);\n else {\n type = getOwnerDocumentFromRootContainer(\n rootInstanceStackCursor.current\n );\n switch (current) {\n case 1:\n current = type.createElementNS(\n \"http://www.w3.org/2000/svg\",\n renderLanes\n );\n break;\n case 2:\n current = type.createElementNS(\n \"http://www.w3.org/1998/Math/MathML\",\n renderLanes\n );\n break;\n default:\n switch (renderLanes) {\n case \"svg\":\n current = type.createElementNS(\n \"http://www.w3.org/2000/svg\",\n renderLanes\n );\n break;\n case \"math\":\n current = type.createElementNS(\n \"http://www.w3.org/1998/Math/MathML\",\n renderLanes\n );\n break;\n case \"script\":\n current = type.createElement(\"div\");\n current.innerHTML = \" + From d20f83e8d7170e2677154a91123955aa1c6693bb Mon Sep 17 00:00:00 2001 From: Dylan Huang Date: Thu, 28 Aug 2025 22:32:21 -0700 Subject: [PATCH 13/18] fix --- eval_protocol/pytest/evaluation_test.py | 2 +- .../pytest/generate_parameter_combinations.py | 4 +-- eval_protocol/pytest/parameterize.py | 2 +- tests/pytest/test_pydantic_agent.py | 3 +- ..._pytest_assertion_error_no_new_rollouts.py | 28 ++++++++++++------- 5 files changed, 23 insertions(+), 16 deletions(-) diff --git a/eval_protocol/pytest/evaluation_test.py b/eval_protocol/pytest/evaluation_test.py index 8d32ed2c..753aebb9 100644 --- a/eval_protocol/pytest/evaluation_test.py +++ b/eval_protocol/pytest/evaluation_test.py @@ -63,7 +63,7 @@ def evaluation_test( *, completion_params: Sequence[CompletionParams | None] | None = None, input_messages: Sequence[InputMessagesParam | None] | None = None, - input_dataset: list[DatasetPathParam] | None = None, + input_dataset: Sequence[DatasetPathParam] | None = None, input_rows: Sequence[list[EvaluationRow]] | None = None, dataset_adapter: Callable[[list[dict[str, Any]]], Dataset] = default_dataset_adapter, # pyright: ignore[reportExplicitAny] rollout_processor: RolloutProcessor | None = None, diff --git a/eval_protocol/pytest/generate_parameter_combinations.py b/eval_protocol/pytest/generate_parameter_combinations.py index 53ee7a78..e6c172af 100644 --- a/eval_protocol/pytest/generate_parameter_combinations.py +++ b/eval_protocol/pytest/generate_parameter_combinations.py @@ -45,7 +45,7 @@ class ParameterizedTestKwargs(TypedDict): def generate_parameter_combinations( - input_dataset: list[DatasetPathParam] | None, + input_dataset: Sequence[DatasetPathParam] | None, completion_params: Sequence[CompletionParams | None], input_messages: Sequence[InputMessagesParam | None] | None, input_rows: Sequence[list[EvaluationRow] | None] | None, @@ -73,7 +73,7 @@ def generate_parameter_combinations( datasets: Sequence[list[DatasetPathParam] | None] = [None] if input_dataset is not None: if combine_datasets: - datasets = [input_dataset] + datasets = [list(input_dataset)] else: # Fan out: one dataset path per parameterization datasets = [[p] for p in input_dataset] diff --git a/eval_protocol/pytest/parameterize.py b/eval_protocol/pytest/parameterize.py index 5815abd4..3b0806d2 100644 --- a/eval_protocol/pytest/parameterize.py +++ b/eval_protocol/pytest/parameterize.py @@ -16,7 +16,7 @@ class PytestParametrizeArgs(TypedDict): def pytest_parametrize( combinations: list[CombinationTuple], - input_dataset: list[DatasetPathParam] | None, + input_dataset: Sequence[DatasetPathParam] | None, completion_params: Sequence[CompletionParams | None] | None, input_messages: Sequence[InputMessagesParam | None] | None, input_rows: Sequence[list[EvaluationRow]] | None, diff --git a/tests/pytest/test_pydantic_agent.py b/tests/pytest/test_pydantic_agent.py index bea37b6e..2c777f5e 100644 --- a/tests/pytest/test_pydantic_agent.py +++ b/tests/pytest/test_pydantic_agent.py @@ -1,4 +1,3 @@ -import os import pytest from eval_protocol.models import EvaluationRow, Message @@ -12,7 +11,7 @@ @pytest.mark.asyncio @evaluation_test( - input_messages=[Message(role="user", content="Hello, how are you?")], + input_messages=[[Message(role="user", content="Hello, how are you?")]], completion_params=[ {"model": "accounts/fireworks/models/gpt-oss-120b", "provider": "fireworks"}, ], diff --git a/tests/pytest/test_pytest_assertion_error_no_new_rollouts.py b/tests/pytest/test_pytest_assertion_error_no_new_rollouts.py index 74b6ab72..1ecf4240 100644 --- a/tests/pytest/test_pytest_assertion_error_no_new_rollouts.py +++ b/tests/pytest/test_pytest_assertion_error_no_new_rollouts.py @@ -1,5 +1,6 @@ -from typing import List, Set import asyncio +from typing import Any +from typing_extensions import override from eval_protocol.dataset_logger.dataset_logger import DatasetLogger from eval_protocol.models import EvaluationRow @@ -11,14 +12,17 @@ class TrackingRolloutProcessor(RolloutProcessor): """Custom rollout processor that tracks which rollout IDs are generated during rollout phase.""" - def __init__(self, shared_rollout_ids: Set[str]): - self.shared_rollout_ids = shared_rollout_ids + def __init__(self, shared_rollout_ids: set[str]): + self.shared_rollout_ids: set[str] = shared_rollout_ids - def __call__(self, rows: List[EvaluationRow], config: RolloutProcessorConfig) -> List[asyncio.Task[EvaluationRow]]: + @override + def __call__(self, rows: list[EvaluationRow], config: RolloutProcessorConfig) -> list[asyncio.Task[EvaluationRow]]: """Process rows and track rollout IDs generated during rollout phase.""" async def process_row(row: EvaluationRow) -> EvaluationRow: # Track this rollout ID as being generated during rollout phase + if row.execution_metadata.rollout_id is None: + raise ValueError("Rollout ID is None") self.shared_rollout_ids.add(row.execution_metadata.rollout_id) return row @@ -30,13 +34,17 @@ async def process_row(row: EvaluationRow) -> EvaluationRow: class TrackingLogger(DatasetLogger): """Custom logger that tracks all rollout IDs that are logged.""" - def __init__(self, shared_rollout_ids: Set[str]): - self.shared_rollout_ids = shared_rollout_ids + def __init__(self, shared_rollout_ids: set[str]): + self.shared_rollout_ids: set[str] = shared_rollout_ids + @override def log(self, row: EvaluationRow): + if row.execution_metadata.rollout_id is None: + raise ValueError("Rollout ID is None") self.shared_rollout_ids.add(row.execution_metadata.rollout_id) - def read(self): + @override + def read(self, row_id: str | None = None) -> list[EvaluationRow]: return [] @@ -48,7 +56,7 @@ async def test_assertion_error_no_new_rollouts(): from eval_protocol.pytest.evaluation_test import evaluation_test # Create shared set to track rollout IDs generated during rollout phase - shared_rollout_ids: Set[str] = set() + shared_rollout_ids: set[str] = set() # Create custom processor and logger for tracking with shared set rollout_processor = TrackingRolloutProcessor(shared_rollout_ids) @@ -57,7 +65,7 @@ async def test_assertion_error_no_new_rollouts(): input_dataset: list[str] = [ "tests/pytest/data/markdown_dataset.jsonl", ] - completion_params: list[dict] = [{"temperature": 0.0, "model": "dummy/local-model"}] + completion_params: list[dict[str, Any]] = [{"temperature": 0.0, "model": "dummy/local-model"}] # pyright: ignore[reportExplicitAny] @evaluation_test( input_dataset=input_dataset, @@ -81,7 +89,7 @@ def eval_fn(row: EvaluationRow) -> EvaluationRow: # This should fail due to threshold not being met for ds_path in input_dataset: for completion_param in completion_params: - await eval_fn(dataset_path=ds_path, completion_params=completion_param) + await eval_fn(dataset_path=[ds_path], completion_params=completion_param) # pyright: ignore[reportCallIssue] except AssertionError: # Expected - the threshold check should fail pass From 2f2bf26d6c59eb757af0389e4ec015d409237a2d Mon Sep 17 00:00:00 2001 From: Dylan Huang Date: Fri, 29 Aug 2025 10:43:10 -0700 Subject: [PATCH 14/18] fix test_math_dataset --- eval_protocol/pytest/evaluation_test.py | 6 ++++-- eval_protocol/pytest/execution.py | 14 ++++++++------ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/eval_protocol/pytest/evaluation_test.py b/eval_protocol/pytest/evaluation_test.py index 753aebb9..39185e63 100644 --- a/eval_protocol/pytest/evaluation_test.py +++ b/eval_protocol/pytest/evaluation_test.py @@ -322,10 +322,11 @@ async def _execute_pointwise_eval_with_semaphore( row: EvaluationRow, ) -> EvaluationRow: async with semaphore: + evaluation_test_kwargs = kwargs.get("evaluation_test_kwargs") or {} result = await execute_pytest( test_func, processed_row=row, - evaluation_test_kwargs=kwargs.get("evaluation_test_kwargs") or {}, + evaluation_test_kwargs=evaluation_test_kwargs, ) if not isinstance(result, EvaluationRow): raise ValueError( @@ -337,10 +338,11 @@ async def _execute_groupwise_eval_with_semaphore( rows: list[EvaluationRow], ) -> list[EvaluationRow]: async with semaphore: + evaluation_test_kwargs = kwargs.get("evaluation_test_kwargs") or {} results = await execute_pytest( test_func, processed_dataset=rows, - evaluation_test_kwargs=kwargs.get("evaluation_test_kwargs") or {}, + evaluation_test_kwargs=evaluation_test_kwargs, ) if not isinstance(results, list): raise ValueError( diff --git a/eval_protocol/pytest/execution.py b/eval_protocol/pytest/execution.py index 40ff3d31..fa572ee0 100644 --- a/eval_protocol/pytest/execution.py +++ b/eval_protocol/pytest/execution.py @@ -19,23 +19,25 @@ async def execute_pytest( raise ValueError("'row' is a reserved parameter for the evaluation function") if "rows" in evaluation_test_kwargs: raise ValueError("'rows' is a reserved parameter for the evaluation function") + else: + evaluation_test_kwargs = {} # Handle both sync and async test functions if asyncio.iscoroutinefunction(test_func): if processed_row is not None: test_func = cast(Callable[[EvaluationRow], Awaitable[EvaluationRow]], test_func) - return await test_func(processed_row) + return await test_func(processed_row, **evaluation_test_kwargs) if processed_dataset is not None: test_func = cast(Callable[[list[EvaluationRow]], Awaitable[list[EvaluationRow]]], test_func) - return await test_func(processed_dataset) + return await test_func(processed_dataset, **evaluation_test_kwargs) test_func = cast(Callable[[], Awaitable[EvaluationRow]], test_func) - return await test_func() + return await test_func(**evaluation_test_kwargs) else: if processed_row is not None: test_func = cast(Callable[[EvaluationRow], EvaluationRow], test_func) - return test_func(processed_row) + return test_func(processed_row, **evaluation_test_kwargs) if processed_dataset is not None: test_func = cast(Callable[[Dataset], Dataset], test_func) - return test_func(processed_dataset) + return test_func(processed_dataset, **evaluation_test_kwargs) test_func = cast(Callable[[], EvaluationRow], test_func) - return test_func() + return test_func(**evaluation_test_kwargs) From 67b40d7f4638d489c21dfad5f90909c76dd8924c Mon Sep 17 00:00:00 2001 From: Dylan Huang Date: Fri, 29 Aug 2025 11:08:32 -0700 Subject: [PATCH 15/18] fix test_pytest_tools_are_added_to_row --- tests/pytest/test_pytest_mcp_config.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/tests/pytest/test_pytest_mcp_config.py b/tests/pytest/test_pytest_mcp_config.py index ec72a811..efcdf11d 100644 --- a/tests/pytest/test_pytest_mcp_config.py +++ b/tests/pytest/test_pytest_mcp_config.py @@ -1,3 +1,4 @@ +from typing_extensions import override import pytest from eval_protocol.dataset_logger.dataset_logger import DatasetLogger from eval_protocol.models import EvaluateResult, EvaluationRow, Message @@ -48,12 +49,16 @@ class TrackingLogger(DatasetLogger): """Custom logger that ensures that the final row is in an error state.""" def __init__(self, rollouts: dict[str, EvaluationRow]): - self.rollouts = rollouts + self.rollouts: dict[str, EvaluationRow] = rollouts + @override def log(self, row: EvaluationRow): + if row.execution_metadata.rollout_id is None: + raise ValueError("Rollout ID is None") self.rollouts[row.execution_metadata.rollout_id] = row - def read(self): + @override + def read(self, row_id: str | None = None) -> list[EvaluationRow]: return [] input_messages = [ @@ -82,11 +87,13 @@ def read(self): def eval_fn(row: EvaluationRow) -> EvaluationRow: return row - await eval_fn(input_messages=input_messages, completion_params=completion_params_list[0]) + await eval_fn(input_messages=input_messages[0], completion_params=completion_params_list[0]) # pyright: ignore[reportCallIssue] # ensure that the row has tools that were set during AgentRolloutProcessor assert len(rollouts) == 1 row = list(rollouts.values())[0] - assert sorted([tool["function"].name for tool in row.tools]) == sorted( + if row.tools is None: + raise ValueError("Row has no tools") + assert sorted([tool["function"].name for tool in row.tools]) == sorted( # pyright: ignore[reportAny] ["list_servers", "get_channels", "read_messages"] ) From d330ee0a1a9c00b9616beef66b0acbf2adb81fc4 Mon Sep 17 00:00:00 2001 From: Dylan Huang Date: Fri, 29 Aug 2025 11:11:46 -0700 Subject: [PATCH 16/18] fix test_pytest_propagate_error --- tests/pytest/test_pytest_propagate_error.py | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/tests/pytest/test_pytest_propagate_error.py b/tests/pytest/test_pytest_propagate_error.py index 83797a1f..95e390ea 100644 --- a/tests/pytest/test_pytest_propagate_error.py +++ b/tests/pytest/test_pytest_propagate_error.py @@ -1,19 +1,23 @@ -from typing import Set +from typing_extensions import override from eval_protocol.models import EvaluationRow, Message from eval_protocol.pytest.default_agent_rollout_processor import AgentRolloutProcessor -from eval_protocol.dataset_logger import DatasetLogger +from eval_protocol.dataset_logger.dataset_logger import DatasetLogger class TrackingLogger(DatasetLogger): """Custom logger that ensures that the final row is in an error state.""" def __init__(self, rollouts: dict[str, EvaluationRow]): - self.rollouts = rollouts + self.rollouts: dict[str, EvaluationRow] = rollouts + @override def log(self, row: EvaluationRow): + if row.execution_metadata.rollout_id is None: + raise ValueError("Rollout ID is None") self.rollouts[row.execution_metadata.rollout_id] = row - def read(self): + @override + def read(self, row_id: str | None = None) -> list[EvaluationRow]: return [] @@ -56,11 +60,16 @@ def eval_fn(row: EvaluationRow) -> EvaluationRow: # Manually invoke all parameter combinations within a single test for params in completion_params_list: - await eval_fn(input_messages=input_messages, completion_params=params) + await eval_fn(input_messages=input_messages[0], completion_params=params) # pyright: ignore[reportCallIssue] # assert that the status of eval_metadata.status is "error" assert len(rollouts) == 5 - assert all(row.eval_metadata.status.is_error() for row in rollouts.values()) + for row in rollouts.values(): + if row.eval_metadata is None: + raise ValueError("Row has no eval_metadata") + if row.eval_metadata.status is None: + raise ValueError("Eval metadata has no status") + assert row.eval_metadata.status.is_error() # make sure the error message includes details of the error assert all("HTTPStatusError" in row.rollout_status.message for row in rollouts.values()) From 6f69941064b2405bd703dfe7f70076688a2b00d3 Mon Sep 17 00:00:00 2001 From: Dylan Huang Date: Fri, 29 Aug 2025 12:54:32 -0700 Subject: [PATCH 17/18] fix input_message data type --- eval_protocol/benchmarks/test_gpqa.py | 13 ++-- .../test_livebench_data_analysis.py | 4 +- eval_protocol/pytest/evaluation_test.py | 4 +- .../pytest/generate_parameter_combinations.py | 12 ++-- eval_protocol/pytest/parameterize.py | 2 +- eval_protocol/pytest/rollout_processor.py | 3 +- examples/healthbench/tests/test_evaluation.py | 13 ++-- tests/chinook/test_pydantic_chinook.py | 2 +- tests/pytest/test_get_metadata.py | 12 ++-- tests/pytest/test_pydantic_agent.py | 2 +- tests/pytest/test_pydantic_multi_agent.py | 2 +- tests/pytest/test_pytest_async.py | 12 ++-- ..._pytest_default_agent_rollout_processor.py | 14 ++-- tests/pytest/test_pytest_flaky_sometimes.py | 2 +- tests/pytest/test_pytest_groupwise.py | 4 +- tests/pytest/test_pytest_input_messages.py | 4 +- tests/pytest/test_pytest_mcp_config.py | 22 ++++--- tests/pytest/test_pytest_mcp_url.py | 22 ++++--- tests/pytest/test_pytest_propagate_error.py | 2 +- tests/test_retry_mechanism.py | 65 ++++++++++--------- 20 files changed, 119 insertions(+), 97 deletions(-) diff --git a/eval_protocol/benchmarks/test_gpqa.py b/eval_protocol/benchmarks/test_gpqa.py index af4a3c56..2cbda574 100644 --- a/eval_protocol/benchmarks/test_gpqa.py +++ b/eval_protocol/benchmarks/test_gpqa.py @@ -2,7 +2,6 @@ import csv import io import re -from typing import List import requests @@ -20,12 +19,12 @@ ) -def _load_gpqa_messages_from_csv() -> List[List[Message]]: +def _load_gpqa_messages_from_csv() -> list[list[list[Message]]]: url = "https://openaipublic.blob.core.windows.net/simple-evals/gpqa_diamond.csv" resp = requests.get(url, timeout=60) resp.raise_for_status() - messages_list: List[List[Message]] = [] + messages_list: list[list[Message]] = [] reader = csv.DictReader(io.StringIO(resp.text)) for ex in reader: q = str(ex.get("Question", "")) @@ -45,7 +44,7 @@ def _load_gpqa_messages_from_csv() -> List[List[Message]]: ) if not messages_list: raise RuntimeError("Failed to load GPQA messages: no rows found from source") - return messages_list + return [messages_list] def _extract_abcd_letter(text: str) -> str | None: @@ -58,7 +57,7 @@ def _extract_abcd_letter(text: str) -> str | None: _GPQA_INPUT_MESSAGES = _load_gpqa_messages_from_csv() -def _strip_gt_messages(msgs: List[Message]) -> List[Message]: +def _strip_gt_messages(msgs: list[Message]) -> list[Message]: return [m for m in msgs if not (m.role == "system" and (m.content or "").startswith("__GT__:"))] @@ -69,9 +68,9 @@ def __init__(self): super().__init__() self.single_turn_processor = SingleTurnRolloutProcessor() - def __call__(self, rows: List[EvaluationRow], config: RolloutProcessorConfig) -> List[asyncio.Task[EvaluationRow]]: + def __call__(self, rows: list[EvaluationRow], config: RolloutProcessorConfig) -> list[asyncio.Task[EvaluationRow]]: """Preprocess rows and delegate to SingleTurnRolloutProcessor.""" - processed: List[EvaluationRow] = [] + processed: list[EvaluationRow] = [] for r in rows: gt_tokens = [ diff --git a/eval_protocol/benchmarks/test_livebench_data_analysis.py b/eval_protocol/benchmarks/test_livebench_data_analysis.py index 85becd6d..a54ccc2b 100644 --- a/eval_protocol/benchmarks/test_livebench_data_analysis.py +++ b/eval_protocol/benchmarks/test_livebench_data_analysis.py @@ -409,7 +409,7 @@ def _extract_gt(row: EvaluationRow) -> Dict[str, Any]: @evaluation_test( completion_params=[{"model": "fireworks_ai/accounts/fireworks/models/gpt-oss-120b"}], - input_messages=[[m for m in r.messages] for r in _CTA_ROWS], + input_messages=[[[m for m in r.messages] for r in _CTA_ROWS]], rollout_processor_kwargs=[{"extra_body": {"reasoning_effort": "low"}}], rollout_processor=SingleTurnRolloutProcessor(), aggregation_method="mean", @@ -451,7 +451,7 @@ def test_livebench_cta_pointwise(row: EvaluationRow) -> EvaluationRow: @evaluation_test( completion_params=[{"model": "fireworks_ai/accounts/fireworks/models/gpt-oss-120b"}], - input_messages=[[m for m in r.messages] for r in _TABLEJOIN_ROWS], + input_messages=[[[m for m in r.messages] for r in _TABLEJOIN_ROWS]], rollout_processor_kwargs=[{"extra_body": {"reasoning_effort": "low"}}], rollout_processor=LiveBenchGroundTruthRolloutProcessor(_TABLEJOIN_ROWS), aggregation_method="mean", diff --git a/eval_protocol/pytest/evaluation_test.py b/eval_protocol/pytest/evaluation_test.py index 39185e63..32f01cc6 100644 --- a/eval_protocol/pytest/evaluation_test.py +++ b/eval_protocol/pytest/evaluation_test.py @@ -62,7 +62,7 @@ def evaluation_test( *, completion_params: Sequence[CompletionParams | None] | None = None, - input_messages: Sequence[InputMessagesParam | None] | None = None, + input_messages: Sequence[list[InputMessagesParam] | None] | None = None, input_dataset: Sequence[DatasetPathParam] | None = None, input_rows: Sequence[list[EvaluationRow]] | None = None, dataset_adapter: Callable[[list[dict[str, Any]]], Dataset] = default_dataset_adapter, # pyright: ignore[reportExplicitAny] @@ -232,7 +232,7 @@ def _log_eval_error(status: Status, rows: list[EvaluationRow] | None, passed: bo elif "input_messages" in kwargs and kwargs["input_messages"] is not None: # Support either a single row (List[Message]) or many rows (List[List[Message]]) im = kwargs["input_messages"] - data = [EvaluationRow(messages=im)] + data = [EvaluationRow(messages=dataset_messages) for dataset_messages in im] elif "input_rows" in kwargs and kwargs["input_rows"] is not None: # Use pre-constructed EvaluationRow objects directly data = kwargs["input_rows"] diff --git a/eval_protocol/pytest/generate_parameter_combinations.py b/eval_protocol/pytest/generate_parameter_combinations.py index e6c172af..6a1dcf2f 100644 --- a/eval_protocol/pytest/generate_parameter_combinations.py +++ b/eval_protocol/pytest/generate_parameter_combinations.py @@ -18,7 +18,7 @@ Either a single completion params object or None. """ -InputMessagesKwarg = InputMessagesParam | None +InputMessagesKwarg = list[InputMessagesParam] | None InputRowsKwarg = Dataset | None EvaluationTestKwargs = EvaluationInputParam | None @@ -47,7 +47,7 @@ class ParameterizedTestKwargs(TypedDict): def generate_parameter_combinations( input_dataset: Sequence[DatasetPathParam] | None, completion_params: Sequence[CompletionParams | None], - input_messages: Sequence[InputMessagesParam | None] | None, + input_messages: Sequence[list[InputMessagesParam] | None] | None, input_rows: Sequence[list[EvaluationRow] | None] | None, evaluation_test_kwargs: Sequence[EvaluationInputParam | None] | None, max_dataset_rows: int | None, @@ -83,11 +83,15 @@ def generate_parameter_combinations( # Apply EP_MAX_DATASET_ROWS to input_messages, but do NOT parameterize over # each row. Instead, pass the entire sliced list through in a single test run # so summaries aggregate all rows together (AIME-style behavior). - messages: Sequence[InputMessagesParam | None] = [None] + messages: Sequence[list[InputMessagesParam] | None] = [None] if input_messages is not None: effective_max_rows = parse_ep_max_rows(max_dataset_rows) if effective_max_rows is not None: - sliced_messages: Sequence[InputMessagesParam | None] = input_messages[:effective_max_rows] + sliced_messages: Sequence[list[InputMessagesParam] | None] = [ + dataset_messages[:effective_max_rows] + for dataset_messages in input_messages + if dataset_messages is not None + ] else: sliced_messages = input_messages # Wrap as a single parameter payload diff --git a/eval_protocol/pytest/parameterize.py b/eval_protocol/pytest/parameterize.py index 3b0806d2..51e7ee45 100644 --- a/eval_protocol/pytest/parameterize.py +++ b/eval_protocol/pytest/parameterize.py @@ -18,7 +18,7 @@ def pytest_parametrize( combinations: list[CombinationTuple], input_dataset: Sequence[DatasetPathParam] | None, completion_params: Sequence[CompletionParams | None] | None, - input_messages: Sequence[InputMessagesParam | None] | None, + input_messages: Sequence[list[InputMessagesParam] | None] | None, input_rows: Sequence[list[EvaluationRow]] | None, evaluation_test_kwargs: Sequence[EvaluationInputParam | None] | None, ) -> PytestParametrizeArgs: diff --git a/eval_protocol/pytest/rollout_processor.py b/eval_protocol/pytest/rollout_processor.py index 824dd015..313f1768 100644 --- a/eval_protocol/pytest/rollout_processor.py +++ b/eval_protocol/pytest/rollout_processor.py @@ -1,6 +1,5 @@ import asyncio from abc import ABC, abstractmethod -from typing import List from eval_protocol.models import EvaluationRow from eval_protocol.pytest.types import RolloutProcessorConfig @@ -12,7 +11,7 @@ class RolloutProcessor(ABC): """ @abstractmethod - def __call__(self, rows: List[EvaluationRow], config: RolloutProcessorConfig) -> List[asyncio.Task[EvaluationRow]]: + def __call__(self, rows: list[EvaluationRow], config: RolloutProcessorConfig) -> list[asyncio.Task[EvaluationRow]]: """Process evaluation rows and return async tasks. Must be implemented by subclasses.""" pass diff --git a/examples/healthbench/tests/test_evaluation.py b/examples/healthbench/tests/test_evaluation.py index e0c7917b..76c32a20 100644 --- a/examples/healthbench/tests/test_evaluation.py +++ b/examples/healthbench/tests/test_evaluation.py @@ -1,6 +1,3 @@ -import json -from typing import Dict, List - from eval_protocol.models import EvaluateResult, EvaluationRow, Message, MetricResult from eval_protocol.pytest.default_single_turn_rollout_process import ( SingleTurnRolloutProcessor, @@ -34,13 +31,15 @@ }, ] -_HB_INPUT_MESSAGES: List[List[Message]] = [] -_HB_RUBRICS_MAP: Dict[str, List[Dict]] = {} +_HB_INPUT_MESSAGES: list[list[list[Message]]] = [] +_HB_RUBRICS_MAP: dict[str, list[dict]] = {} for s in _HB_SAMPLES: _HB_INPUT_MESSAGES.append( [ - Message(role="system", content=SYSTEM_PROMPT), - Message(role="user", content=s["prompt_text"]), + [ + Message(role="system", content=SYSTEM_PROMPT), + Message(role="user", content=s["prompt_text"]), + ] ] ) _HB_RUBRICS_MAP[s["prompt_text"]] = s["rubrics"] diff --git a/tests/chinook/test_pydantic_chinook.py b/tests/chinook/test_pydantic_chinook.py index 87c54a29..37ffd64f 100644 --- a/tests/chinook/test_pydantic_chinook.py +++ b/tests/chinook/test_pydantic_chinook.py @@ -21,7 +21,7 @@ @pytest.mark.asyncio @evaluation_test( - input_messages=[[Message(role="user", content="What is the total number of tracks in the database?")]], + input_messages=[[[Message(role="user", content="What is the total number of tracks in the database?")]]], completion_params=[ { "model": { diff --git a/tests/pytest/test_get_metadata.py b/tests/pytest/test_get_metadata.py index e27064b2..e89f5a9e 100644 --- a/tests/pytest/test_get_metadata.py +++ b/tests/pytest/test_get_metadata.py @@ -7,11 +7,13 @@ @evaluation_test( input_messages=[ [ - Message(role="user", content="What is the capital of France?"), - ], - [ - Message(role="user", content="What is the capital of the moon?"), - ], + [ + Message(role="user", content="What is the capital of France?"), + ], + [ + Message(role="user", content="What is the capital of the moon?"), + ], + ] ], completion_params=[{"model": "accounts/fireworks/models/kimi-k2-instruct"}] * 2, mode="groupwise", diff --git a/tests/pytest/test_pydantic_agent.py b/tests/pytest/test_pydantic_agent.py index 2c777f5e..1c9079c1 100644 --- a/tests/pytest/test_pydantic_agent.py +++ b/tests/pytest/test_pydantic_agent.py @@ -11,7 +11,7 @@ @pytest.mark.asyncio @evaluation_test( - input_messages=[[Message(role="user", content="Hello, how are you?")]], + input_messages=[[[Message(role="user", content="Hello, how are you?")]]], completion_params=[ {"model": "accounts/fireworks/models/gpt-oss-120b", "provider": "fireworks"}, ], diff --git a/tests/pytest/test_pydantic_multi_agent.py b/tests/pytest/test_pydantic_multi_agent.py index 05cdddd9..9c0665ad 100644 --- a/tests/pytest/test_pydantic_multi_agent.py +++ b/tests/pytest/test_pydantic_multi_agent.py @@ -47,7 +47,7 @@ async def joke_factory(ctx: RunContext[None], count: int) -> list[str]: # pyrig @pytest.mark.asyncio @evaluation_test( - input_messages=[[Message(role="user", content="Tell me a joke.")]], + input_messages=[[[Message(role="user", content="Tell me a joke.")]]], completion_params=[ { "model": { diff --git a/tests/pytest/test_pytest_async.py b/tests/pytest/test_pytest_async.py index 6e42f186..64e7cb1b 100644 --- a/tests/pytest/test_pytest_async.py +++ b/tests/pytest/test_pytest_async.py @@ -7,11 +7,13 @@ @evaluation_test( input_messages=[ [ - Message(role="user", content="What is the capital of France?"), - ], - [ - Message(role="user", content="What is the capital of the moon?"), - ], + [ + Message(role="user", content="What is the capital of France?"), + ], + [ + Message(role="user", content="What is the capital of the moon?"), + ], + ] ], completion_params=[{"model": "accounts/fireworks/models/kimi-k2-instruct"}], mode="all", diff --git a/tests/pytest/test_pytest_default_agent_rollout_processor.py b/tests/pytest/test_pytest_default_agent_rollout_processor.py index 6eec4c5d..d5324b4d 100644 --- a/tests/pytest/test_pytest_default_agent_rollout_processor.py +++ b/tests/pytest/test_pytest_default_agent_rollout_processor.py @@ -8,12 +8,14 @@ @evaluation_test( input_messages=[ [ - Message( - role="user", - content="Can you give a summary of the past week in the 'general, model-requests, bug-reports, questions, and feature-requests' channels. For EVERY message or thread has not been resolved, please list them at the end of your response in a table. Be sure to include the exact message, severity, and current status so far. Current Date & Time: {current_date_time}".format( - current_date_time=datetime.now().strftime("%B %d, %Y at %I:%M %p") - ), - ) + [ + Message( + role="user", + content="Can you give a summary of the past week in the 'general, model-requests, bug-reports, questions, and feature-requests' channels. For EVERY message or thread has not been resolved, please list them at the end of your response in a table. Be sure to include the exact message, severity, and current status so far. Current Date & Time: {current_date_time}".format( + current_date_time=datetime.now().strftime("%B %d, %Y at %I:%M %p") + ), + ) + ] ] ], rollout_processor=AgentRolloutProcessor(), diff --git a/tests/pytest/test_pytest_flaky_sometimes.py b/tests/pytest/test_pytest_flaky_sometimes.py index bde5e34c..671a892e 100644 --- a/tests/pytest/test_pytest_flaky_sometimes.py +++ b/tests/pytest/test_pytest_flaky_sometimes.py @@ -11,7 +11,7 @@ # skip in CI since it will intentionally fail. This is useful for local generation of logs @pytest.mark.skipif(os.getenv("CI") == "true", reason="Skipping flaky test in CI") @evaluation_test( - input_messages=[[Message(role="user", content="Return HEADS or TAILS at random.")]], + input_messages=[[[Message(role="user", content="Return HEADS or TAILS at random.")]]], completion_params=[{"model": "dummy/local-model"}], rollout_processor=NoOpRolloutProcessor(), mode="pointwise", diff --git a/tests/pytest/test_pytest_groupwise.py b/tests/pytest/test_pytest_groupwise.py index 295d6a7b..154606e9 100644 --- a/tests/pytest/test_pytest_groupwise.py +++ b/tests/pytest/test_pytest_groupwise.py @@ -7,7 +7,9 @@ @evaluation_test( input_messages=[ [ - Message(role="user", content="What is the capital of France?"), + [ + Message(role="user", content="What is the capital of France?"), + ] ] ], completion_params=[ diff --git a/tests/pytest/test_pytest_input_messages.py b/tests/pytest/test_pytest_input_messages.py index f4401f22..9a35fc59 100644 --- a/tests/pytest/test_pytest_input_messages.py +++ b/tests/pytest/test_pytest_input_messages.py @@ -7,7 +7,9 @@ @evaluation_test( input_messages=[ [ - Message(role="user", content="What is the capital of France?"), + [ + Message(role="user", content="What is the capital of France?"), + ] ] ], completion_params=[{"model": "fireworks_ai/accounts/fireworks/models/gpt-oss-120b"}], diff --git a/tests/pytest/test_pytest_mcp_config.py b/tests/pytest/test_pytest_mcp_config.py index efcdf11d..5c5a6dd9 100644 --- a/tests/pytest/test_pytest_mcp_config.py +++ b/tests/pytest/test_pytest_mcp_config.py @@ -8,15 +8,17 @@ @evaluation_test( input_messages=[ [ - Message( - role="user", - content=( - "Can you give me a summary of every channel. " - "You can list servers and channels using the " - "list_servers and get_channels tools. And you can " - "read messages using the read_messages tool." - ), - ) + [ + Message( + role="user", + content=( + "Can you give me a summary of every channel. " + "You can list servers and channels using the " + "list_servers and get_channels tools. And you can " + "read messages using the read_messages tool." + ), + ) + ] ] ], rollout_processor=AgentRolloutProcessor(), @@ -77,7 +79,7 @@ def read(self, row_id: str | None = None) -> list[EvaluationRow]: logger = TrackingLogger(rollouts) @evaluation_test( - input_messages=input_messages, + input_messages=[input_messages], completion_params=completion_params_list, rollout_processor=AgentRolloutProcessor(), mode="pointwise", diff --git a/tests/pytest/test_pytest_mcp_url.py b/tests/pytest/test_pytest_mcp_url.py index ce265da5..c8063492 100644 --- a/tests/pytest/test_pytest_mcp_url.py +++ b/tests/pytest/test_pytest_mcp_url.py @@ -5,17 +5,19 @@ @evaluation_test( input_messages=[ [ - Message( - role="system", - content=( - "You are a helpful assistant that can answer questions about Fireworks.\n" - "ALWAYS provide code or commands to execute to answer the question." + [ + Message( + role="system", + content=( + "You are a helpful assistant that can answer questions about Fireworks.\n" + "ALWAYS provide code or commands to execute to answer the question." + ), ), - ), - Message( - role="user", - content=("Can you teach me about how to manage deployments on Fireworks"), - ), + Message( + role="user", + content=("Can you teach me about how to manage deployments on Fireworks"), + ), + ] ] ], rollout_processor=AgentRolloutProcessor(), diff --git a/tests/pytest/test_pytest_propagate_error.py b/tests/pytest/test_pytest_propagate_error.py index 95e390ea..a317a5de 100644 --- a/tests/pytest/test_pytest_propagate_error.py +++ b/tests/pytest/test_pytest_propagate_error.py @@ -47,7 +47,7 @@ async def test_pytest_propagate_error(): logger = TrackingLogger(rollouts) @evaluation_test( - input_messages=input_messages, + input_messages=[input_messages], completion_params=completion_params_list, rollout_processor=AgentRolloutProcessor(), mode="pointwise", diff --git a/tests/test_retry_mechanism.py b/tests/test_retry_mechanism.py index 863d7838..95b70faf 100644 --- a/tests/test_retry_mechanism.py +++ b/tests/test_retry_mechanism.py @@ -2,16 +2,15 @@ """ Simple test to verify the retry mechanism works with evaluation_test. """ +# pyright: reportAny=false +# pyright: reportPrivateImportUsage=false import asyncio -import os from collections import Counter -from typing import List +from typing_extensions import override from unittest.mock import Mock -import pytest - -from eval_protocol.models import EvaluateResult, EvaluationRow, Message, Status +from eval_protocol.models import EvaluateResult, EvaluationRow, Message from eval_protocol.pytest.evaluation_test import evaluation_test from eval_protocol.pytest.rollout_processor import RolloutProcessor from eval_protocol.pytest.types import RolloutProcessorConfig @@ -23,9 +22,10 @@ class MockRolloutProcessorWithRetries(RolloutProcessor): """Mock rollout processor that fails second task alphabetically on first attempt, succeeds on retry""" def __init__(self): - self.mock_tracker = Mock() + self.mock_tracker: Mock = Mock() - def __call__(self, rows: List[EvaluationRow], config: RolloutProcessorConfig) -> List[asyncio.Task[EvaluationRow]]: + @override + def __call__(self, rows: list[EvaluationRow], config: RolloutProcessorConfig) -> list[asyncio.Task[EvaluationRow]]: # Track this batch call self.mock_tracker.batch_call(len(rows)) @@ -67,7 +67,7 @@ async def process_single_row( # Create and return tasks (let evaluation_test handle them) tasks = [ - asyncio.create_task(process_single_row(row, row_setup[i]["delay"], row_setup[i]["should_fail"])) + asyncio.create_task(process_single_row(row, row_setup[i]["delay"], row_setup[i]["should_fail"])) # pyright: ignore[reportArgumentType] for i, row in enumerate(rows) ] @@ -81,11 +81,13 @@ async def process_single_row( @evaluation_test( completion_params=[{"model": "gpt-4o-mini", "temperature": 0}], input_messages=[ - [Message(role="user", content="Task A")], - [Message(role="user", content="Task B")], - [Message(role="user", content="Task C")], - [Message(role="user", content="Task D")], - [Message(role="user", content="Task E")], + [ + [Message(role="user", content="Task A")], + [Message(role="user", content="Task B")], + [Message(role="user", content="Task C")], + [Message(role="user", content="Task D")], + [Message(role="user", content="Task E")], + ] ], rollout_processor=shared_processor, num_runs=1, @@ -163,9 +165,10 @@ class MockRolloutProcessorFailFast(RolloutProcessor): """Mock processor that always raises ValueError (fail-fast exception)""" def __init__(self): - self.mock_tracker = Mock() + self.mock_tracker: Mock = Mock() - def __call__(self, rows: List[EvaluationRow], config: RolloutProcessorConfig) -> List[asyncio.Task[EvaluationRow]]: + @override + def __call__(self, rows: list[EvaluationRow], config: RolloutProcessorConfig) -> list[asyncio.Task[EvaluationRow]]: self.mock_tracker.batch_call(len(rows)) async def process_single_row(row: EvaluationRow) -> EvaluationRow: @@ -182,7 +185,7 @@ async def process_single_row(row: EvaluationRow) -> EvaluationRow: @evaluation_test( completion_params=[{"model": "gpt-4o-mini", "temperature": 0}], - input_messages=[[Message(role="user", content="Test")]], + input_messages=[[[Message(role="user", content="Test")]]], rollout_processor=shared_processor_fail_fast, num_runs=1, mode="pointwise", @@ -226,9 +229,10 @@ class MockRolloutProcessorCustomGiveup(RolloutProcessor): """Mock processor for testing custom giveup functions""" def __init__(self): - self.mock_tracker = Mock() + self.mock_tracker: Mock = Mock() - def __call__(self, rows: List[EvaluationRow], config: RolloutProcessorConfig) -> List[asyncio.Task[EvaluationRow]]: + @override + def __call__(self, rows: list[EvaluationRow], config: RolloutProcessorConfig) -> list[asyncio.Task[EvaluationRow]]: self.mock_tracker.batch_call(len(rows)) async def process_single_row(row: EvaluationRow) -> EvaluationRow: @@ -236,7 +240,7 @@ async def process_single_row(row: EvaluationRow) -> EvaluationRow: # Raise real litellm exceptions based on task content task_content = row.messages[0].content if row.messages else "" - if "429" in task_content: + if task_content is not None and "429" in task_content: raise litellm.RateLimitError( "Rate limit exceeded", llm_provider="test", model="test-model" ) # Should retry @@ -253,7 +257,7 @@ async def process_single_row(row: EvaluationRow) -> EvaluationRow: # Custom giveup function for litellm exceptions -def custom_http_giveup(e): +def custom_http_giveup(e: Exception) -> bool: # Don't retry bad requests (400-level errors), but do retry rate limits (429) if isinstance(e, litellm.BadRequestError): return True # Give up immediately on bad requests @@ -266,8 +270,10 @@ def custom_http_giveup(e): @evaluation_test( completion_params=[{"model": "gpt-4o-mini", "temperature": 0}], input_messages=[ - [Message(role="user", content="Test 429")], # Should retry - [Message(role="user", content="Test 400")], # Should not retry + [ + [Message(role="user", content="Test 429")], # Should retry + [Message(role="user", content="Test 400")], # Should not retry + ] ], rollout_processor=shared_processor_custom_giveup, num_runs=1, @@ -325,9 +331,10 @@ class MockRolloutProcessorSimpleGiveup(RolloutProcessor): """Mock processor that raises BadRequestError""" def __init__(self): - self.mock_tracker = Mock() + self.mock_tracker: Mock = Mock() - def __call__(self, rows: List[EvaluationRow], config: RolloutProcessorConfig) -> List[asyncio.Task[EvaluationRow]]: + @override + def __call__(self, rows: list[EvaluationRow], config: RolloutProcessorConfig) -> list[asyncio.Task[EvaluationRow]]: self.mock_tracker.batch_call(len(rows)) async def process_single_row(row: EvaluationRow) -> EvaluationRow: @@ -347,16 +354,16 @@ async def process_single_row(row: EvaluationRow) -> EvaluationRow: # Simple giveup function for 4xx errors -def simple_4xx_giveup(e): - if hasattr(e, "response") and hasattr(e.response, "status_code"): - status = e.response.status_code - return 400 <= status < 500 # Give up on all 4xx client errors +def simple_4xx_giveup(e: Exception) -> bool: + if hasattr(e, "response") and hasattr(e.response, "status_code"): # pyright: ignore[reportUnknownMemberType, reportUnknownArgumentType, reportAttributeAccessIssue] + status = e.response.status_code # pyright: ignore[reportUnknownMemberType, reportUnknownVariableType, reportAttributeAccessIssue] + return 400 <= status < 500 # Give up on all 4xx client errors # pyright: ignore[reportUnknownVariableType] return False # Retry everything else @evaluation_test( completion_params=[{"model": "gpt-4o-mini", "temperature": 0}], - input_messages=[[Message(role="user", content="Test 400 giveup")]], + input_messages=[[[Message(role="user", content="Test 400 giveup")]]], rollout_processor=shared_processor_simple_giveup, num_runs=1, mode="pointwise", From 0381ab251d0b79b5f5a530fa49f5622e051eacab Mon Sep 17 00:00:00 2001 From: Dylan Huang Date: Fri, 29 Aug 2025 13:14:07 -0700 Subject: [PATCH 18/18] fix input_messages --- tests/pytest/test_pytest_async.py | 6 ++++-- tests/pytest/test_pytest_mcp_config.py | 2 +- tests/pytest/test_pytest_propagate_error.py | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/pytest/test_pytest_async.py b/tests/pytest/test_pytest_async.py index 64e7cb1b..b1183a6d 100644 --- a/tests/pytest/test_pytest_async.py +++ b/tests/pytest/test_pytest_async.py @@ -26,8 +26,10 @@ async def test_pytest_async(rows: list[EvaluationRow]) -> list[EvaluationRow]: @evaluation_test( input_messages=[ [ - Message(role="user", content="What is the capital of France?"), - ], + [ + Message(role="user", content="What is the capital of France?"), + ], + ] ], completion_params=[{"model": "accounts/fireworks/models/kimi-k2-instruct"}], mode="pointwise", diff --git a/tests/pytest/test_pytest_mcp_config.py b/tests/pytest/test_pytest_mcp_config.py index 5c5a6dd9..d43bfe6d 100644 --- a/tests/pytest/test_pytest_mcp_config.py +++ b/tests/pytest/test_pytest_mcp_config.py @@ -89,7 +89,7 @@ def read(self, row_id: str | None = None) -> list[EvaluationRow]: def eval_fn(row: EvaluationRow) -> EvaluationRow: return row - await eval_fn(input_messages=input_messages[0], completion_params=completion_params_list[0]) # pyright: ignore[reportCallIssue] + await eval_fn(input_messages=input_messages, completion_params=completion_params_list[0]) # pyright: ignore[reportCallIssue] # ensure that the row has tools that were set during AgentRolloutProcessor assert len(rollouts) == 1 diff --git a/tests/pytest/test_pytest_propagate_error.py b/tests/pytest/test_pytest_propagate_error.py index a317a5de..63ed21ce 100644 --- a/tests/pytest/test_pytest_propagate_error.py +++ b/tests/pytest/test_pytest_propagate_error.py @@ -60,7 +60,7 @@ def eval_fn(row: EvaluationRow) -> EvaluationRow: # Manually invoke all parameter combinations within a single test for params in completion_params_list: - await eval_fn(input_messages=input_messages[0], completion_params=params) # pyright: ignore[reportCallIssue] + await eval_fn(input_messages=input_messages, completion_params=params) # pyright: ignore[reportCallIssue] # assert that the status of eval_metadata.status is "error" assert len(rollouts) == 5