diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index c70d161a8591..8d6b16d28527 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,4 +1,4 @@ -name: Bug report +name: 🐛 Bug report description: Submit a bug report to help us improve Streamlit labels: ["type:bug", "status:needs-triage"] body: diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 7109cb40fd4b..3ff36e2aa144 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,11 +1,11 @@ blank_issues_enabled: false contact_links: - - name: Documentation request + - name: 📚 Documentation request url: https://github.com/streamlit/docs/issues/new/choose about: Let us know how our docs could be better - - name: Streamlit documentation + - name: 📖 Streamlit documentation url: https://docs.streamlit.io/ about: Learn more about how to use Streamlit - - name: Anything else? + - name: ❓ Anything else? url: https://discuss.streamlit.io/ about: Ask usage questions on the Streamlit community forum diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 90887c31cc08..000000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -name: Feature request -about: Suggest a feature or enhancement for Streamlit -title: "" -labels: type:enhancement -assignees: "" ---- - -_(Note, you don't have to fill out every section here. They're just here for guidance. That said, nicely detailed feature requests are more likely to get eng attention sooner)_ - -### Problem - -Is your feature request related to a problem? Please describe the problem here. Ex. I'm always frustrated when [...] - -### Solution - -**MVP:** What's the smallest possible solution that would get 80% of the problem out of the way? - -**Possible additions:** What are other things that could be added to the MVP over time to make it better? - -**Preferred solution:** If you don't like the MVP above, tell us why, and what you'd like done instead. - -### Additional context - -Add any other context or screenshots about the feature request here. For example, did this FR come from https://discuss.streamlit.io or another site? Link the original source here! - ---- - -Community voting on feature requests enables the Streamlit team to understand which features are most important to our users. - -**If you'd like the Streamlit team to prioritize this feature request, please use the 👍 (thumbs up emoji) reaction in response to the initial post.** diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 000000000000..66d9ea8cdc60 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,52 @@ +name: ✨ Feature request +description: Suggest a feature or enhancement for Streamlit +labels: [type:enhancement] +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to suggest a feature or enhancement for Streamlit! + We really appreciate the community's efforts to improve Streamlit ❤️ + - type: checkboxes + attributes: + label: Checklist + description: Please confirm and check all the following options. + options: + - label: I have searched the [existing issues](https://github.com/streamlit/streamlit/issues) for similar feature requests. + required: true + - label: I added a descriptive title and summary to this issue. + required: true + - type: textarea + attributes: + label: Summary + description: Type here a clear and concise description of the feature or enhancement request. Aim for 2-3 sentences. + validations: + required: true + - type: textarea + attributes: + label: Why? + description: Please outline the problem, motivation, or use case related to this feature request. + placeholder: | + I'm always frustrated when ... + validations: + required: false + - type: textarea + attributes: + label: How? + description: | + Please describe the solution or implementation you'd like to see. This might include suggestions for `st` commands, new parameters, or UI mockups. + Don't worry if you don't have a clear solution in mind; any input helps! + placeholder: | + Introduce a new command called `st.foo` with the following set of parameters... + validations: + required: false + - type: textarea + attributes: + label: Additional Context + description: | + Links? References? Anything that will give us more context about the feature request here! + For example, did this feature request come from https://discuss.streamlit.io or another site? Link the original source here! + + _Tip: You can attach images by clicking this area to highlight it and then dragging files in._ + validations: + required: false diff --git a/.github/workflows/community-voting.yml b/.github/workflows/community-voting.yml new file mode 100644 index 000000000000..73afa1258a7a --- /dev/null +++ b/.github/workflows/community-voting.yml @@ -0,0 +1,51 @@ +# This workflow automatically comments on issues labeled with 'type:enhancement' or 'type:bug' +# and adds a thumbs-up reaction to the issue to encourage community voting. + +name: Community voting +on: + issues: + types: + - labeled +jobs: + add-enhancement-comment: + if: github.event.label.name == 'type:enhancement' + runs-on: ubuntu-latest + permissions: + issues: write + steps: + - name: Add comment to issue + run: gh issue comment ${{ github.event.issue.html_url }} --body "$ISSUE_BODY" + env: + GH_TOKEN: ${{ github.token }} + ISSUE_BODY: | + **To help Streamlit prioritize this feature, react with a 👍 (thumbs up emoji) to the initial post.** + + Your vote helps us identify which enhancements matter most to our users. + + ![Visits](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2Fstreamlit%2Fstreamlit%2Fissues%2F${{ github.event.issue.number }}&title=visits&edge_flat=false) + - name: Upvote issue + uses: aidan-mundy/react-to-issue@14d172c22f28fabdd86b3458b1701ba1a684bc19 + with: + issue-number: ${{ github.event.issue.number }} + reactions: "+1" + add-bug-comment: + if: github.event.label.name == 'type:bug' + runs-on: ubuntu-latest + permissions: + issues: write + steps: + - name: Add comment to issue + run: gh issue comment ${{ github.event.issue.html_url }} --body "$ISSUE_BODY" + env: + GH_TOKEN: ${{ github.token }} + ISSUE_BODY: | + **If this issue affects you, please react with a 👍 (thumbs up emoji) to the initial post.** + + Your feedback helps us prioritize which bugs to investigate and address first. + + ![Visits](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2Fstreamlit%2Fstreamlit%2Fissues%2F${{ github.event.issue.number }}&title=visits&edge_flat=false) + - name: Upvote issue + uses: aidan-mundy/react-to-issue@14d172c22f28fabdd86b3458b1701ba1a684bc19 + with: + issue-number: ${{ github.event.issue.number }} + reactions: "+1" diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml new file mode 100644 index 000000000000..616b722a6948 --- /dev/null +++ b/.github/workflows/playwright.yml @@ -0,0 +1,75 @@ +name: Playwright E2E Tests + +on: + push: + branches: + - "develop" + pull_request: + types: [opened, synchronize, reopened] + # Allows workflow to be called from other workflows + workflow_call: + inputs: + ref: + required: true + type: string + +# Avoid duplicate workflows on same branch +concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-playwright + cancel-in-progress: true + +jobs: + test: + runs-on: ubuntu-latest-4-cores + + defaults: + run: + shell: bash --login -eo pipefail {0} + + steps: + - name: Checkout Streamlit code + uses: actions/checkout@v3 + with: + ref: ${{ inputs.ref }} + persist-credentials: false + submodules: "recursive" + fetch-depth: 2 + - name: Set Python version vars + uses: ./.github/actions/build_info + - name: Set up Python ${{ env.PYTHON_MAX_VERSION }} + uses: actions/setup-python@v4 + with: + python-version: "${{ env.PYTHON_MAX_VERSION }}" + - name: Setup virtual env + uses: ./.github/actions/make_init + - name: Run make develop + run: make develop + - name: Run make protobuf + run: make protobuf + - name: Run make frontend + run: make frontend-fast + - name: Run make playwright + run: make playwright + - name: Check that all screenshot have been committed + run: | + set -x; + + UNTRACKED_FILE_COUNT=$(git ls-files --others --exclude-standard | grep snapshots | wc -l | bc -l || echo '0') + echo "Untracked files count: ${UNTRACKED_FILE_COUNT}" + if [[ "${UNTRACKED_FILE_COUNT}" -gt 0 ]]; then + echo "Untracked files:"; + git ls-files --others --exclude-standard | grep snapshots; + exit 1; + fi + - name: Upload snapshots + uses: actions/upload-artifact@v3 + if: always() + with: + name: playwright_snapshots + path: e2e/playwright/snapshots + - name: Upload failed test results + uses: actions/upload-artifact@v3 + if: always() + with: + name: playwright_test_results + path: e2e/playwright/test-results diff --git a/.gitignore b/.gitignore index 35072021c745..4372c4d75484 100644 --- a/.gitignore +++ b/.gitignore @@ -83,6 +83,16 @@ lib/Pipfile.lock ######################################################################## .idea +######################################################################## +# Playwright +######################################################################## +# Playwright test +e2e/playwright/playwright-report +e2e/playwright/test-results +# Only keep the snapshots in the linux folder +e2e/playwright/snapshots/* +!e2e/playwright/snapshots/linux + ######################################################################## # Cypress ######################################################################## diff --git a/Makefile b/Makefile index 62a75bf7ccb7..d21cb3f3c134 100644 --- a/Makefile +++ b/Makefile @@ -196,8 +196,14 @@ conda-distribution: GIT_HASH=$$(git rev-parse --short HEAD) conda build lib/conda-recipe --output-folder lib/conda-recipe/dist .PHONY: conda-package -# Build lib and frontend, and then run 'conda-distribution' -conda-package: build-deps frontend conda-distribution +# Build lib and (maybe) frontend assets, and then run 'conda-distribution' +conda-package: build-deps + if [ "${SNOWPARK_CONDA_BUILD}" = "1" ] ; then\ + echo "Creating Snowpark conda build, so skipping building frontend assets."; \ + else \ + make frontend; \ + fi + make conda-distribution; .PHONY: clean # Remove all generated files. @@ -221,6 +227,7 @@ clean: rm -rf frontend/public/reports rm -rf frontend/lib/dist rm -rf ~/.cache/pre-commit + rm -rf e2e/playwright/test-results find . -name .streamlit -type d -exec rm -rfv {} \; || true cd lib; rm -rf .coverage .coverage\.* @@ -327,6 +334,14 @@ jscoverage: e2etest: ./scripts/run_e2e_tests.py +.PHONY: playwright +# Run playwright E2E tests. +playwright: + python -m playwright install --with-deps; \ + cd e2e/playwright; \ + rm -rf ./test-results; \ + pytest --browser webkit --browser chromium --browser firefox --video retain-on-failure --screenshot only-on-failure --output ./test-results/ -n auto -v + .PHONY: loc # Count the number of lines of code in the project. loc: diff --git a/NOTICES b/NOTICES index d39ee91a8a82..7afd3a6e34aa 100644 --- a/NOTICES +++ b/NOTICES @@ -18529,6 +18529,20 @@ SOFTWARE. ----- +The following software may be included in this product: uuid. A copy of the source code may be downloaded from https://github.com/uuidjs/uuid.git. This software contains the following license and notice below: + +The MIT License (MIT) + +Copyright (c) 2010-2020 Robert Kieffer and other contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----- + The following software may be included in this product: validate.io-array. A copy of the source code may be downloaded from git://github.com/validate-io/array.git. This software contains the following license and notice below: The MIT License (MIT) diff --git a/component-lib/yarn.lock b/component-lib/yarn.lock index 74bde065fc7d..cb080aa01d0f 100644 --- a/component-lib/yarn.lock +++ b/component-lib/yarn.lock @@ -4103,9 +4103,9 @@ which@^2.0.1: isexe "^2.0.0" word-wrap@~1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + version "1.2.5" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" + integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== wordwrapjs@^4.0.0: version "4.0.1" diff --git a/e2e/playwright/conftest.py b/e2e/playwright/conftest.py new file mode 100644 index 000000000000..7ea8e9194b10 --- /dev/null +++ b/e2e/playwright/conftest.py @@ -0,0 +1,421 @@ +# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +Global pytest fixtures for e2e tests. +This file is automatically run by pytest before tests are executed. +""" +from __future__ import annotations + +import contextlib +import os +import re +import shlex +import shutil +import socket +import subprocess +import sys +import time +from io import BytesIO +from pathlib import Path +from tempfile import TemporaryFile +from types import ModuleType +from typing import Any, Generator, List, Literal, Protocol + +import pytest +import requests +from PIL import Image +from playwright.sync_api import ElementHandle, Locator, Page +from pytest import FixtureRequest + + +class AsyncSubprocess: + """A context manager. Wraps subprocess. Popen to capture output safely.""" + + def __init__(self, args, cwd=None, env=None): + self.args = args + self.cwd = cwd + self.env = env + self._proc = None + self._stdout_file = None + + def terminate(self): + """Terminate the process and return its stdout/stderr in a string.""" + if self._proc is not None: + self._proc.terminate() + self._proc.wait() + self._proc = None + + # Read the stdout file and close it + stdout = None + if self._stdout_file is not None: + self._stdout_file.seek(0) + stdout = self._stdout_file.read() + self._stdout_file.close() + self._stdout_file = None + + return stdout + + def __enter__(self): + self.start() + return self + + def start(self): + # Start the process and capture its stdout/stderr output to a temp + # file. We do this instead of using subprocess.PIPE (which causes the + # Popen object to capture the output to its own internal buffer), + # because large amounts of output can cause it to deadlock. + self._stdout_file = TemporaryFile("w+") + print(f"Running: {shlex.join(self.args)}") + self._proc = subprocess.Popen( + self.args, + cwd=self.cwd, + stdout=self._stdout_file, + stderr=subprocess.STDOUT, + text=True, + env={**os.environ.copy(), **self.env} if self.env else None, + ) + + def __exit__(self, exc_type, exc_val, exc_tb): + if self._proc is not None: + self._proc.terminate() + self._proc = None + if self._stdout_file is not None: + self._stdout_file.close() + self._stdout_file = None + + +def resolve_test_to_script(test_module: ModuleType) -> str: + """Resolve the test module to the corresponding test script filename.""" + module_name = test_module.__name__ + return module_name.replace("_test", ".py") + + +def find_available_port(host: str = "localhost") -> int: + """Find an available port on the given host.""" + with contextlib.closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s: + s.bind((host, 0)) # 0 means that the OS chooses a random port + s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + return int(s.getsockname()[1]) # [1] contains the randomly selected port number + + +def is_app_server_running(port: int, host: str = "localhost") -> bool: + """Check if the app server is running.""" + try: + return ( + requests.get(f"http://{host}:{port}/_stcore/health", timeout=1).text == "ok" + ) + except Exception: + return False + + +def wait_for_app_server_to_start(port: int, timeout: int = 5) -> bool: + """Wait for the app server to start. + + Parameters + ---------- + port : int + The port on which the app server is running. + + timeout : int + The number of minutes to wait for the app server to start. + + Returns + ------- + bool + True if the app server is started, False otherwise. + """ + + print(f"Waiting for app to start... {port}") + start_time = time.time() + while not is_app_server_running(port): + time.sleep(3) + if time.time() - start_time > 60 * timeout: + return False + return True + + +def wait_for_app_run(page: Page, wait_delay: int = 100): + """Wait for the given page to finish running.""" + page.wait_for_selector( + "[data-testid='stStatusWidget']", timeout=20000, state="detached" + ) + + if wait_delay > 0: + # Give the app a little more time to render everything + page.wait_for_timeout(wait_delay) + + +def wait_for_app_loaded(page: Page): + """Wait for the app to fully load.""" + # Wait for the app view container to appear: + page.wait_for_selector( + "[data-testid='stAppViewContainer']", timeout=30000, state="attached" + ) + # Wait for the main app container to appear: + page.wait_for_selector( + "[data-testid='block-container']", timeout=20000, state="attached" + ) + # Wait for the main menu to appear: + page.wait_for_selector("#MainMenu", timeout=20000, state="attached") + wait_for_app_run(page) + + +@pytest.fixture(scope="module") +def app_port() -> int: + """Fixture that returns an available port on localhost.""" + return find_available_port() + + +@pytest.fixture(scope="module", autouse=True) +def app_server( + app_port: int, request: FixtureRequest +) -> Generator[AsyncSubprocess, None, None]: + """Fixture that starts and stops the Streamlit app server.""" + streamlit_proc = AsyncSubprocess( + [ + "streamlit", + "run", + resolve_test_to_script(request.module), + "--server.headless", + "true", + "--global.developmentMode", + "false", + "--server.port", + str(app_port), + "--browser.gatherUsageStats", + "false", + ], + cwd=".", + ) + streamlit_proc.start() + if not wait_for_app_server_to_start(app_port): + streamlit_stdout = streamlit_proc.terminate() + print(streamlit_stdout) + raise RuntimeError("Unable to start Streamlit app") + yield streamlit_proc + streamlit_stdout = streamlit_proc.terminate() + print(streamlit_stdout) + + +@pytest.fixture(scope="function") +def app(page: Page, app_port: int) -> Page: + """Fixture that opens the app.""" + page.goto(f"http://localhost:{app_port}/") + wait_for_app_loaded(page) + return page + + +@pytest.fixture(scope="function", params=["light_theme", "dark_theme"]) +def app_theme(request) -> str: + """Fixture that returns the theme name.""" + return str(request.param) + + +@pytest.fixture(scope="function") +def themed_app(page: Page, app_port: int, app_theme: str) -> Page: + """Fixture that opens the app with the given theme.""" + page.goto(f"http://localhost:{app_port}/?embed_options={app_theme}") + wait_for_app_loaded(page) + return page + + +class ImageCompareFunction(Protocol): + def __call__( + self, + element: ElementHandle | Locator, + *, + image_threshold: float = 0.001, + pixel_threshold: float = 0.05, + name: str | None = None, + fail_fast: bool = False, + ) -> None: + """Compare a screenshot with screenshot from a past run. + + Parameters + ---------- + element : ElementHandle or Locator + The element to take a screenshot of. + image_threshold : float, optional + The allowed percentage of different pixels in the image. + pixel_threshold : float, optional + The allowed percentage of difference for a single pixel. + name : str | None, optional + The name of the screenshot without an extension. If not provided, the name + of the test function will be used. + fail_fast : bool, optional + If True, the comparison will stop at the first pixel mismatch. + """ + + +@pytest.fixture(scope="session") +def output_folder(pytestconfig: Any) -> Path: + """Fixture that returns the directory that is used for all test failures information. + + This includes: + - snapshot-tests-failures: This directory contains all the snapshots that did not + match with the snapshots from past runs. The folder structure is based on the folder + structure used in the main snapshots folder. + - snapshot-updates: This directory contains all the snapshots that got updated in + the current run based on folder structure used in the main snapshots folder. + """ + return Path(pytestconfig.getoption("--output")).resolve() + + +@pytest.fixture(scope="function") +def assert_snapshot( + request: FixtureRequest, output_folder: Path +) -> Generator[ImageCompareFunction, None, None]: + """Fixture that compares a screenshot with screenshot from a past run.""" + platform = str(sys.platform) + module_name = request.module.__name__ + test_function_name = request.node.originalname + root_path = Path(request.node.fspath).parent.resolve() + + snapshot_dir: Path = root_path / "snapshots" / platform / module_name + + module_snapshot_failures_dir: Path = ( + output_folder / "snapshot-tests-failures" / platform / module_name + ) + module_snapshot_updates_dir: Path = ( + output_folder / "snapshot-updates" / platform / module_name + ) + + snapshot_file_suffix = "" + # Extract the parameter ids if they exist + match = re.search(r"\[(.*?)\]", request.node.name) + if match: + snapshot_file_suffix = f"[{match.group(1)}]" + + snapshot_default_file_name: str = test_function_name + snapshot_file_suffix + + test_failure_messages: List[str] = [] + + def compare( + element: ElementHandle | Locator, + *, + image_threshold: float = 0.001, + pixel_threshold: float = 0.05, + name: str | None = None, + fail_fast: bool = False, + file_type: Literal["png", "jpg"] = "png", + ) -> None: + """Compare a screenshot with screenshot from a past run. + + Parameters + ---------- + element : ElementHandle or Locator + The element to take a screenshot of. + image_threshold : float, optional + The allowed percentage of different pixels in the image. + pixel_threshold : float, optional + The allowed percentage of difference for a single pixel to be considered + different. + name : str | None, optional + The name of the screenshot without an extension. If not provided, the name + of the test function will be used. + fail_fast : bool, optional + If True, the comparison will stop at the first pixel mismatch. + file_type: "png" or "jpg" + The file type of the screenshot. Defaults to "png". + """ + nonlocal test_failure_messages + nonlocal snapshot_default_file_name + nonlocal module_snapshot_updates_dir + nonlocal module_snapshot_failures_dir + nonlocal snapshot_file_suffix + + if file_type == "jpg": + file_extension = ".jpg" + img_bytes = element.screenshot( + type="jpeg", quality=90, animations="disabled" + ) + + else: + file_extension = ".png" + img_bytes = element.screenshot(type="png", animations="disabled") + + snapshot_file_name: str = snapshot_default_file_name + if name: + snapshot_file_name = name + snapshot_file_suffix + + snapshot_file_path: Path = ( + snapshot_dir / f"{snapshot_file_name}{file_extension}" + ) + + snapshot_updates_file_path: Path = ( + module_snapshot_updates_dir / f"{snapshot_file_name}{file_extension}" + ) + + snapshot_file_path.parent.mkdir(parents=True, exist_ok=True) + + test_failures_dir = module_snapshot_failures_dir / snapshot_file_name + if test_failures_dir.exists(): + # Remove the past runs failure dir for this specific screenshot + shutil.rmtree(test_failures_dir) + + if not snapshot_file_path.exists(): + snapshot_file_path.write_bytes(img_bytes) + # Update this in updates folder: + snapshot_updates_file_path.parent.mkdir(parents=True, exist_ok=True) + snapshot_updates_file_path.write_bytes(img_bytes) + # For missing snapshots, we don't want to directly fail in order to generate + # all missing snapshots in one run. + test_failure_messages.append(f"Missing snapshot for {snapshot_file_name}") + return + + from pixelmatch.contrib.PIL import pixelmatch + + # Compare the new screenshot with the screenshot from past runs: + img_a = Image.open(BytesIO(img_bytes)) + img_b = Image.open(snapshot_file_path) + img_diff = Image.new("RGBA", img_a.size) + try: + mismatch = pixelmatch( + img_a, + img_b, + img_diff, + threshold=pixel_threshold, + fail_fast=fail_fast, + alpha=0, + ) + except ValueError as ex: + # ValueError is thrown when the images have different sizes + # Update this in updates folder: + snapshot_updates_file_path.parent.mkdir(parents=True, exist_ok=True) + snapshot_updates_file_path.write_bytes(img_bytes) + pytest.fail(f"Snapshot matching failed: {ex}") + max_diff_pixels = int(image_threshold * img_a.size[0] * img_a.size[1]) + + if mismatch < max_diff_pixels: + return + + # Update this in updates folder: + snapshot_updates_file_path.parent.mkdir(parents=True, exist_ok=True) + snapshot_updates_file_path.write_bytes(img_bytes) + + # Create new failures folder for this test: + test_failures_dir.mkdir(parents=True, exist_ok=True) + img_diff.save(f"{test_failures_dir}/diff_{snapshot_file_name}{file_extension}") + img_a.save(f"{test_failures_dir}/actual_{snapshot_file_name}{file_extension}") + img_b.save(f"{test_failures_dir}/expected_{snapshot_file_name}{file_extension}") + + pytest.fail( + f"Snapshot mismatch for {snapshot_file_name} ({mismatch} pixels difference)" + ) + + yield compare + + if test_failure_messages: + pytest.fail("Snapshot test failed \n" + "\n".join(test_failure_messages)) diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-0[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-0[dark_theme-chromium].png new file mode 100644 index 000000000000..2b2b05fbd382 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-0[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-0[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-0[dark_theme-firefox].png new file mode 100644 index 000000000000..a06c896dee24 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-0[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-0[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-0[dark_theme-webkit].png new file mode 100644 index 000000000000..adf58f31cbbd Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-0[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-0[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-0[light_theme-chromium].png new file mode 100644 index 000000000000..bdc52d2d06b4 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-0[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-0[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-0[light_theme-firefox].png new file mode 100644 index 000000000000..1db1e1e7193f Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-0[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-0[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-0[light_theme-webkit].png new file mode 100644 index 000000000000..b94b295712a8 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-0[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-1[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-1[dark_theme-chromium].png new file mode 100644 index 000000000000..05f9b9ebdfb8 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-1[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-1[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-1[dark_theme-firefox].png new file mode 100644 index 000000000000..8c93c7a6826a Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-1[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-1[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-1[dark_theme-webkit].png new file mode 100644 index 000000000000..94728ef55fb9 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-1[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-1[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-1[light_theme-chromium].png new file mode 100644 index 000000000000..f1196d77d948 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-1[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-1[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-1[light_theme-firefox].png new file mode 100644 index 000000000000..af7d5b17f3ee Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-1[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-1[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-1[light_theme-webkit].png new file mode 100644 index 000000000000..984cd34c1676 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-1[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-2[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-2[dark_theme-chromium].png new file mode 100644 index 000000000000..e9fcb051f101 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-2[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-2[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-2[dark_theme-firefox].png new file mode 100644 index 000000000000..d4e66fa2ec00 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-2[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-2[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-2[dark_theme-webkit].png new file mode 100644 index 000000000000..a943ea9e0a2c Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-2[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-2[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-2[light_theme-chromium].png new file mode 100644 index 000000000000..60792bdf3909 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-2[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-2[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-2[light_theme-firefox].png new file mode 100644 index 000000000000..fbb894eb3c4b Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-2[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-2[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-2[light_theme-webkit].png new file mode 100644 index 000000000000..b2ed807d6953 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-2[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-3[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-3[dark_theme-chromium].png new file mode 100644 index 000000000000..60e0869b8964 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-3[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-3[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-3[dark_theme-firefox].png new file mode 100644 index 000000000000..2fbc17064033 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-3[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-3[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-3[dark_theme-webkit].png new file mode 100644 index 000000000000..aa8ec7441dd9 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-3[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-3[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-3[light_theme-chromium].png new file mode 100644 index 000000000000..a38791f44d00 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-3[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-3[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-3[light_theme-firefox].png new file mode 100644 index 000000000000..27711f478462 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-3[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-3[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-3[light_theme-webkit].png new file mode 100644 index 000000000000..793fa69150b9 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-3[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-4[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-4[dark_theme-chromium].png new file mode 100644 index 000000000000..23f3ff91da28 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-4[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-4[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-4[dark_theme-firefox].png new file mode 100644 index 000000000000..32c51b7afc0a Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-4[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-4[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-4[dark_theme-webkit].png new file mode 100644 index 000000000000..6201a7df90c6 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-4[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-4[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-4[light_theme-chromium].png new file mode 100644 index 000000000000..5ea3c748d985 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-4[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-4[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-4[light_theme-firefox].png new file mode 100644 index 000000000000..a77a730a064c Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-4[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-4[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-4[light_theme-webkit].png new file mode 100644 index 000000000000..6f056bd9ef38 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-4[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-5[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-5[dark_theme-chromium].png new file mode 100644 index 000000000000..2bee524f00ca Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-5[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-5[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-5[dark_theme-firefox].png new file mode 100644 index 000000000000..8d52b314f7b5 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-5[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-5[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-5[dark_theme-webkit].png new file mode 100644 index 000000000000..b3eba3dc11e7 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-5[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-5[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-5[light_theme-chromium].png new file mode 100644 index 000000000000..da999f4e2c13 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-5[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-5[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-5[light_theme-firefox].png new file mode 100644 index 000000000000..abd5e3c1d1bf Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-5[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-5[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-5[light_theme-webkit].png new file mode 100644 index 000000000000..413c0ac4a5bd Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-5[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-6[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-6[dark_theme-chromium].png new file mode 100644 index 000000000000..dd123c57738b Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-6[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-6[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-6[dark_theme-firefox].png new file mode 100644 index 000000000000..727178f41ae5 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-6[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-6[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-6[dark_theme-webkit].png new file mode 100644 index 000000000000..e55761f008cc Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-6[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-6[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-6[light_theme-chromium].png new file mode 100644 index 000000000000..3ac1916254ab Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-6[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-6[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-6[light_theme-firefox].png new file mode 100644 index 000000000000..88b6eecbe2ba Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-6[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-6[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-6[light_theme-webkit].png new file mode 100644 index 000000000000..5d91111c66ea Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-6[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-7[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-7[dark_theme-chromium].png new file mode 100644 index 000000000000..1e14961cffec Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-7[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-7[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-7[dark_theme-firefox].png new file mode 100644 index 000000000000..d2c1ae3d28a3 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-7[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-7[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-7[dark_theme-webkit].png new file mode 100644 index 000000000000..f449c5df2133 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-7[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-7[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-7[light_theme-chromium].png new file mode 100644 index 000000000000..d77474eb1d21 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-7[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-7[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-7[light_theme-firefox].png new file mode 100644 index 000000000000..99711e2a13a7 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-7[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-7[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-7[light_theme-webkit].png new file mode 100644 index 000000000000..90bb821f1147 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-7[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-8[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-8[dark_theme-chromium].png new file mode 100644 index 000000000000..bb9e3c597c2b Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-8[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-8[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-8[dark_theme-firefox].png new file mode 100644 index 000000000000..05eced2f071c Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-8[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-8[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-8[dark_theme-webkit].png new file mode 100644 index 000000000000..3985af9581de Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-8[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-8[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-8[light_theme-chromium].png new file mode 100644 index 000000000000..aa5cde54ac3d Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-8[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-8[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-8[light_theme-firefox].png new file mode 100644 index 000000000000..568c865f9e79 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-8[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-8[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-8[light_theme-webkit].png new file mode 100644 index 000000000000..827077966758 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_column_types_test/dataframe-column-types-8[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-0[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-0[dark_theme-chromium].png new file mode 100644 index 000000000000..eb19cbbdb225 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-0[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-0[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-0[dark_theme-firefox].png new file mode 100644 index 000000000000..154fff8a9a06 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-0[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-0[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-0[dark_theme-webkit].png new file mode 100644 index 000000000000..ce1fa3e97938 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-0[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-0[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-0[light_theme-chromium].png new file mode 100644 index 000000000000..f51b08674009 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-0[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-0[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-0[light_theme-firefox].png new file mode 100644 index 000000000000..f1349e6a69c0 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-0[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-0[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-0[light_theme-webkit].png new file mode 100644 index 000000000000..b770ac7d6866 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-0[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-1[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-1[dark_theme-chromium].png new file mode 100644 index 000000000000..38451a1b62ce Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-1[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-1[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-1[dark_theme-firefox].png new file mode 100644 index 000000000000..b9c8d9295ebb Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-1[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-1[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-1[dark_theme-webkit].png new file mode 100644 index 000000000000..44a548641409 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-1[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-1[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-1[light_theme-chromium].png new file mode 100644 index 000000000000..eb3caf60c7b4 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-1[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-1[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-1[light_theme-firefox].png new file mode 100644 index 000000000000..2e9fc863f3e1 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-1[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-1[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-1[light_theme-webkit].png new file mode 100644 index 000000000000..c62182ae2863 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-1[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-2[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-2[dark_theme-chromium].png new file mode 100644 index 000000000000..e56c7fe2b460 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-2[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-2[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-2[dark_theme-firefox].png new file mode 100644 index 000000000000..ce7a75bc8637 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-2[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-2[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-2[dark_theme-webkit].png new file mode 100644 index 000000000000..32a7c3e0ef37 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-2[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-2[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-2[light_theme-chromium].png new file mode 100644 index 000000000000..68eafd2664f8 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-2[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-2[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-2[light_theme-firefox].png new file mode 100644 index 000000000000..a2078ede8f0e Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-2[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-2[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-2[light_theme-webkit].png new file mode 100644 index 000000000000..18c55f6c0503 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-2[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-3[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-3[dark_theme-chromium].png new file mode 100644 index 000000000000..bdf4326c1188 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-3[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-3[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-3[dark_theme-firefox].png new file mode 100644 index 000000000000..5402d9ca71f0 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-3[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-3[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-3[dark_theme-webkit].png new file mode 100644 index 000000000000..77d921ef9090 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-3[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-3[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-3[light_theme-chromium].png new file mode 100644 index 000000000000..dc8f45c7a2c3 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-3[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-3[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-3[light_theme-firefox].png new file mode 100644 index 000000000000..4d038d549ca4 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-3[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-3[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-3[light_theme-webkit].png new file mode 100644 index 000000000000..6f36a22022f8 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_arrow_dataframe_styler_support_test/dataframe-pd-styler-3[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-0[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-0[dark_theme-chromium].png new file mode 100644 index 000000000000..dbbe8f525e71 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-0[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-0[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-0[dark_theme-firefox].png new file mode 100644 index 000000000000..5d656a437357 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-0[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-0[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-0[dark_theme-webkit].png new file mode 100644 index 000000000000..c10b729672ca Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-0[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-0[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-0[light_theme-chromium].png new file mode 100644 index 000000000000..060c25f54e01 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-0[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-0[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-0[light_theme-firefox].png new file mode 100644 index 000000000000..2aa23e9cb019 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-0[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-0[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-0[light_theme-webkit].png new file mode 100644 index 000000000000..cdcf9d7e77bb Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-0[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-1[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-1[dark_theme-chromium].png new file mode 100644 index 000000000000..7edf0a839440 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-1[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-1[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-1[dark_theme-firefox].png new file mode 100644 index 000000000000..edb4780a253e Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-1[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-1[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-1[dark_theme-webkit].png new file mode 100644 index 000000000000..05689796937d Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-1[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-1[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-1[light_theme-chromium].png new file mode 100644 index 000000000000..3ff08e4e5715 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-1[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-1[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-1[light_theme-firefox].png new file mode 100644 index 000000000000..80fc093dbd55 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-1[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-1[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-1[light_theme-webkit].png new file mode 100644 index 000000000000..604004ddf32e Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-1[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-2[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-2[dark_theme-chromium].png new file mode 100644 index 000000000000..80317cbf689f Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-2[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-2[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-2[dark_theme-firefox].png new file mode 100644 index 000000000000..7512739683b8 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-2[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-2[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-2[dark_theme-webkit].png new file mode 100644 index 000000000000..87dbfd484b1d Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-2[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-2[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-2[light_theme-chromium].png new file mode 100644 index 000000000000..4a7946de234c Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-2[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-2[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-2[light_theme-firefox].png new file mode 100644 index 000000000000..0dfcf78629af Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-2[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-2[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-2[light_theme-webkit].png new file mode 100644 index 000000000000..31290e5304ec Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-2[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-3[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-3[dark_theme-chromium].png new file mode 100644 index 000000000000..f4d65c5098e6 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-3[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-3[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-3[dark_theme-firefox].png new file mode 100644 index 000000000000..02e62203d0f4 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-3[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-3[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-3[dark_theme-webkit].png new file mode 100644 index 000000000000..de2751f89db2 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-3[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-3[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-3[light_theme-chromium].png new file mode 100644 index 000000000000..c0671bb9110e Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-3[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-3[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-3[light_theme-firefox].png new file mode 100644 index 000000000000..3c322ed21ce8 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-3[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-3[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-3[light_theme-webkit].png new file mode 100644 index 000000000000..fb7e852ef10b Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-3[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-4[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-4[dark_theme-chromium].png new file mode 100644 index 000000000000..bf6489b04841 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-4[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-4[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-4[dark_theme-firefox].png new file mode 100644 index 000000000000..f1ef5879a760 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-4[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-4[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-4[dark_theme-webkit].png new file mode 100644 index 000000000000..f16b0585732c Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-4[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-4[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-4[light_theme-chromium].png new file mode 100644 index 000000000000..2bea875cbae4 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-4[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-4[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-4[light_theme-firefox].png new file mode 100644 index 000000000000..d3fbca2e5cc3 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-4[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-4[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-4[light_theme-webkit].png new file mode 100644 index 000000000000..afe397329cc8 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-4[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-5[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-5[dark_theme-chromium].png new file mode 100644 index 000000000000..091b3d798304 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-5[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-5[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-5[dark_theme-firefox].png new file mode 100644 index 000000000000..798b7eefee2f Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-5[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-5[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-5[dark_theme-webkit].png new file mode 100644 index 000000000000..b44903a7a51f Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-5[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-5[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-5[light_theme-chromium].png new file mode 100644 index 000000000000..f16a7a4da4af Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-5[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-5[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-5[light_theme-firefox].png new file mode 100644 index 000000000000..7890932eec8a Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-5[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-5[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-5[light_theme-webkit].png new file mode 100644 index 000000000000..60a819596c48 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-5[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-6[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-6[dark_theme-chromium].png new file mode 100644 index 000000000000..08b9a773da3f Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-6[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-6[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-6[dark_theme-firefox].png new file mode 100644 index 000000000000..c9c9720c089c Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-6[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-6[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-6[dark_theme-webkit].png new file mode 100644 index 000000000000..c1c1f0fa3e0a Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-6[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-6[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-6[light_theme-chromium].png new file mode 100644 index 000000000000..69f995e14d4a Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-6[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-6[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-6[light_theme-firefox].png new file mode 100644 index 000000000000..87a46591f92e Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-6[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-6[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-6[light_theme-webkit].png new file mode 100644 index 000000000000..44d210fbab6b Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-6[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-7[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-7[dark_theme-chromium].png new file mode 100644 index 000000000000..a2694c80da15 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-7[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-7[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-7[dark_theme-firefox].png new file mode 100644 index 000000000000..85ab070cda68 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-7[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-7[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-7[dark_theme-webkit].png new file mode 100644 index 000000000000..e91c8e8ba188 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-7[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-7[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-7[light_theme-chromium].png new file mode 100644 index 000000000000..3b92d84f5912 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-7[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-7[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-7[light_theme-firefox].png new file mode 100644 index 000000000000..576a5edb9b78 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-7[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-7[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-7[light_theme-webkit].png new file mode 100644 index 000000000000..9da292e06b7e Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-7[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-8[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-8[dark_theme-chromium].png new file mode 100644 index 000000000000..14dd321062f9 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-8[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-8[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-8[dark_theme-firefox].png new file mode 100644 index 000000000000..c525043a094a Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-8[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-8[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-8[dark_theme-webkit].png new file mode 100644 index 000000000000..4feab5968d04 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-8[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-8[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-8[light_theme-chromium].png new file mode 100644 index 000000000000..e408d1342953 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-8[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-8[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-8[light_theme-firefox].png new file mode 100644 index 000000000000..651c56dd3128 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-8[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-8[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-8[light_theme-webkit].png new file mode 100644 index 000000000000..50ae03f51eeb Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-8[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-9[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-9[dark_theme-chromium].png new file mode 100644 index 000000000000..f4fea2a5be50 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-9[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-9[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-9[dark_theme-firefox].png new file mode 100644 index 000000000000..5730b56e7f7b Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-9[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-9[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-9[dark_theme-webkit].png new file mode 100644 index 000000000000..7c5ea7a5ddbf Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-9[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-9[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-9[light_theme-chromium].png new file mode 100644 index 000000000000..1a40085e3df3 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-9[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-9[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-9[light_theme-firefox].png new file mode 100644 index 000000000000..c8d1cf047ffa Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-9[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-9[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-9[light_theme-webkit].png new file mode 100644 index 000000000000..269ad73f28da Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_chat_message_test/chat_message-9[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-0[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-0[dark_theme-chromium].png new file mode 100644 index 000000000000..3e06f18cc274 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-0[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-0[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-0[dark_theme-firefox].png new file mode 100644 index 000000000000..c8fd85a96523 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-0[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-0[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-0[dark_theme-webkit].png new file mode 100644 index 000000000000..4c10369664d4 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-0[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-0[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-0[light_theme-chromium].png new file mode 100644 index 000000000000..452c05f0f695 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-0[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-0[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-0[light_theme-firefox].png new file mode 100644 index 000000000000..de41b868ec0e Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-0[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-0[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-0[light_theme-webkit].png new file mode 100644 index 000000000000..284821b8296a Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-0[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-1[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-1[dark_theme-chromium].png new file mode 100644 index 000000000000..cfd17e96d7f3 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-1[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-1[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-1[dark_theme-firefox].png new file mode 100644 index 000000000000..461ed2493c4c Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-1[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-1[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-1[dark_theme-webkit].png new file mode 100644 index 000000000000..88bdb4f517f4 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-1[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-1[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-1[light_theme-chromium].png new file mode 100644 index 000000000000..d329a11f9620 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-1[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-1[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-1[light_theme-firefox].png new file mode 100644 index 000000000000..880438916deb Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-1[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-1[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-1[light_theme-webkit].png new file mode 100644 index 000000000000..ebfaec22ae56 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-1[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-2[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-2[dark_theme-chromium].png new file mode 100644 index 000000000000..002107a61c70 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-2[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-2[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-2[dark_theme-firefox].png new file mode 100644 index 000000000000..305b6ab90c4c Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-2[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-2[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-2[dark_theme-webkit].png new file mode 100644 index 000000000000..75c0104e0181 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-2[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-2[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-2[light_theme-chromium].png new file mode 100644 index 000000000000..ec252ea64375 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-2[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-2[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-2[light_theme-firefox].png new file mode 100644 index 000000000000..71f710834649 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-2[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-2[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-2[light_theme-webkit].png new file mode 100644 index 000000000000..9ff1fd854ed7 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-2[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-3[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-3[dark_theme-chromium].png new file mode 100644 index 000000000000..97aaf890b06c Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-3[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-3[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-3[dark_theme-firefox].png new file mode 100644 index 000000000000..e3233936701b Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-3[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-3[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-3[dark_theme-webkit].png new file mode 100644 index 000000000000..3b0609a7f376 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-3[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-3[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-3[light_theme-chromium].png new file mode 100644 index 000000000000..c9288ba00d31 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-3[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-3[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-3[light_theme-firefox].png new file mode 100644 index 000000000000..bf77c992eee3 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-3[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-3[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-3[light_theme-webkit].png new file mode 100644 index 000000000000..ecd37a931a09 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-3[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-4[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-4[dark_theme-chromium].png new file mode 100644 index 000000000000..2da5837a4975 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-4[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-4[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-4[dark_theme-firefox].png new file mode 100644 index 000000000000..16d11e3b39bb Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-4[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-4[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-4[dark_theme-webkit].png new file mode 100644 index 000000000000..d523bb5baf16 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-4[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-4[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-4[light_theme-chromium].png new file mode 100644 index 000000000000..d8ac9b71fd31 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-4[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-4[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-4[light_theme-firefox].png new file mode 100644 index 000000000000..cc667e0189f7 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-4[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-4[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-4[light_theme-webkit].png new file mode 100644 index 000000000000..add7608bc0d8 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-4[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-5[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-5[dark_theme-chromium].png new file mode 100644 index 000000000000..f38197dc3637 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-5[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-5[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-5[dark_theme-firefox].png new file mode 100644 index 000000000000..8898b52e4c17 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-5[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-5[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-5[dark_theme-webkit].png new file mode 100644 index 000000000000..e7674c8f8abe Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-5[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-5[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-5[light_theme-chromium].png new file mode 100644 index 000000000000..5c153aaba14a Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-5[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-5[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-5[light_theme-firefox].png new file mode 100644 index 000000000000..ba77f698cb9c Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-5[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-5[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-5[light_theme-webkit].png new file mode 100644 index 000000000000..19632733106d Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-5[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-6[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-6[dark_theme-chromium].png new file mode 100644 index 000000000000..1df3a75d7f97 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-6[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-6[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-6[dark_theme-firefox].png new file mode 100644 index 000000000000..a32679ae3076 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-6[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-6[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-6[dark_theme-webkit].png new file mode 100644 index 000000000000..afeaea71d34b Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-6[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-6[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-6[light_theme-chromium].png new file mode 100644 index 000000000000..d6a44f02bd76 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-6[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-6[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-6[light_theme-firefox].png new file mode 100644 index 000000000000..e1976dcb9c79 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-6[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-6[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-6[light_theme-webkit].png new file mode 100644 index 000000000000..7862047fe312 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-6[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-7[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-7[dark_theme-chromium].png new file mode 100644 index 000000000000..1156c90ff986 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-7[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-7[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-7[dark_theme-firefox].png new file mode 100644 index 000000000000..0d72b58405fc Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-7[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-7[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-7[dark_theme-webkit].png new file mode 100644 index 000000000000..8777030c8ad3 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-7[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-7[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-7[light_theme-chromium].png new file mode 100644 index 000000000000..f44c5d64daa3 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-7[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-7[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-7[light_theme-firefox].png new file mode 100644 index 000000000000..e35f7243085c Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-7[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-7[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-7[light_theme-webkit].png new file mode 100644 index 000000000000..4afec5c412a6 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_checkbox_test/checkbox-7[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/expander_with_code[chromium].png b/e2e/playwright/snapshots/linux/st_code_test/expander_with_code[chromium].png new file mode 100644 index 000000000000..42f1beebb4e1 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/expander_with_code[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/expander_with_code[firefox].png b/e2e/playwright/snapshots/linux/st_code_test/expander_with_code[firefox].png new file mode 100644 index 000000000000..2a81caeeb363 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/expander_with_code[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/expander_with_code[webkit].png b/e2e/playwright/snapshots/linux/st_code_test/expander_with_code[webkit].png new file mode 100644 index 000000000000..c38a0e50d5b2 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/expander_with_code[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/expander_with_markdown_code[chromium].png b/e2e/playwright/snapshots/linux/st_code_test/expander_with_markdown_code[chromium].png new file mode 100644 index 000000000000..e03c2d5fbdef Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/expander_with_markdown_code[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/expander_with_markdown_code[firefox].png b/e2e/playwright/snapshots/linux/st_code_test/expander_with_markdown_code[firefox].png new file mode 100644 index 000000000000..4f27a9ffa0e1 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/expander_with_markdown_code[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/expander_with_markdown_code[webkit].png b/e2e/playwright/snapshots/linux/st_code_test/expander_with_markdown_code[webkit].png new file mode 100644 index 000000000000..f2a04ce1c7ed Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/expander_with_markdown_code[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/st_code-auto_lang[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_code_test/st_code-auto_lang[dark_theme-chromium].png new file mode 100644 index 000000000000..1dad9441b1d1 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/st_code-auto_lang[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/st_code-auto_lang[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_code_test/st_code-auto_lang[dark_theme-firefox].png new file mode 100644 index 000000000000..c067d4b27ea6 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/st_code-auto_lang[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/st_code-auto_lang[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_code_test/st_code-auto_lang[dark_theme-webkit].png new file mode 100644 index 000000000000..5abc99d4b2c4 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/st_code-auto_lang[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/st_code-auto_lang[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_code_test/st_code-auto_lang[light_theme-chromium].png new file mode 100644 index 000000000000..f6649d128926 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/st_code-auto_lang[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/st_code-auto_lang[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_code_test/st_code-auto_lang[light_theme-firefox].png new file mode 100644 index 000000000000..fffa2529bb84 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/st_code-auto_lang[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/st_code-auto_lang[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_code_test/st_code-auto_lang[light_theme-webkit].png new file mode 100644 index 000000000000..b2cef5e29226 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/st_code-auto_lang[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/st_code-empty[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_code_test/st_code-empty[dark_theme-chromium].png new file mode 100644 index 000000000000..ef5ce0212788 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/st_code-empty[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/st_code-empty[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_code_test/st_code-empty[dark_theme-firefox].png new file mode 100644 index 000000000000..16e4351bb69d Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/st_code-empty[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/st_code-empty[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_code_test/st_code-empty[dark_theme-webkit].png new file mode 100644 index 000000000000..a56242e0d66d Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/st_code-empty[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/st_code-empty[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_code_test/st_code-empty[light_theme-chromium].png new file mode 100644 index 000000000000..7addaa65ace6 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/st_code-empty[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/st_code-empty[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_code_test/st_code-empty[light_theme-firefox].png new file mode 100644 index 000000000000..b0f90c623c0a Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/st_code-empty[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/st_code-empty[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_code_test/st_code-empty[light_theme-webkit].png new file mode 100644 index 000000000000..3d107b779db8 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/st_code-empty[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/st_code-line_numbers[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_code_test/st_code-line_numbers[dark_theme-chromium].png new file mode 100644 index 000000000000..59eeb2014542 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/st_code-line_numbers[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/st_code-line_numbers[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_code_test/st_code-line_numbers[dark_theme-firefox].png new file mode 100644 index 000000000000..ecd206e283d6 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/st_code-line_numbers[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/st_code-line_numbers[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_code_test/st_code-line_numbers[dark_theme-webkit].png new file mode 100644 index 000000000000..35ac98735f60 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/st_code-line_numbers[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/st_code-line_numbers[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_code_test/st_code-line_numbers[light_theme-chromium].png new file mode 100644 index 000000000000..f6861b2646b2 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/st_code-line_numbers[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/st_code-line_numbers[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_code_test/st_code-line_numbers[light_theme-firefox].png new file mode 100644 index 000000000000..9abcdab94729 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/st_code-line_numbers[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/st_code-line_numbers[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_code_test/st_code-line_numbers[light_theme-webkit].png new file mode 100644 index 000000000000..19b4fa9c6540 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/st_code-line_numbers[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/st_code-no_lang[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_code_test/st_code-no_lang[dark_theme-chromium].png new file mode 100644 index 000000000000..b856c700f9db Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/st_code-no_lang[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/st_code-no_lang[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_code_test/st_code-no_lang[dark_theme-firefox].png new file mode 100644 index 000000000000..0337ebfdabd1 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/st_code-no_lang[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/st_code-no_lang[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_code_test/st_code-no_lang[dark_theme-webkit].png new file mode 100644 index 000000000000..0900e3862ef2 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/st_code-no_lang[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/st_code-no_lang[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_code_test/st_code-no_lang[light_theme-chromium].png new file mode 100644 index 000000000000..723edfc1a117 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/st_code-no_lang[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/st_code-no_lang[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_code_test/st_code-no_lang[light_theme-firefox].png new file mode 100644 index 000000000000..117b62b2f905 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/st_code-no_lang[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/st_code-no_lang[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_code_test/st_code-no_lang[light_theme-webkit].png new file mode 100644 index 000000000000..771fed527225 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/st_code-no_lang[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/st_code-python_lang[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_code_test/st_code-python_lang[dark_theme-chromium].png new file mode 100644 index 000000000000..63a3b7ad2026 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/st_code-python_lang[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/st_code-python_lang[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_code_test/st_code-python_lang[dark_theme-firefox].png new file mode 100644 index 000000000000..dad074bad122 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/st_code-python_lang[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/st_code-python_lang[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_code_test/st_code-python_lang[dark_theme-webkit].png new file mode 100644 index 000000000000..e1011b6a6e94 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/st_code-python_lang[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/st_code-python_lang[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_code_test/st_code-python_lang[light_theme-chromium].png new file mode 100644 index 000000000000..6e3950e45369 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/st_code-python_lang[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/st_code-python_lang[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_code_test/st_code-python_lang[light_theme-firefox].png new file mode 100644 index 000000000000..2a2f2c3262e9 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/st_code-python_lang[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/st_code-python_lang[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_code_test/st_code-python_lang[light_theme-webkit].png new file mode 100644 index 000000000000..7ce5a88e4653 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/st_code-python_lang[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/syntax_highlighting-hover[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_code_test/syntax_highlighting-hover[dark_theme-chromium].png new file mode 100644 index 000000000000..79b8c158c9ea Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/syntax_highlighting-hover[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/syntax_highlighting-hover[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_code_test/syntax_highlighting-hover[dark_theme-firefox].png new file mode 100644 index 000000000000..82dd1ddd5b21 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/syntax_highlighting-hover[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/syntax_highlighting-hover[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_code_test/syntax_highlighting-hover[dark_theme-webkit].png new file mode 100644 index 000000000000..c25cb985938c Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/syntax_highlighting-hover[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/syntax_highlighting-hover[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_code_test/syntax_highlighting-hover[light_theme-chromium].png new file mode 100644 index 000000000000..a57866b9f084 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/syntax_highlighting-hover[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/syntax_highlighting-hover[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_code_test/syntax_highlighting-hover[light_theme-firefox].png new file mode 100644 index 000000000000..e957edd2de56 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/syntax_highlighting-hover[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_code_test/syntax_highlighting-hover[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_code_test/syntax_highlighting-hover[light_theme-webkit].png new file mode 100644 index 000000000000..c7f2fc77ac3a Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_code_test/syntax_highlighting-hover[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-0[chromium].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-0[chromium].png new file mode 100644 index 000000000000..832dc2182246 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-0[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-0[firefox].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-0[firefox].png new file mode 100644 index 000000000000..a89271fe0b13 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-0[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-0[webkit].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-0[webkit].png new file mode 100644 index 000000000000..56f0995e36fd Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-0[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-10[chromium].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-10[chromium].png new file mode 100644 index 000000000000..c20dcd052e2e Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-10[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-10[firefox].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-10[firefox].png new file mode 100644 index 000000000000..2f8d1c4989b8 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-10[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-10[webkit].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-10[webkit].png new file mode 100644 index 000000000000..f50cc81be859 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-10[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-11[chromium].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-11[chromium].png new file mode 100644 index 000000000000..678226de120c Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-11[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-11[firefox].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-11[firefox].png new file mode 100644 index 000000000000..27c9246feb49 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-11[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-11[webkit].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-11[webkit].png new file mode 100644 index 000000000000..21ec7355509f Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-11[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-12[chromium].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-12[chromium].png new file mode 100644 index 000000000000..3bbb26a2f76a Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-12[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-12[firefox].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-12[firefox].png new file mode 100644 index 000000000000..197a0c1e5961 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-12[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-12[webkit].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-12[webkit].png new file mode 100644 index 000000000000..c602ac86e7bc Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-12[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-13[chromium].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-13[chromium].png new file mode 100644 index 000000000000..2f752aab8f5a Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-13[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-13[firefox].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-13[firefox].png new file mode 100644 index 000000000000..1d42c6f13a6d Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-13[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-13[webkit].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-13[webkit].png new file mode 100644 index 000000000000..476feb8ca694 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-13[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-14[chromium].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-14[chromium].png new file mode 100644 index 000000000000..5b3f7a0756ae Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-14[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-14[firefox].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-14[firefox].png new file mode 100644 index 000000000000..fb4f61b5e1c1 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-14[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-14[webkit].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-14[webkit].png new file mode 100644 index 000000000000..ff37402bafb5 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-14[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-15[chromium].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-15[chromium].png new file mode 100644 index 000000000000..727376afea72 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-15[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-15[firefox].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-15[firefox].png new file mode 100644 index 000000000000..f6fe54c1ce24 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-15[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-15[webkit].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-15[webkit].png new file mode 100644 index 000000000000..17a23688e550 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-15[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-16[chromium].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-16[chromium].png new file mode 100644 index 000000000000..4a746c9b4598 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-16[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-16[firefox].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-16[firefox].png new file mode 100644 index 000000000000..be41aa16a07d Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-16[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-16[webkit].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-16[webkit].png new file mode 100644 index 000000000000..e4ad97b67818 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-16[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-17[chromium].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-17[chromium].png new file mode 100644 index 000000000000..8d97e86e8f1d Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-17[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-17[firefox].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-17[firefox].png new file mode 100644 index 000000000000..b5e0c68c11ff Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-17[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-17[webkit].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-17[webkit].png new file mode 100644 index 000000000000..3355588b3911 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-17[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-18[chromium].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-18[chromium].png new file mode 100644 index 000000000000..cac0a1e699ae Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-18[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-18[firefox].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-18[firefox].png new file mode 100644 index 000000000000..046a76ad8373 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-18[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-18[webkit].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-18[webkit].png new file mode 100644 index 000000000000..e4278e251a83 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-18[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-19[chromium].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-19[chromium].png new file mode 100644 index 000000000000..0f1fe6ebe19e Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-19[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-19[firefox].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-19[firefox].png new file mode 100644 index 000000000000..710988872016 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-19[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-19[webkit].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-19[webkit].png new file mode 100644 index 000000000000..e00dfe54b265 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-19[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-1[chromium].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-1[chromium].png new file mode 100644 index 000000000000..58c51d3b59f4 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-1[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-1[firefox].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-1[firefox].png new file mode 100644 index 000000000000..397f1a182658 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-1[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-1[webkit].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-1[webkit].png new file mode 100644 index 000000000000..b17d58c9eb44 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-1[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-20[chromium].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-20[chromium].png new file mode 100644 index 000000000000..a7ed3872b369 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-20[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-20[firefox].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-20[firefox].png new file mode 100644 index 000000000000..553693755f71 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-20[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-20[webkit].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-20[webkit].png new file mode 100644 index 000000000000..b7cde895bb13 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-20[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-21[chromium].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-21[chromium].png new file mode 100644 index 000000000000..97ca5a9af32c Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-21[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-21[firefox].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-21[firefox].png new file mode 100644 index 000000000000..38332a03f3be Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-21[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-21[webkit].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-21[webkit].png new file mode 100644 index 000000000000..8b335fc76ec3 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-21[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-22[chromium].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-22[chromium].png new file mode 100644 index 000000000000..81ccc2caa9e1 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-22[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-22[firefox].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-22[firefox].png new file mode 100644 index 000000000000..a7d64e01a570 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-22[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-22[webkit].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-22[webkit].png new file mode 100644 index 000000000000..fdc73d767255 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-22[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-2[chromium].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-2[chromium].png new file mode 100644 index 000000000000..3cf7070c7cc1 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-2[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-2[firefox].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-2[firefox].png new file mode 100644 index 000000000000..b92fc8a89f8c Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-2[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-2[webkit].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-2[webkit].png new file mode 100644 index 000000000000..d17e37e24aec Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-2[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-3[chromium].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-3[chromium].png new file mode 100644 index 000000000000..a3cee30dddd4 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-3[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-3[firefox].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-3[firefox].png new file mode 100644 index 000000000000..951f55e0168a Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-3[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-3[webkit].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-3[webkit].png new file mode 100644 index 000000000000..4164c49e2c5d Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-3[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-4[chromium].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-4[chromium].png new file mode 100644 index 000000000000..9aee4902157c Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-4[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-4[firefox].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-4[firefox].png new file mode 100644 index 000000000000..b24aaec0429d Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-4[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-4[webkit].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-4[webkit].png new file mode 100644 index 000000000000..33b5af66423c Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-4[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-5[chromium].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-5[chromium].png new file mode 100644 index 000000000000..a40639550264 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-5[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-5[firefox].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-5[firefox].png new file mode 100644 index 000000000000..424de4edcff6 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-5[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-5[webkit].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-5[webkit].png new file mode 100644 index 000000000000..167a767c6bf3 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-5[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-6[chromium].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-6[chromium].png new file mode 100644 index 000000000000..5adcf9b92678 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-6[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-6[firefox].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-6[firefox].png new file mode 100644 index 000000000000..321a0f2dace4 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-6[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-6[webkit].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-6[webkit].png new file mode 100644 index 000000000000..488049903a78 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-6[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-7[chromium].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-7[chromium].png new file mode 100644 index 000000000000..7f4b67a7b36d Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-7[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-7[firefox].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-7[firefox].png new file mode 100644 index 000000000000..7ce8da1a5cf2 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-7[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-7[webkit].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-7[webkit].png new file mode 100644 index 000000000000..75d5635a3647 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-7[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-8[chromium].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-8[chromium].png new file mode 100644 index 000000000000..402598bf7261 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-8[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-8[firefox].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-8[firefox].png new file mode 100644 index 000000000000..02a1dbd638ac Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-8[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-8[webkit].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-8[webkit].png new file mode 100644 index 000000000000..ae51dad061e3 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-8[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-9[chromium].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-9[chromium].png new file mode 100644 index 000000000000..ffc8173a531e Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-9[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-9[firefox].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-9[firefox].png new file mode 100644 index 000000000000..0629090bc0ba Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-9[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-9[webkit].png b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-9[webkit].png new file mode 100644 index 000000000000..b995bf1eac79 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_data_editor_config_test/data_editor-config-9[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-main[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-main[dark_theme-chromium].png new file mode 100644 index 000000000000..1e33d8bb76c2 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-main[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-main[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-main[dark_theme-firefox].png new file mode 100644 index 000000000000..04664847158e Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-main[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-main[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-main[dark_theme-webkit].png new file mode 100644 index 000000000000..bc01a02f68ef Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-main[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-main[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-main[light_theme-chromium].png new file mode 100644 index 000000000000..3b2af97a538f Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-main[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-main[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-main[light_theme-firefox].png new file mode 100644 index 000000000000..12c4ec7838ec Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-main[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-main[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-main[light_theme-webkit].png new file mode 100644 index 000000000000..efcf8919e3bd Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-main[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-sidebar[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-sidebar[dark_theme-chromium].png new file mode 100644 index 000000000000..74f83bd90764 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-sidebar[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-sidebar[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-sidebar[dark_theme-firefox].png new file mode 100644 index 000000000000..39b83d97d259 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-sidebar[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-sidebar[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-sidebar[dark_theme-webkit].png new file mode 100644 index 000000000000..eea943928b7c Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-sidebar[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-sidebar[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-sidebar[light_theme-chromium].png new file mode 100644 index 000000000000..739fa43ce3d3 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-sidebar[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-sidebar[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-sidebar[light_theme-firefox].png new file mode 100644 index 000000000000..09b2a9f108ce Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-sidebar[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-sidebar[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-sidebar[light_theme-webkit].png new file mode 100644 index 000000000000..478c641292d3 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_expander_test/expanders-in-sidebar[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-0[chromium].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-0[chromium].png new file mode 100644 index 000000000000..229461662206 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-0[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-0[firefox].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-0[firefox].png new file mode 100644 index 000000000000..1d402f4f4799 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-0[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-0[webkit].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-0[webkit].png new file mode 100644 index 000000000000..a3081f2b8c48 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-0[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-1[chromium].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-1[chromium].png new file mode 100644 index 000000000000..a30de9958c6f Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-1[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-1[firefox].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-1[firefox].png new file mode 100644 index 000000000000..6194cca62d26 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-1[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-1[webkit].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-1[webkit].png new file mode 100644 index 000000000000..ccfff631924f Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-1[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-2[chromium].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-2[chromium].png new file mode 100644 index 000000000000..c897f934f846 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-2[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-2[firefox].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-2[firefox].png new file mode 100644 index 000000000000..969717a736cd Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-2[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-2[webkit].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-2[webkit].png new file mode 100644 index 000000000000..3a7befa65484 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-2[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-3[chromium].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-3[chromium].png new file mode 100644 index 000000000000..10d43bd9e13f Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-3[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-3[firefox].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-3[firefox].png new file mode 100644 index 000000000000..e7443e0f05b3 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-3[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-3[webkit].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-3[webkit].png new file mode 100644 index 000000000000..6def78522eb2 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-3[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-4[chromium].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-4[chromium].png new file mode 100644 index 000000000000..1cbbe60b9da0 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-4[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-4[firefox].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-4[firefox].png new file mode 100644 index 000000000000..68094036fa9b Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-4[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-4[webkit].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-4[webkit].png new file mode 100644 index 000000000000..f5c6cb4c9627 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-4[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-5[chromium].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-5[chromium].png new file mode 100644 index 000000000000..e0f3a1167bc7 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-5[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-5[firefox].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-5[firefox].png new file mode 100644 index 000000000000..bf5a9b8c5d0f Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-5[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-5[webkit].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-5[webkit].png new file mode 100644 index 000000000000..98507f6708a7 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-5[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-6[chromium].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-6[chromium].png new file mode 100644 index 000000000000..ed13b1fe4107 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-6[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-6[firefox].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-6[firefox].png new file mode 100644 index 000000000000..224509d72667 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-6[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-6[webkit].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-6[webkit].png new file mode 100644 index 000000000000..6c71e8e444c5 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-6[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-7[chromium].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-7[chromium].png new file mode 100644 index 000000000000..a972eeb48f71 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-7[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-7[firefox].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-7[firefox].png new file mode 100644 index 000000000000..03f359d32461 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-7[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-7[webkit].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-7[webkit].png new file mode 100644 index 000000000000..42612b3a6b6e Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/header-divider-7[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-10[chromium].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-10[chromium].png new file mode 100644 index 000000000000..b3ffbb28d488 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-10[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-10[firefox].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-10[firefox].png new file mode 100644 index 000000000000..4c621e7960a0 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-10[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-10[webkit].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-10[webkit].png new file mode 100644 index 000000000000..ed9416293c8a Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-10[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-11[chromium].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-11[chromium].png new file mode 100644 index 000000000000..3acbe536d2b0 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-11[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-11[firefox].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-11[firefox].png new file mode 100644 index 000000000000..3de983246d23 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-11[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-11[webkit].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-11[webkit].png new file mode 100644 index 000000000000..f76a4f9a5e9d Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-11[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-12[chromium].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-12[chromium].png new file mode 100644 index 000000000000..46b4711d7094 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-12[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-12[firefox].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-12[firefox].png new file mode 100644 index 000000000000..38989d126258 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-12[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-12[webkit].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-12[webkit].png new file mode 100644 index 000000000000..b7a12d17385f Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-12[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-13[chromium].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-13[chromium].png new file mode 100644 index 000000000000..5baaaffd5a04 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-13[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-13[firefox].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-13[firefox].png new file mode 100644 index 000000000000..d339e4276472 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-13[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-13[webkit].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-13[webkit].png new file mode 100644 index 000000000000..6ef8cb959238 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-13[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-14[chromium].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-14[chromium].png new file mode 100644 index 000000000000..ed8fb6eb7d68 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-14[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-14[firefox].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-14[firefox].png new file mode 100644 index 000000000000..b395e130c243 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-14[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-14[webkit].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-14[webkit].png new file mode 100644 index 000000000000..af4458f1451a Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-14[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-15[chromium].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-15[chromium].png new file mode 100644 index 000000000000..eda9637f48d3 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-15[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-15[firefox].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-15[firefox].png new file mode 100644 index 000000000000..396466f88061 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-15[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-15[webkit].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-15[webkit].png new file mode 100644 index 000000000000..8464fca9b1dd Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-15[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-8[chromium].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-8[chromium].png new file mode 100644 index 000000000000..fb42d7c73844 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-8[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-8[firefox].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-8[firefox].png new file mode 100644 index 000000000000..105afdd65734 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-8[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-8[webkit].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-8[webkit].png new file mode 100644 index 000000000000..0a9840df2e2a Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-8[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-9[chromium].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-9[chromium].png new file mode 100644 index 000000000000..74eba0039aea Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-9[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-9[firefox].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-9[firefox].png new file mode 100644 index 000000000000..93737f11ae97 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-9[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-9[webkit].png b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-9[webkit].png new file mode 100644 index 000000000000..ccdad52ee91a Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_headings_divider_test/subheader-divider-9[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-container-gray[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-gray[dark_theme-chromium].png new file mode 100644 index 000000000000..ac36307fc084 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-gray[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-container-gray[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-gray[dark_theme-firefox].png new file mode 100644 index 000000000000..130b33d16195 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-gray[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-container-gray[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-gray[dark_theme-webkit].png new file mode 100644 index 000000000000..34cc0cc536a2 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-gray[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-container-gray[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-gray[light_theme-chromium].png new file mode 100644 index 000000000000..6830212b9418 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-gray[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-container-gray[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-gray[light_theme-firefox].png new file mode 100644 index 000000000000..980bc3362b26 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-gray[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-container-gray[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-gray[light_theme-webkit].png new file mode 100644 index 000000000000..a35c7380a7fd Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-gray[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-container-green[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-green[dark_theme-chromium].png new file mode 100644 index 000000000000..3f89a93a6330 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-green[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-container-green[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-green[dark_theme-firefox].png new file mode 100644 index 000000000000..60fbfb46ffe6 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-green[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-container-green[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-green[dark_theme-webkit].png new file mode 100644 index 000000000000..9d167e541ab8 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-green[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-container-green[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-green[light_theme-chromium].png new file mode 100644 index 000000000000..07081cbc16f2 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-green[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-container-green[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-green[light_theme-firefox].png new file mode 100644 index 000000000000..32738eb66c89 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-green[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-container-green[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-green[light_theme-webkit].png new file mode 100644 index 000000000000..dbb010da8702 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-green[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-container-red[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-red[dark_theme-chromium].png new file mode 100644 index 000000000000..9b42816f57c4 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-red[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-container-red[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-red[dark_theme-firefox].png new file mode 100644 index 000000000000..2c547a995933 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-red[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-container-red[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-red[dark_theme-webkit].png new file mode 100644 index 000000000000..436f66197f67 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-red[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-container-red[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-red[light_theme-chromium].png new file mode 100644 index 000000000000..7ca6666f054b Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-red[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-container-red[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-red[light_theme-firefox].png new file mode 100644 index 000000000000..88da50f57264 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-red[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-container-red[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-red[light_theme-webkit].png new file mode 100644 index 000000000000..f142228170b3 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-container-red[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-help-and-ellipses[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-help-and-ellipses[dark_theme-chromium].png new file mode 100644 index 000000000000..99bce5e73dee Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-help-and-ellipses[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-help-and-ellipses[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-help-and-ellipses[dark_theme-firefox].png new file mode 100644 index 000000000000..06bdc99051fd Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-help-and-ellipses[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-help-and-ellipses[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-help-and-ellipses[dark_theme-webkit].png new file mode 100644 index 000000000000..b37d73d2bcd7 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-help-and-ellipses[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-help-and-ellipses[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-help-and-ellipses[light_theme-chromium].png new file mode 100644 index 000000000000..3b47ef6e029e Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-help-and-ellipses[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-help-and-ellipses[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-help-and-ellipses[light_theme-firefox].png new file mode 100644 index 000000000000..3c2923f8484d Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-help-and-ellipses[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-help-and-ellipses[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-help-and-ellipses[light_theme-webkit].png new file mode 100644 index 000000000000..baa761e92694 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-help-and-ellipses[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-label-collapse[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-label-collapse[dark_theme-chromium].png new file mode 100644 index 000000000000..5e9c1364b334 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-label-collapse[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-label-collapse[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-label-collapse[dark_theme-firefox].png new file mode 100644 index 000000000000..4a7054f0f2ec Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-label-collapse[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-label-collapse[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-label-collapse[dark_theme-webkit].png new file mode 100644 index 000000000000..2c79fd34bd6e Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-label-collapse[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-label-collapse[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-label-collapse[light_theme-chromium].png new file mode 100644 index 000000000000..de13a1c32fb5 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-label-collapse[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-label-collapse[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-label-collapse[light_theme-firefox].png new file mode 100644 index 000000000000..528b110230dc Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-label-collapse[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-label-collapse[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-label-collapse[light_theme-webkit].png new file mode 100644 index 000000000000..0c7287bda177 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-label-collapse[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-label-hidden[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-label-hidden[dark_theme-chromium].png new file mode 100644 index 000000000000..e2f741595cc8 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-label-hidden[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-label-hidden[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-label-hidden[dark_theme-firefox].png new file mode 100644 index 000000000000..57c56c0283fc Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-label-hidden[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-label-hidden[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-label-hidden[dark_theme-webkit].png new file mode 100644 index 000000000000..6bb4e76a6487 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-label-hidden[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-label-hidden[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-label-hidden[light_theme-chromium].png new file mode 100644 index 000000000000..77cb3182f027 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-label-hidden[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-label-hidden[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-label-hidden[light_theme-firefox].png new file mode 100644 index 000000000000..8e14e533b671 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-label-hidden[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-label-hidden[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-label-hidden[light_theme-webkit].png new file mode 100644 index 000000000000..d4c80ad8c658 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-label-hidden[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-with-help[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-with-help[dark_theme-chromium].png new file mode 100644 index 000000000000..61465657c179 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-with-help[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-with-help[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-with-help[dark_theme-firefox].png new file mode 100644 index 000000000000..cee0dee3e932 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-with-help[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-with-help[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-with-help[dark_theme-webkit].png new file mode 100644 index 000000000000..4f5e12d29581 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-with-help[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-with-help[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-with-help[light_theme-chromium].png new file mode 100644 index 000000000000..89ed756f6fe8 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-with-help[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-with-help[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-with-help[light_theme-firefox].png new file mode 100644 index 000000000000..939bfb9d66bd Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-with-help[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-with-help[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-with-help[light_theme-webkit].png new file mode 100644 index 000000000000..13d06dd5ceeb Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-with-help[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-with-none-value[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-with-none-value[dark_theme-chromium].png new file mode 100644 index 000000000000..d782fc865fd5 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-with-none-value[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-with-none-value[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-with-none-value[dark_theme-firefox].png new file mode 100644 index 000000000000..9d63a9ecc492 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-with-none-value[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-with-none-value[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-with-none-value[dark_theme-webkit].png new file mode 100644 index 000000000000..86711239e27d Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-with-none-value[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-with-none-value[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-with-none-value[light_theme-chromium].png new file mode 100644 index 000000000000..fc1894082dcf Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-with-none-value[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-with-none-value[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-with-none-value[light_theme-firefox].png new file mode 100644 index 000000000000..00b0fd7c5ffb Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-with-none-value[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_metric_test/metric-with-none-value[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_metric_test/metric-with-none-value[light_theme-webkit].png new file mode 100644 index 000000000000..919b6c73bcaa Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_metric_test/metric-with-none-value[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-0[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-0[dark_theme-chromium].png new file mode 100644 index 000000000000..58b8ce5738a6 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-0[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-0[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-0[dark_theme-firefox].png new file mode 100644 index 000000000000..70566102de44 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-0[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-0[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-0[dark_theme-webkit].png new file mode 100644 index 000000000000..d40be821c983 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-0[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-0[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-0[light_theme-chromium].png new file mode 100644 index 000000000000..f1acc85d5223 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-0[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-0[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-0[light_theme-firefox].png new file mode 100644 index 000000000000..6746f0c3245c Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-0[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-0[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-0[light_theme-webkit].png new file mode 100644 index 000000000000..d56ad6b8ba2e Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-0[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-10[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-10[dark_theme-chromium].png new file mode 100644 index 000000000000..b2c1090729b4 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-10[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-10[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-10[dark_theme-firefox].png new file mode 100644 index 000000000000..9a3cc1195cf7 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-10[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-10[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-10[dark_theme-webkit].png new file mode 100644 index 000000000000..4917b854dd38 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-10[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-10[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-10[light_theme-chromium].png new file mode 100644 index 000000000000..b3fafadca4ee Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-10[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-10[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-10[light_theme-firefox].png new file mode 100644 index 000000000000..0f9406bd6ec6 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-10[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-10[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-10[light_theme-webkit].png new file mode 100644 index 000000000000..7b3263ca830b Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-10[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-11[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-11[dark_theme-chromium].png new file mode 100644 index 000000000000..5309e363cd99 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-11[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-11[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-11[dark_theme-firefox].png new file mode 100644 index 000000000000..47048cc13b9d Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-11[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-11[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-11[dark_theme-webkit].png new file mode 100644 index 000000000000..b125b38a5d3b Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-11[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-11[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-11[light_theme-chromium].png new file mode 100644 index 000000000000..79326ce54438 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-11[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-11[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-11[light_theme-firefox].png new file mode 100644 index 000000000000..28c63282d7a6 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-11[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-11[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-11[light_theme-webkit].png new file mode 100644 index 000000000000..bdb7f95145e7 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-11[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-1[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-1[dark_theme-chromium].png new file mode 100644 index 000000000000..ab551befdac8 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-1[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-1[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-1[dark_theme-firefox].png new file mode 100644 index 000000000000..6cc14ef4d335 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-1[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-1[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-1[dark_theme-webkit].png new file mode 100644 index 000000000000..79d342d5ca46 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-1[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-1[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-1[light_theme-chromium].png new file mode 100644 index 000000000000..085c702c46f5 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-1[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-1[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-1[light_theme-firefox].png new file mode 100644 index 000000000000..a63fd6dcf341 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-1[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-1[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-1[light_theme-webkit].png new file mode 100644 index 000000000000..aa2e5e508d72 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-1[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-2[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-2[dark_theme-chromium].png new file mode 100644 index 000000000000..fe7e39ed0af1 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-2[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-2[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-2[dark_theme-firefox].png new file mode 100644 index 000000000000..e6023b38b47f Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-2[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-2[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-2[dark_theme-webkit].png new file mode 100644 index 000000000000..3b565ae71282 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-2[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-2[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-2[light_theme-chromium].png new file mode 100644 index 000000000000..54b00b635af6 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-2[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-2[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-2[light_theme-firefox].png new file mode 100644 index 000000000000..46af615f44bf Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-2[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-2[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-2[light_theme-webkit].png new file mode 100644 index 000000000000..f24d1b084c2e Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-2[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-3[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-3[dark_theme-chromium].png new file mode 100644 index 000000000000..f9841790b1f4 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-3[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-3[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-3[dark_theme-firefox].png new file mode 100644 index 000000000000..ed9016213662 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-3[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-3[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-3[dark_theme-webkit].png new file mode 100644 index 000000000000..e2a21735c66e Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-3[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-3[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-3[light_theme-chromium].png new file mode 100644 index 000000000000..c0c68772d156 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-3[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-3[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-3[light_theme-firefox].png new file mode 100644 index 000000000000..0140766fac46 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-3[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-3[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-3[light_theme-webkit].png new file mode 100644 index 000000000000..86b0facf38b6 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-3[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-4[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-4[dark_theme-chromium].png new file mode 100644 index 000000000000..0b75f8e17378 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-4[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-4[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-4[dark_theme-firefox].png new file mode 100644 index 000000000000..8ee8d7c8ebca Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-4[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-4[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-4[dark_theme-webkit].png new file mode 100644 index 000000000000..ce63970ff584 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-4[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-4[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-4[light_theme-chromium].png new file mode 100644 index 000000000000..490ce59f5d70 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-4[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-4[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-4[light_theme-firefox].png new file mode 100644 index 000000000000..eaa682425cd2 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-4[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-4[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-4[light_theme-webkit].png new file mode 100644 index 000000000000..1f656f40e888 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-4[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-5[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-5[dark_theme-chromium].png new file mode 100644 index 000000000000..216c059af688 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-5[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-5[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-5[dark_theme-firefox].png new file mode 100644 index 000000000000..097cb23c2b79 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-5[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-5[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-5[dark_theme-webkit].png new file mode 100644 index 000000000000..3098bd22b511 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-5[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-5[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-5[light_theme-chromium].png new file mode 100644 index 000000000000..cc819977f572 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-5[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-5[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-5[light_theme-firefox].png new file mode 100644 index 000000000000..32d29dda3848 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-5[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-5[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-5[light_theme-webkit].png new file mode 100644 index 000000000000..9413cb623bd4 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-5[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-6[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-6[dark_theme-chromium].png new file mode 100644 index 000000000000..2c33c224ae58 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-6[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-6[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-6[dark_theme-firefox].png new file mode 100644 index 000000000000..f2e21ace0888 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-6[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-6[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-6[dark_theme-webkit].png new file mode 100644 index 000000000000..eb16cf4e8d7c Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-6[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-6[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-6[light_theme-chromium].png new file mode 100644 index 000000000000..ee5f0c34b928 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-6[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-6[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-6[light_theme-firefox].png new file mode 100644 index 000000000000..cdc963d4c504 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-6[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-6[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-6[light_theme-webkit].png new file mode 100644 index 000000000000..1b70c777ea87 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-6[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-7[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-7[dark_theme-chromium].png new file mode 100644 index 000000000000..18db598a8898 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-7[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-7[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-7[dark_theme-firefox].png new file mode 100644 index 000000000000..5667339b653b Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-7[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-7[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-7[dark_theme-webkit].png new file mode 100644 index 000000000000..a8bcedb2b792 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-7[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-7[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-7[light_theme-chromium].png new file mode 100644 index 000000000000..8d962ffe3f22 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-7[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-7[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-7[light_theme-firefox].png new file mode 100644 index 000000000000..9fe0d3804099 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-7[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-7[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-7[light_theme-webkit].png new file mode 100644 index 000000000000..6f1a08bc9524 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-7[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-8[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-8[dark_theme-chromium].png new file mode 100644 index 000000000000..6ced90a9e3c4 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-8[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-8[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-8[dark_theme-firefox].png new file mode 100644 index 000000000000..f38f0ed7e53b Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-8[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-8[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-8[dark_theme-webkit].png new file mode 100644 index 000000000000..0c17591ae6fc Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-8[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-8[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-8[light_theme-chromium].png new file mode 100644 index 000000000000..1f91f74ee5d4 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-8[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-8[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-8[light_theme-firefox].png new file mode 100644 index 000000000000..86a2fa760d4d Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-8[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-8[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-8[light_theme-webkit].png new file mode 100644 index 000000000000..470511893513 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-8[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-9[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-9[dark_theme-chromium].png new file mode 100644 index 000000000000..a338df6c5473 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-9[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-9[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-9[dark_theme-firefox].png new file mode 100644 index 000000000000..842fd37d11e4 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-9[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-9[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-9[dark_theme-webkit].png new file mode 100644 index 000000000000..5e18e2f37159 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-9[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-9[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-9[light_theme-chromium].png new file mode 100644 index 000000000000..65385cc6fff2 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-9[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-9[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-9[light_theme-firefox].png new file mode 100644 index 000000000000..431bd1981001 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-9[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-9[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-9[light_theme-webkit].png new file mode 100644 index 000000000000..26afc781e6b1 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-9[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-0[chromium].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-0[chromium].png new file mode 100644 index 000000000000..e2e601967236 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-0[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-0[firefox].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-0[firefox].png new file mode 100644 index 000000000000..b9935901b11e Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-0[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-0[webkit].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-0[webkit].png new file mode 100644 index 000000000000..d73b9c05ae34 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-0[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-1[chromium].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-1[chromium].png new file mode 100644 index 000000000000..5c8d9264b836 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-1[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-1[firefox].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-1[firefox].png new file mode 100644 index 000000000000..f42643a16ccc Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-1[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-1[webkit].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-1[webkit].png new file mode 100644 index 000000000000..6fc3b8abada0 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-1[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-0[chromium].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-0[chromium].png new file mode 100644 index 000000000000..631a401d84a5 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-0[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-0[firefox].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-0[firefox].png new file mode 100644 index 000000000000..3194b2d09e8b Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-0[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-0[webkit].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-0[webkit].png new file mode 100644 index 000000000000..475e493c71f7 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-0[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-1[chromium].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-1[chromium].png new file mode 100644 index 000000000000..c7364f137302 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-1[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-1[firefox].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-1[firefox].png new file mode 100644 index 000000000000..ee2de016b6cc Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-1[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-1[webkit].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-1[webkit].png new file mode 100644 index 000000000000..1a04e8ecba2a Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-1[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-2[chromium].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-2[chromium].png new file mode 100644 index 000000000000..4f20f12f2344 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-2[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-2[firefox].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-2[firefox].png new file mode 100644 index 000000000000..ecc0e7c25143 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-2[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-2[webkit].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-2[webkit].png new file mode 100644 index 000000000000..2b0e2cf4c57c Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-2[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-3[chromium].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-3[chromium].png new file mode 100644 index 000000000000..df11f36d81db Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-3[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-3[firefox].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-3[firefox].png new file mode 100644 index 000000000000..d0d396857d84 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-3[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-3[webkit].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-3[webkit].png new file mode 100644 index 000000000000..8598698d9652 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-3[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-4[chromium].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-4[chromium].png new file mode 100644 index 000000000000..04b4337d6a8d Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-4[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-4[firefox].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-4[firefox].png new file mode 100644 index 000000000000..3a92fea3d32c Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-4[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-4[webkit].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-4[webkit].png new file mode 100644 index 000000000000..4000a735828a Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-dropdown-long-label-4[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-selection[chromium].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-selection[chromium].png new file mode 100644 index 000000000000..2c51e7aef059 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-selection[chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-selection[firefox].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-selection[firefox].png new file mode 100644 index 000000000000..4e6bb4c18238 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-selection[firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-selection[webkit].png b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-selection[webkit].png new file mode 100644 index 000000000000..3d0faabd7a63 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_multiselect_test/multiselect-selection[webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-changed_label[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-changed_label[dark_theme-chromium].png new file mode 100644 index 000000000000..782485beb27d Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-changed_label[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-changed_label[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-changed_label[dark_theme-firefox].png new file mode 100644 index 000000000000..baa5f4160d9e Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-changed_label[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-changed_label[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-changed_label[dark_theme-webkit].png new file mode 100644 index 000000000000..45832aba95f9 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-changed_label[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-changed_label[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-changed_label[light_theme-chromium].png new file mode 100644 index 000000000000..f3c1982e88a1 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-changed_label[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-changed_label[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-changed_label[light_theme-firefox].png new file mode 100644 index 000000000000..7da64fe1e370 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-changed_label[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-changed_label[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-changed_label[light_theme-webkit].png new file mode 100644 index 000000000000..9de7d708ca6e Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-changed_label[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed[dark_theme-chromium].png new file mode 100644 index 000000000000..3d4b4798443b Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed[dark_theme-firefox].png new file mode 100644 index 000000000000..1bbd0c66e0e1 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed[dark_theme-webkit].png new file mode 100644 index 000000000000..f3d56c432b4a Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed[light_theme-chromium].png new file mode 100644 index 000000000000..8d88a1c4b3a6 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed[light_theme-firefox].png new file mode 100644 index 000000000000..63cf01fcbfe8 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed[light_theme-webkit].png new file mode 100644 index 000000000000..62af1f0a5066 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed_via_update[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed_via_update[dark_theme-chromium].png new file mode 100644 index 000000000000..1a5db90631c0 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed_via_update[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed_via_update[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed_via_update[dark_theme-firefox].png new file mode 100644 index 000000000000..e2a3c197e085 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed_via_update[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed_via_update[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed_via_update[dark_theme-webkit].png new file mode 100644 index 000000000000..f3d56c432b4a Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed_via_update[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed_via_update[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed_via_update[light_theme-chromium].png new file mode 100644 index 000000000000..65fbb24a53ae Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed_via_update[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed_via_update[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed_via_update[light_theme-firefox].png new file mode 100644 index 000000000000..993fd9e17904 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed_via_update[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed_via_update[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed_via_update[light_theme-webkit].png new file mode 100644 index 000000000000..62af1f0a5066 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-collapsed_via_update[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-complete_state[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-complete_state[dark_theme-chromium].png new file mode 100644 index 000000000000..13d18c7ada7f Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-complete_state[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-complete_state[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-complete_state[dark_theme-firefox].png new file mode 100644 index 000000000000..23fe7ce4f577 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-complete_state[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-complete_state[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-complete_state[dark_theme-webkit].png new file mode 100644 index 000000000000..09b39d44e0ca Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-complete_state[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-complete_state[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-complete_state[light_theme-chromium].png new file mode 100644 index 000000000000..1eeecf8aa628 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-complete_state[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-complete_state[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-complete_state[light_theme-firefox].png new file mode 100644 index 000000000000..3fec59543167 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-complete_state[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-complete_state[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-complete_state[light_theme-webkit].png new file mode 100644 index 000000000000..3683532e5650 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-complete_state[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-empty_state[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-empty_state[dark_theme-chromium].png new file mode 100644 index 000000000000..97239c24b803 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-empty_state[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-empty_state[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-empty_state[dark_theme-firefox].png new file mode 100644 index 000000000000..5278e34b9203 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-empty_state[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-empty_state[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-empty_state[dark_theme-webkit].png new file mode 100644 index 000000000000..dcbeb9177556 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-empty_state[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-empty_state[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-empty_state[light_theme-chromium].png new file mode 100644 index 000000000000..e706bd0938bb Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-empty_state[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-empty_state[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-empty_state[light_theme-firefox].png new file mode 100644 index 000000000000..8c4f69dfc1b5 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-empty_state[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-empty_state[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-empty_state[light_theme-webkit].png new file mode 100644 index 000000000000..e596e8d9f267 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-empty_state[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-error_state[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-error_state[dark_theme-chromium].png new file mode 100644 index 000000000000..2f59f41611e2 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-error_state[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-error_state[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-error_state[dark_theme-firefox].png new file mode 100644 index 000000000000..9fa8e6cdea80 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-error_state[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-error_state[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-error_state[dark_theme-webkit].png new file mode 100644 index 000000000000..5e57ad57c805 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-error_state[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-error_state[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-error_state[light_theme-chromium].png new file mode 100644 index 000000000000..70b4c08a5c32 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-error_state[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-error_state[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-error_state[light_theme-firefox].png new file mode 100644 index 000000000000..4f3750e9e9ec Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-error_state[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-error_state[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-error_state[light_theme-webkit].png new file mode 100644 index 000000000000..3c37067d533f Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-error_state[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-uncaught_exception[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-uncaught_exception[dark_theme-chromium].png new file mode 100644 index 000000000000..f0b7cc1b8a76 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-uncaught_exception[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-uncaught_exception[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-uncaught_exception[dark_theme-firefox].png new file mode 100644 index 000000000000..81b15fa1c825 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-uncaught_exception[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-uncaught_exception[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-uncaught_exception[dark_theme-webkit].png new file mode 100644 index 000000000000..9e3f1bfc5460 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-uncaught_exception[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-uncaught_exception[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-uncaught_exception[light_theme-chromium].png new file mode 100644 index 000000000000..3a28aa85ebf7 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-uncaught_exception[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-uncaught_exception[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-uncaught_exception[light_theme-firefox].png new file mode 100644 index 000000000000..983d5d888a10 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-uncaught_exception[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-uncaught_exception[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-uncaught_exception[light_theme-webkit].png new file mode 100644 index 000000000000..f8fc541a346b Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-uncaught_exception[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-without_cm[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-without_cm[dark_theme-chromium].png new file mode 100644 index 000000000000..d2823edab704 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-without_cm[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-without_cm[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-without_cm[dark_theme-firefox].png new file mode 100644 index 000000000000..26772df0402e Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-without_cm[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-without_cm[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-without_cm[dark_theme-webkit].png new file mode 100644 index 000000000000..75c38ae03663 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-without_cm[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-without_cm[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-without_cm[light_theme-chromium].png new file mode 100644 index 000000000000..b6fd5c269131 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-without_cm[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-without_cm[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-without_cm[light_theme-firefox].png new file mode 100644 index 000000000000..a2f865925b3f Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-without_cm[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_status_test/st_status-without_cm[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_status_test/st_status-without_cm[light_theme-webkit].png new file mode 100644 index 000000000000..85769f97c59b Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_status_test/st_status-without_cm[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-0[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-0[dark_theme-chromium].png new file mode 100644 index 000000000000..bbfe5e4dd9b2 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-0[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-0[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-0[dark_theme-firefox].png new file mode 100644 index 000000000000..708c2b14cc1f Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-0[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-0[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-0[dark_theme-webkit].png new file mode 100644 index 000000000000..4523d721f447 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-0[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-0[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-0[light_theme-chromium].png new file mode 100644 index 000000000000..33945ed1534c Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-0[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-0[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-0[light_theme-firefox].png new file mode 100644 index 000000000000..176366cf7b74 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-0[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-0[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-0[light_theme-webkit].png new file mode 100644 index 000000000000..35d8724a61d0 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-0[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-1[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-1[dark_theme-chromium].png new file mode 100644 index 000000000000..59e16d176377 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-1[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-1[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-1[dark_theme-firefox].png new file mode 100644 index 000000000000..f73ad0b9dd55 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-1[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-1[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-1[dark_theme-webkit].png new file mode 100644 index 000000000000..50517ee2a6b1 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-1[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-1[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-1[light_theme-chromium].png new file mode 100644 index 000000000000..1cca6a12ac65 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-1[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-1[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-1[light_theme-firefox].png new file mode 100644 index 000000000000..a4ab459f9f77 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-1[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-1[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-1[light_theme-webkit].png new file mode 100644 index 000000000000..f7645c6d3caf Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-1[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-2[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-2[dark_theme-chromium].png new file mode 100644 index 000000000000..a75ea4dcaa61 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-2[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-2[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-2[dark_theme-firefox].png new file mode 100644 index 000000000000..eb299506902c Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-2[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-2[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-2[dark_theme-webkit].png new file mode 100644 index 000000000000..aeb484a2b006 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-2[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-2[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-2[light_theme-chromium].png new file mode 100644 index 000000000000..51c5b550a6fd Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-2[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-2[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-2[light_theme-firefox].png new file mode 100644 index 000000000000..17dfae983d65 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-2[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-2[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-2[light_theme-webkit].png new file mode 100644 index 000000000000..6e0517046e71 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-2[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-3[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-3[dark_theme-chromium].png new file mode 100644 index 000000000000..ebb27934c9ad Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-3[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-3[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-3[dark_theme-firefox].png new file mode 100644 index 000000000000..e5ce8f62ed1a Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-3[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-3[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-3[dark_theme-webkit].png new file mode 100644 index 000000000000..356217ed0ded Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-3[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-3[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-3[light_theme-chromium].png new file mode 100644 index 000000000000..ed7e4e9823b4 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-3[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-3[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-3[light_theme-firefox].png new file mode 100644 index 000000000000..e4a2c7945835 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-3[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-3[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-3[light_theme-webkit].png new file mode 100644 index 000000000000..afcc98300a44 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-3[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-4[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-4[dark_theme-chromium].png new file mode 100644 index 000000000000..55276b774bc8 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-4[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-4[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-4[dark_theme-firefox].png new file mode 100644 index 000000000000..001d160bc507 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-4[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-4[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-4[dark_theme-webkit].png new file mode 100644 index 000000000000..86f67cfb077d Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-4[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-4[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-4[light_theme-chromium].png new file mode 100644 index 000000000000..5121ca59b704 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-4[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-4[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-4[light_theme-firefox].png new file mode 100644 index 000000000000..bb5671279797 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-4[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-4[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-4[light_theme-webkit].png new file mode 100644 index 000000000000..f65494e8b50f Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-4[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-5[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-5[dark_theme-chromium].png new file mode 100644 index 000000000000..4f67fdff43d0 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-5[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-5[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-5[dark_theme-firefox].png new file mode 100644 index 000000000000..040425ee095e Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-5[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-5[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-5[dark_theme-webkit].png new file mode 100644 index 000000000000..0ff9570660bb Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-5[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-5[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-5[light_theme-chromium].png new file mode 100644 index 000000000000..f2c5a15c7527 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-5[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-5[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-5[light_theme-firefox].png new file mode 100644 index 000000000000..78c289203cf0 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-5[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-5[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-5[light_theme-webkit].png new file mode 100644 index 000000000000..3f8d71f77baa Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-5[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-6[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-6[dark_theme-chromium].png new file mode 100644 index 000000000000..3ac07ed15e1f Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-6[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-6[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-6[dark_theme-firefox].png new file mode 100644 index 000000000000..5cc900507deb Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-6[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-6[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-6[dark_theme-webkit].png new file mode 100644 index 000000000000..0295ab2a092b Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-6[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-6[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-6[light_theme-chromium].png new file mode 100644 index 000000000000..a0849eed4b12 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-6[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-6[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-6[light_theme-firefox].png new file mode 100644 index 000000000000..0074f1059cbe Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-6[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-6[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-6[light_theme-webkit].png new file mode 100644 index 000000000000..be278f6410e4 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-6[light_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-7[dark_theme-chromium].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-7[dark_theme-chromium].png new file mode 100644 index 000000000000..9655e692a54b Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-7[dark_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-7[dark_theme-firefox].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-7[dark_theme-firefox].png new file mode 100644 index 000000000000..a6c72b026cb7 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-7[dark_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-7[dark_theme-webkit].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-7[dark_theme-webkit].png new file mode 100644 index 000000000000..0295ab2a092b Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-7[dark_theme-webkit].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-7[light_theme-chromium].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-7[light_theme-chromium].png new file mode 100644 index 000000000000..a330134477e4 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-7[light_theme-chromium].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-7[light_theme-firefox].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-7[light_theme-firefox].png new file mode 100644 index 000000000000..e3c6c141a73a Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-7[light_theme-firefox].png differ diff --git a/e2e/playwright/snapshots/linux/st_toggle_test/toggle-7[light_theme-webkit].png b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-7[light_theme-webkit].png new file mode 100644 index 000000000000..be278f6410e4 Binary files /dev/null and b/e2e/playwright/snapshots/linux/st_toggle_test/toggle-7[light_theme-webkit].png differ diff --git a/e2e/playwright/st_arrow_dataframe_column_types.py b/e2e/playwright/st_arrow_dataframe_column_types.py new file mode 100644 index 000000000000..1b9acd7c38b5 --- /dev/null +++ b/e2e/playwright/st_arrow_dataframe_column_types.py @@ -0,0 +1,72 @@ +# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import random + +import numpy as np +import pandas as pd + +import streamlit as st +from tests.streamlit.data_mocks import ( + BASE_TYPES_DF, + DATETIME_TYPES_DF, + INTERVAL_TYPES_DF, + LIST_TYPES_DF, + NUMBER_TYPES_DF, + PERIOD_TYPES_DF, + SPECIAL_TYPES_DF, + UNSUPPORTED_TYPES_DF, +) + +np.random.seed(0) +random.seed(0) + +st.set_page_config(layout="wide") + +st.subheader("Base types") +st._arrow_dataframe(BASE_TYPES_DF, use_container_width=True) + +st.subheader("Number types") +st._arrow_dataframe(NUMBER_TYPES_DF, use_container_width=True) + +st.subheader("Date, time and datetime types") +st._arrow_dataframe(DATETIME_TYPES_DF, use_container_width=True) + +st.subheader("List types") +st._arrow_dataframe(LIST_TYPES_DF, use_container_width=True) + +st.subheader("Interval dtypes in pd.DataFrame") +st._arrow_dataframe(INTERVAL_TYPES_DF, use_container_width=True) + +st.subheader("Special types") +st._arrow_dataframe(SPECIAL_TYPES_DF, use_container_width=True) + +st.subheader("Period dtypes in pd.DataFrame") +st._arrow_dataframe(PERIOD_TYPES_DF, use_container_width=True) + +st.subheader("Unsupported types") +st._arrow_dataframe(UNSUPPORTED_TYPES_DF, use_container_width=True) + +st.subheader("Long colum header") +st._arrow_dataframe( + pd.DataFrame( + np.random.randn(100, 4), + columns=[ + "this is a very long header name", + "A", + "C", + "this is another long name", + ], + ) +) diff --git a/e2e/playwright/st_arrow_dataframe_column_types_test.py b/e2e/playwright/st_arrow_dataframe_column_types_test.py new file mode 100644 index 000000000000..69464f5e7f78 --- /dev/null +++ b/e2e/playwright/st_arrow_dataframe_column_types_test.py @@ -0,0 +1,28 @@ +# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from playwright.sync_api import Page, expect + +from conftest import ImageCompareFunction + + +def test_dataframe_column_types( + themed_app: Page, assert_snapshot: ImageCompareFunction +): + """Test that st.dataframe render various column types correctly.""" + dataframe_elements = themed_app.locator(".stDataFrame") + expect(dataframe_elements).to_have_count(9) + + for i, element in enumerate(dataframe_elements.all()): + assert_snapshot(element, name=f"dataframe-column-types-{i}") diff --git a/e2e/playwright/st_arrow_dataframe_dimensions.py b/e2e/playwright/st_arrow_dataframe_dimensions.py new file mode 100644 index 000000000000..863e5384086f --- /dev/null +++ b/e2e/playwright/st_arrow_dataframe_dimensions.py @@ -0,0 +1,43 @@ +# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import numpy as np +import pandas as pd + +import streamlit as st +from tests.streamlit import snowpark_mocks + +# Explicitly seed the RNG for deterministic results +np.random.seed(0) + +data = np.random.randn(100, 100) + +df = pd.DataFrame(data) +st._arrow_dataframe(df) +st._arrow_dataframe(df, 250, 150) +st._arrow_dataframe(df, width=250) +st._arrow_dataframe(df, height=150) +st._arrow_dataframe(df, 5000, 5000) +st._arrow_dataframe(df, use_container_width=True) + +small_df = pd.DataFrame(np.random.randn(100, 3)) +st._arrow_dataframe(small_df, width=500) +st._arrow_dataframe(small_df, use_container_width=True) +st._arrow_dataframe(small_df, width=200, use_container_width=True) +st._arrow_dataframe(small_df, width=200, use_container_width=False) + +one_col_df = pd.DataFrame(np.random.randn(100, 1)) +st._arrow_dataframe(one_col_df, use_container_width=True) + +st._arrow_dataframe(snowpark_mocks.DataFrame(), use_container_width=True) diff --git a/e2e/playwright/st_arrow_dataframe_dimensions_test.py b/e2e/playwright/st_arrow_dataframe_dimensions_test.py new file mode 100644 index 000000000000..336ec091cffe --- /dev/null +++ b/e2e/playwright/st_arrow_dataframe_dimensions_test.py @@ -0,0 +1,40 @@ +# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from playwright.sync_api import Page, expect + + +def test_data_frame_with_different_sizes(app: Page): + """Test that st.dataframe should show different sizes as expected.""" + expected = [ + {"width": "704px", "height": "400px"}, + {"width": "250px", "height": "150px"}, + {"width": "250px", "height": "400px"}, + {"width": "704px", "height": "150px"}, + {"width": "704px", "height": "5000px"}, + {"width": "704px", "height": "400px"}, + {"width": "500px", "height": "400px"}, + {"width": "704px", "height": "400px"}, + {"width": "704px", "height": "400px"}, + {"width": "200px", "height": "400px"}, + {"width": "704px", "height": "400px"}, + {"width": "704px", "height": "400px"}, + ] + + dataframe_elements = app.locator(".stDataFrame") + expect(dataframe_elements).to_have_count(12) + + for i, element in enumerate(dataframe_elements.all()): + expect(element).to_have_css("width", expected[i]["width"]) + expect(element).to_have_css("height", expected[i]["height"]) diff --git a/e2e/playwright/st_arrow_dataframe_styler_support.py b/e2e/playwright/st_arrow_dataframe_styler_support.py new file mode 100644 index 000000000000..67e4a3242d96 --- /dev/null +++ b/e2e/playwright/st_arrow_dataframe_styler_support.py @@ -0,0 +1,95 @@ +# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import random + +import numpy as np +import pandas as pd + +import streamlit as st + +# Explicitly seed the RNG for deterministic results +np.random.seed(0) +random.seed(0) + + +st.header("Pandas Styler: Value formatting") +df = pd.DataFrame({"test": [3.1423424, 3.1]}) +st._arrow_dataframe(df.style.format({"test": "{:.2f}"})) + +st.header("Pandas Styler: Background color") + + +def highlight_first(value): + return "background-color: yellow" if value == 0 else "" + + +df = pd.DataFrame(np.arange(0, 100, 1).reshape(10, 10)) +st._arrow_dataframe(df.style.applymap(highlight_first)) + +st.header("Pandas Styler: Background and font styling") + +df = pd.DataFrame(np.random.randn(20, 4), columns=["A", "B", "C", "D"]) + + +def style_negative(v, props=""): + return props if v < 0 else None + + +def highlight_max(s, props=""): + return np.where(s == np.nanmax(s.values), props, "") + + +# Passing style values w/ all color formats to test css-style-string parsing robustness. +styled_df = df.style.applymap(style_negative, props="color:#FF0000;").applymap( + lambda v: "opacity: 20%;" if (v < 0.3) and (v > -0.3) else None +) + +styled_df.apply( + highlight_max, props="color:white;background-color:rgb(255, 0, 0)", axis=0 +) + +styled_df.apply( + highlight_max, props="color:white;background-color:hsl(273, 98%, 60%);", axis=1 +).apply(highlight_max, props="color:white;background-color:purple", axis=None) + +st._arrow_dataframe(styled_df) + +st.header("Pandas Styler: Gradient Styling") + +weather_df = pd.DataFrame( + np.random.rand(10, 2) * 5, + index=pd.date_range(start="2021-01-01", periods=10), + columns=["Tokyo", "Beijing"], +) + + +def rain_condition(v): + if v < 1.75: + return "Dry" + elif v < 2.75: + return "Rain" + return "Heavy Rain" + + +def make_pretty(styler): + styler.set_caption("Weather Conditions") + styler.format(rain_condition) + styler.background_gradient(axis=None, vmin=1, vmax=5, cmap="YlGnBu") + return styler + + +styled_df = weather_df.style.pipe(make_pretty) + +st._arrow_dataframe(styled_df) diff --git a/e2e/playwright/st_arrow_dataframe_styler_support_test.py b/e2e/playwright/st_arrow_dataframe_styler_support_test.py new file mode 100644 index 000000000000..0e04e2731230 --- /dev/null +++ b/e2e/playwright/st_arrow_dataframe_styler_support_test.py @@ -0,0 +1,26 @@ +# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from playwright.sync_api import Page, expect + +from conftest import ImageCompareFunction + + +def test_dataframe_pd_styler(themed_app: Page, assert_snapshot: ImageCompareFunction): + """Test that st.dataframe supports styling and display values via Pandas Styler.""" + dataframe_elements = themed_app.locator(".stDataFrame") + expect(dataframe_elements).to_have_count(4) + + for i, element in enumerate(dataframe_elements.all()): + assert_snapshot(element, name=f"dataframe-pd-styler-{i}") diff --git a/e2e/playwright/st_chat_message.py b/e2e/playwright/st_chat_message.py new file mode 100644 index 000000000000..21fa6b34a5d8 --- /dev/null +++ b/e2e/playwright/st_chat_message.py @@ -0,0 +1,80 @@ +# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import numpy as np +import pandas as pd +from PIL import Image + +import streamlit as st + +np.random.seed(0) + + +# Generate a random dataframe +df = pd.DataFrame( + np.random.randn(5, 5), + columns=("col_%d" % i for i in range(5)), +) + + +with st.chat_message("user"): + st.write("Hello…") + +with st.chat_message("assistant"): + st.write( + """ +Hello, here is a code snippet: + +```python +import streamlit as st +with st.chat_message("assistant"): + st.write("Hello, here is a code snippet...") +``` +""" + ) + +with st.chat_message("user", avatar="🧑"): + st.write( + """ +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris tristique est +at tincidunt pul vinar. Nam pulvinar neque sapien, eu pellentesque metus pellentesque +at. Ut et dui molestie, iaculis magna sed. +""" + ) + +with st.chat_message("dog", avatar="https://static.streamlit.io/examples/dog.jpg"): + st.write("Woof woof! I'm a dog and I like charts:") + st.line_chart(df, use_container_width=True) + +cat = st.chat_message("cat", avatar="https://static.streamlit.io/examples/cat.jpg") +cat.write("I'm a cat and I like this dataset:") +cat.dataframe(df, use_container_width=True) +cat.text_input("What's your name?") + + +with st.chat_message("Bot"): + with st.expander("See more", expanded=True): + st.write("Lorem ipsum dolor sit amet") + +st.chat_message("human") + + +image1 = Image.new("RGB", (10, 10), "red") +st.chat_message("user", avatar=image1).write("Red local image") + +image2 = Image.new("RGB", (10, 10), "blue") +st.chat_message("assistant", avatar=image2).write("Blue local image") +st.chat_message("assistant", avatar=image2).write( + "Another message with the same blue avatar." +) diff --git a/e2e/playwright/st_chat_message_test.py b/e2e/playwright/st_chat_message_test.py new file mode 100644 index 000000000000..5b6ba73589e5 --- /dev/null +++ b/e2e/playwright/st_chat_message_test.py @@ -0,0 +1,31 @@ +# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from playwright.sync_api import Page, expect + +from conftest import ImageCompareFunction + + +def test_renders_chat_messages_correctly_1( + themed_app: Page, assert_snapshot: ImageCompareFunction +): + """Test if the chat messages render correctly""" + # Wait a bit more to allow all images to load: + chat_message_elements = themed_app.locator(".stChatMessage") + expect(chat_message_elements).to_have_count(10) + for i, element in enumerate(chat_message_elements.all()): + element.scroll_into_view_if_needed() + # Wait a bit more to allow the avatar images to load: + themed_app.wait_for_timeout(100) + assert_snapshot(element, name=f"chat_message-{i}") diff --git a/e2e/playwright/st_checkbox.py b/e2e/playwright/st_checkbox.py new file mode 100644 index 000000000000..60ba07ee598c --- /dev/null +++ b/e2e/playwright/st_checkbox.py @@ -0,0 +1,48 @@ +# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import streamlit as st +from streamlit import runtime + +i1 = st.checkbox("checkbox 1 (True)", True) +st.write("checkbox 1 - value:", i1) + +i2 = st.checkbox("checkbox 2 (False)", False) +st.write("checkbox 2 - value:", i2) + +i3 = st.checkbox( + "checkbox 3: This is a really really really really long label that should wrap eventually if we keep addding more text to it" +) +st.write("checkbox 3 - value:", i3) + +if runtime.exists(): + + def on_change(): + st.session_state.checkbox_clicked = True + + st.checkbox("checkbox 4 (with callback)", key="checkbox4", on_change=on_change) + st.write("checkbox 4 - value:", st.session_state.checkbox4) + st.write("checkbox 4 - clicked:", "checkbox_clicked" in st.session_state) + +i5 = st.checkbox("checkbox 5 (False, disabled)", disabled=True) +st.write("checkbox 5 - value:", i5) + +i6 = st.checkbox("checkbox 6 (True, disabled)", value=True, disabled=True) +st.write("checkbox 6 - value:", i6) + +i7 = st.checkbox("checkbox 7 (label hidden)", label_visibility="hidden") +st.write("checkbox 7 - value:", i7) + +i8 = st.checkbox("checkbox 8 (label collapsed)", label_visibility="collapsed") +st.write("checkbox 8 - value:", i8) diff --git a/e2e/playwright/st_checkbox_test.py b/e2e/playwright/st_checkbox_test.py new file mode 100644 index 000000000000..a7076e61c85c --- /dev/null +++ b/e2e/playwright/st_checkbox_test.py @@ -0,0 +1,75 @@ +# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +from playwright.sync_api import Page, expect + +from conftest import ImageCompareFunction + + +def test_checkbox_widget_display( + themed_app: Page, assert_snapshot: ImageCompareFunction +): + """Test that st.checkbox renders correctly.""" + checkbox_elements = themed_app.locator(".stCheckbox") + expect(checkbox_elements).to_have_count(8) + + for i, element in enumerate(checkbox_elements.all()): + assert_snapshot(element, name=f"checkbox-{i}") + + +def test_checkbox_initial_values(app: Page): + """Test that st.checkbox has the correct initial values.""" + markdown_elements = app.locator(".stMarkdown") + expect(markdown_elements).to_have_count(9) + + expected = [ + "checkbox 1 - value: True", + "checkbox 2 - value: False", + "checkbox 3 - value: False", + "checkbox 4 - value: False", + "checkbox 4 - clicked: False", + "checkbox 5 - value: False", + "checkbox 6 - value: True", + "checkbox 7 - value: False", + "checkbox 8 - value: False", + ] + + for markdown_element, expected_text in zip(markdown_elements.all(), expected): + expect(markdown_element).to_have_text(expected_text, use_inner_text=True) + + +def test_checkbox_values_on_click(app: Page): + """Test that st.checkbox updates values correctly when user clicks.""" + checkbox_elements = app.locator(".stCheckbox") + expect(checkbox_elements).to_have_count(8) + + for checkbox_element in checkbox_elements.all(): + checkbox_element.click(delay=50) + + markdown_elements = app.locator(".stMarkdown") + expected = [ + "checkbox 1 - value: False", + "checkbox 2 - value: True", + "checkbox 3 - value: True", + "checkbox 4 - value: True", + "checkbox 4 - clicked: True", + "checkbox 5 - value: False", + "checkbox 6 - value: True", + "checkbox 7 - value: True", + "checkbox 8 - value: True", + ] + + for markdown_element, expected_text in zip(markdown_elements.all(), expected): + expect(markdown_element).to_have_text(expected_text, use_inner_text=True) diff --git a/e2e/playwright/st_code.py b/e2e/playwright/st_code.py new file mode 100644 index 000000000000..fe8c3eafe556 --- /dev/null +++ b/e2e/playwright/st_code.py @@ -0,0 +1,38 @@ +# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) +# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import streamlit as st + +st.code("# This code is awesome!") + +st.code("") + +code = """ +def hello(): + print("Hello, Streamlit!") +""" +st.code(code, language="python") + +st.code(code, language="python", line_numbers=True) + +st.code("PLAIN TEXT", language=None, line_numbers=True) + +with st.expander("`st.code` usage", expanded=True): + st.code(code, language="python") + st.code(code, language="python") + +with st.expander("`st.markdown` code usage", expanded=True): + st.markdown("```python\n" + code + "\n```") + st.markdown("```python\n" + code + "\n```") diff --git a/e2e/playwright/st_code_test.py b/e2e/playwright/st_code_test.py new file mode 100644 index 000000000000..0aa65af2fca8 --- /dev/null +++ b/e2e/playwright/st_code_test.py @@ -0,0 +1,52 @@ +# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) +# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from playwright.sync_api import Page, expect + +from conftest import ImageCompareFunction + + +def test_code_display(app: Page): + """Test that st.code displays a code block.""" + code_element = app.locator(".element-container pre").first + expect(code_element).to_contain_text("This code is awesome!") + + +def test_syntax_highlighting(themed_app: Page, assert_snapshot: ImageCompareFunction): + """Test that the copy-to-clipboard action appears on hover.""" + first_code_element = themed_app.locator(".element-container:first-child pre").first + first_code_element.hover() + assert_snapshot(first_code_element, name="syntax_highlighting-hover") + + +def test_code_blocks_render_correctly( + themed_app: Page, assert_snapshot: ImageCompareFunction +): + """Test that the code blocks render as expected via screenshot matching.""" + code_blocks = themed_app.get_by_test_id("stCodeBlock") + + assert_snapshot(code_blocks.nth(0), name="st_code-auto_lang") + assert_snapshot(code_blocks.nth(1), name="st_code-empty") + assert_snapshot(code_blocks.nth(2), name="st_code-python_lang") + assert_snapshot(code_blocks.nth(3), name="st_code-line_numbers") + assert_snapshot(code_blocks.nth(4), name="st_code-no_lang") + + +def test_code_in_markdown(app: Page, assert_snapshot: ImageCompareFunction): + """Test that the syntax highlighting is applied correctly to the code block.""" + expander_with_code = app.get_by_test_id("stExpander") + + assert_snapshot(expander_with_code.nth(0), name="expander_with_code") + assert_snapshot(expander_with_code.nth(1), name="expander_with_markdown_code") diff --git a/e2e/playwright/st_data_editor_config.py b/e2e/playwright/st_data_editor_config.py new file mode 100644 index 000000000000..77c72f16e3d3 --- /dev/null +++ b/e2e/playwright/st_data_editor_config.py @@ -0,0 +1,420 @@ +# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import datetime +import random + +import numpy as np +import pandas as pd + +import streamlit as st + +np.random.seed(0) +random.seed(0) + +st.set_page_config(layout="wide") + +# Generate a random dataframe +df = pd.DataFrame( + np.random.randn(5, 5), + columns=("col_%d" % i for i in range(5)), +) + +st.header("Disabled parameter:") +st.data_editor(df, disabled=True) +st.data_editor(df, disabled=["col_4", "col_1"]) + +st.header("Hide index parameter:") +st.data_editor(df, hide_index=True) +st.data_editor(df, hide_index=False) + +st.header("Column order parameter:") +st.data_editor(df, column_order=["col_4", "col_3", "col_0"]) + +st.header("Set column labels:") +st.data_editor( + df, + column_config={ + "_index": "Index column", + "col_0": "Column 0", + "col_2": st.column_config.Column("Column 1"), + }, +) + +st.header("Hide columns:") +st.data_editor(df, column_config={"col_1": None, "col_3": {"hidden": True}}) + +st.header("Set column width:") +st.data_editor( + df, + column_config={ + "col_0": st.column_config.Column(width="small"), + "col_1": st.column_config.Column(width="medium"), + "col_4": {"width": "large"}, + }, +) + +st.header("Set help tooltips:") +st.caption("Hover over the column headers to see the tooltips.") +st.data_editor( + pd.DataFrame( + { + "col_0": ["a", "b", "c", None], + } + ), + column_config={ + "col_0": st.column_config.Column(help="This :red[is] a **tooltip** 🌟"), + "_index": {"help": "Index tooltip!"}, + }, +) + + +st.header("Ignore editing-only config options:") +st.data_editor( + pd.DataFrame( + { + "col_0": ["a", "b", "c", None], + } + ), + column_config={"col_0": st.column_config.Column(disabled=False, required=True)}, +) + + +st.header("Text column:") +st.caption( + "Editing the first column should only allow 5 characters. The second column should only allow numerical characters." +) +st.data_editor( + pd.DataFrame( + { + "col_0": ["Hello World", "Lorem ipsum", "", None], + "col_1": ["1", "2", "3", None], + } + ), + column_config={ + "col_0": st.column_config.TextColumn( + "Text column", + width="medium", + help="This is a text column", + required=True, + disabled=False, + default="invalid", + max_chars=5, + ), + "col_1": st.column_config.TextColumn( + validate="^[0-9]+$", + ), + }, +) + +st.header("Number column:") +st.caption( + "Editing the first column should only allow to submit numbers between 0 and 5. And only a maximum of 2 decimals." +) +st.data_editor( + pd.DataFrame( + { + "col_0": [1, 2, 3, None], + "col_1": ["1", "2", "invalid", None], + } + ), + column_config={ + "col_0": st.column_config.NumberColumn( + "Number column", + width="medium", + help="This is a number column", + required=True, + disabled=False, + default=0, + min_value=5, + max_value=10, + step=0.01, + ), + "col_1": st.column_config.NumberColumn( + format="%.2f%%", + ), + }, +) + +st.header("Checkbox column:") +st.data_editor( + pd.DataFrame( + { + "col_0": [True, False, False, None], + "col_1": ["yes", "no", "invalid", None], + } + ), + column_config={ + "col_0": st.column_config.CheckboxColumn( + "Checkbox column", + width="medium", + help="This is a checkbox column", + required=True, + disabled=False, + default=True, + ), + "col_1": st.column_config.CheckboxColumn(), + }, +) + +st.header("Selectbox column:") + +st.data_editor( + pd.DataFrame( + { + "col_0": [1, 2, 3, None], + "col_1": ["a", "b", "c", None], + } + ), + column_config={ + "col_0": st.column_config.SelectboxColumn( + "Selectbox column", + width="medium", + help="This is a selectbox column", + required=True, + disabled=False, + default=True, + options=[1, 2, 3, 4, 5], + ), + "col_1": st.column_config.SelectboxColumn(), + }, +) + +st.header("Link column:") +st.caption( + "Editing the first column should only submitting values starting with http and a maximum of 50 characters." +) +st.data_editor( + pd.DataFrame( + { + "col_0": [ + "https://streamlit.io/", + "https://docs.streamlit.io/", + "https://streamlit.io/gallery", + None, + ], + "col_1": ["/a", "/b", "", None], + } + ), + column_config={ + "col_0": st.column_config.LinkColumn( + "Link column", + width="medium", + help="This is a link column", + required=True, + disabled=False, + default="https://streamlit.io/", + max_chars=50, + validate="^http.*$", + ), + "col_1": st.column_config.LinkColumn(), + }, +) + +st.header("Datetime column:") +st.caption( + "Editing the first column should only allow datetime values between 2021-01-01 and 2022-01-01." +) +st.data_editor( + pd.DataFrame( + { + "col_0": [ + datetime.datetime(2021, 1, 1, 1, 0, 0, 123000), + datetime.datetime(2022, 1, 2, 2, 0, 0, 234000), + datetime.datetime(2023, 1, 3, 3, 0, 0, 345000), + None, + ], + } + ), + column_config={ + "col_0": st.column_config.DatetimeColumn( + "Datetime column", + width="medium", + help="This is a datetime column", + required=True, + disabled=False, + default=datetime.datetime(2021, 1, 1, 1, 0, 0), + min_value=datetime.datetime(2021, 1, 1, 1, 0, 0), + max_value=datetime.datetime(2022, 1, 1, 1, 0, 0), + step=0.01, + format="YYYY-MM-DD HH:mm:ss.SSS", + ), + }, +) + +st.header("Date column:") +st.caption( + "Editing the first column should only allow picking every second day and between 2021-01-01 and 2022-01-01." +) +st.data_editor( + pd.DataFrame( + { + "col_0": [ + datetime.date(2021, 1, 1), + datetime.date(2022, 1, 2), + datetime.date(2023, 1, 3), + None, + ], + } + ), + column_config={ + "col_0": st.column_config.DateColumn( + "Date column", + width="medium", + help="This is a date column", + required=True, + disabled=False, + default=datetime.date(2021, 1, 1), + min_value=datetime.date(2021, 1, 1), + max_value=datetime.date(2022, 1, 1), + step=2, + ), + }, +) + +st.header("Time column:") +st.caption( + "Editing the first column should only allow datetime values between 01:02 and 01:03." +) +st.data_editor( + pd.DataFrame( + { + "col_0": [ + datetime.time(1, 2, 0, 123000), + datetime.time(2, 3, 0, 234000), + datetime.time(3, 4, 0, 345000), + None, + ] + } + ), + column_config={ + "col_0": st.column_config.TimeColumn( + "Time column", + width="medium", + help="This is a time column", + required=True, + disabled=False, + default=datetime.time(1, 2, 0), + min_value=datetime.time(1, 2, 0), + max_value=datetime.time(1, 3, 0), + step=datetime.timedelta(milliseconds=1), + ), + }, +) + +st.header("Progress column:") + +st.data_editor( + pd.DataFrame( + { + "col_0": [0.1, 0.4, 1.1, None], + "col_1": ["200", "550", "1000", None], + } + ), + column_config={ + "col_0": st.column_config.ProgressColumn( + "Progress column", + width="medium", + help="This is a progress column", + ), + "col_1": st.column_config.ProgressColumn( + format="$%f", min_value=0, max_value=1000 + ), + }, +) + +st.header("List column:") + +st.data_editor( + pd.DataFrame( + { + "col_0": [[1, 2], [2, 3, 4], [], None], + "col_1": ["a,b", "c,d,e", "", None], + } + ), + column_config={ + "col_0": st.column_config.ListColumn( + "List column", + width="medium", + help="This is a list column", + ), + "col_1": st.column_config.ListColumn(), + }, +) + +st.header("Bar chart column:") + +st.data_editor( + pd.DataFrame( + { + "col_0": [[1, 5, 2], [2, 3, 5, -4, -5], [], None], + "col_1": ["1,2,3,4", "6, 5, 1, 10", "invalid", None], + } + ), + column_config={ + "col_0": st.column_config.BarChartColumn( + "Bar chart column", + width="medium", + help="This is a bar chart column", + y_min=-5, + y_max=5, + ), + "col_1": st.column_config.BarChartColumn(), + }, +) + + +st.header("Line chart column:") + +st.data_editor( + pd.DataFrame( + { + "col_0": [[1, 5, 2], [2, 3, 5, -4, -5], [], None], + "col_1": ["1,2,3,4", "6, 5, 1, 10", "invalid", None], + } + ), + column_config={ + "col_0": st.column_config.LineChartColumn( + "Line chart column", + width="medium", + help="This is a line chart column", + y_min=-5, + y_max=5, + ), + "col_1": st.column_config.LineChartColumn(), + }, +) + +st.header("Image column:") + +st.data_editor( + pd.DataFrame( + { + "col_0": [ + # "https://streamlit.io/images/brand/streamlit-mark-color.png", # TODO: Makes the test flaky + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAABSCAMAAACBpt1yAAAAwFBMVEVHcEyAhJWAhJUzNT97f4+AhJWAhJVtcH9WWWaAhJWAhJWAhJVCRFGAhJWAhJWAhJVVWGeAhJWAhJWAhJVVWGcmJzCAhJWAhJWAhJUmJzAmJzBVWGcmJzAmJzAmJzAmJzAmJzCAhJUmJzBVWGcmJzAmJzAmJzBVWGeAhJVVWGdVWGdVWGeAhJVVWGdVWGdVWGdvcoJVJ2WAhJVVWGcmJzBTVmVaXWx8f5B1eYlhZHNoa3tDRVI3OUQtLzhucoJMT13kXsyQAAAAMXRSTlMA+SYWE/ExBQvmfME1P7Uc9lhpjSdsTZ7cnETlsyP6xvHNg7XXV+bYq6NjTtR1yJLh8/IzCQAABHhJREFUaN7Nmut2mkAYRZGLIMQbRMFbvMQYkmjS9YFJU23z/m9VwEpgGJgZYLo4/2ratXbdhyNMFIS68jzzXm+EpuVl5nne623DqKRXL8yb2iyst4jKG7w0S+HgguU93jZPYZin5mhU32Iqb/DcPIWN0phQGGnUGqewQRpTChuj8fbVQ1ODRnVsDeUaFVbXuBhtpsJYgZYxLP3fUzMKK2qURlvf3wkWBGn1xiVX8PbRw6WsRmm09MOE71YYxe2qNSmMUkqj9rC8i6hWgmzAJYrdVqtfhRU0ag/zC5TvzwVBh2s6drsehWHuGTVq0xjKXz0IgtiBbzBLZFL45OWHSaM6naz8OEspeMWGRBydAex5UIA1Y7iDvklC+f4ofG3cSnLBXu9XV8ik8WayS0L5u0X4qryGdNYm1b5qT4VU3uBAt56bNJTvTy6Xng5o1jTDX6iQVuNis0Wg/Lvp5UftToaLYvgJCqk0RpOOJix8dBm4kA1p+EkKoxyoJh3J5vrzYQvDRRh+okKSRuk66Uh28b/JlD4e/m4FhZFGmTzp+MLjS08YfiqF+RqTk44W/uH7r2FKXzz8VArzNKrT+crPy7XwuaWPwbLDfzPzaJPRqCKTnlf4/NJ/fyKlh1+79+hzKJ703MKH6e+hMPvU8B8YqNIas5OOZJ6eOgsISXwiMShMa8RMekHhw3QVElc8/EwKExqxk45kKyFF7AEx/4b/wEjlzV4ooZDChzGBIsHwsyqMNEpazqQjWU1RrL4DVGD2vXdk55rTQGUKT1X6a/58MmN9namo7kbZ7SWX/pqPP+/MXL9psLYLzOeUAdT5+MUIdjzRvFkT3OenCcAP7HguU/gwosPCBT9/vTN0/0jWeLfE38zaABzByBpH+Fsz+tLHYJ/Ua3Ekatwt8FiyAcARjKRxkneLbgJwBCNcjfjClyh9PGOfdVyNSyn3acQGKAf2Xl3jKP8hadwCrmAn2tvS6qVnASvQOCl6WNahfGiGP1cjeluKlL5TgYtmX0/shRfQMzgOYHkaN8VnKKVLTztjeI07wplT3nFEfWBYjXPSIbcOwBnszFp4wnFETcOP0biViEfRLgBnsBNr4cnHEbXsK6pxRXHIWkPpSfuKapzTHJXrALzBToyFD8vVVoA72Jn0HMat9IXDn9K4EahSV+mLZuyL5rYUOY7YA/AGS3w2zml/N2QBcAc7/qa4La36ZEa3r0fc1UhX+Og4ogfABwxzNU7of+1oAvABe89opC08wxlcxRn7It+W8i89BuzMUnhepU+AHWONuwULlmYAx8TD/1X8HPbfSo/M2PE0ZaIqeRzBDMb6JQ7BbAF/sBnzt41VXeHN9fGjxJdn1bHBF0xx20KZyF3d7hn7jlKvz5bi7A3X1rsVvqqnarLYHg9N3XIDQqejlGJsKUrHWRs929LNYbctylpt3+VVVVnui+1uwBhAWrbb6xnGer13HKeTSvCCs1+vDaPnurYVgJjDcYDSr5GlEDN4J+V+EFEU23GCP4jBa7IcUKilOf4CgQRuuzC9EJcAAAAASUVORK5CYII=", + "data:image/svg+xml,%3Csvg width='301' height='165' viewBox='0 0 301 165' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M150.731 101.547L98.1387 73.7471L6.84674 25.4969C6.7634 25.4136 6.59674 25.4136 6.51341 25.4136C3.18007 23.8303 -0.236608 27.1636 1.0134 30.497L47.5302 149.139L47.5385 149.164C47.5885 149.281 47.6302 149.397 47.6802 149.514C49.5885 153.939 53.7552 156.672 58.2886 157.747C58.6719 157.831 58.9461 157.906 59.4064 157.998C59.8645 158.1 60.5052 158.239 61.0552 158.281C61.1469 158.289 61.2302 158.289 61.3219 158.297H61.3886C61.4552 158.306 61.5219 158.306 61.5886 158.314H61.6802C61.7386 158.322 61.8052 158.322 61.8636 158.322H61.9719C62.0386 158.331 62.1052 158.331 62.1719 158.331V158.331C121.084 164.754 180.519 164.754 239.431 158.331V158.331C240.139 158.331 240.831 158.297 241.497 158.231C241.714 158.206 241.922 158.181 242.131 158.156C242.156 158.147 242.189 158.147 242.214 158.139C242.356 158.122 242.497 158.097 242.639 158.072C242.847 158.047 243.056 158.006 243.264 157.964C243.681 157.872 243.87 157.806 244.436 157.611C245.001 157.417 245.94 157.077 246.527 156.794C247.115 156.511 247.522 156.239 248.014 155.931C248.622 155.547 249.201 155.155 249.788 154.715C250.041 154.521 250.214 154.397 250.397 154.222L250.297 154.164L150.731 101.547Z' fill='%23FF4B4B'/%3E%3Cpath d='M294.766 25.4981H294.683L203.357 73.7483L254.124 149.357L300.524 30.4981V30.3315C301.691 26.8314 298.108 23.6648 294.766 25.4981' fill='%237D353B'/%3E%3Cpath d='M155.598 2.55572C153.264 -0.852624 148.181 -0.852624 145.931 2.55572L98.1389 73.7477L150.731 101.548L250.398 154.222C251.024 153.609 251.526 153.012 252.056 152.381C252.806 151.456 253.506 150.465 254.123 149.356L203.356 73.7477L155.598 2.55572Z' fill='%23BD4043'/%3E%3C/svg%3E%0A", + "", + None, + ], + } + ), + column_config={ + "col_0": st.column_config.ImageColumn( + "Image column", + width="medium", + help="This is a image column", + ), + }, +) diff --git a/e2e/playwright/st_data_editor_config_test.py b/e2e/playwright/st_data_editor_config_test.py new file mode 100644 index 000000000000..78d395eeadec --- /dev/null +++ b/e2e/playwright/st_data_editor_config_test.py @@ -0,0 +1,31 @@ +# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from playwright.sync_api import Page, expect + +from conftest import ImageCompareFunction + + +def test_data_editor_supports_various_configurations( + app: Page, assert_snapshot: ImageCompareFunction +): + """Screenshot test that st.data_editor supports various configuration options.""" + dataframe_elements = app.locator(".stDataFrame") + expect(dataframe_elements).to_have_count(23) + + # The data editor might require a bit more time for rendering the canvas + app.wait_for_timeout(250) + + for i, element in enumerate(dataframe_elements.all()): + assert_snapshot(element, name=f"data_editor-config-{i}") diff --git a/e2e/playwright/st_expander.py b/e2e/playwright/st_expander.py new file mode 100644 index 000000000000..c68476d78205 --- /dev/null +++ b/e2e/playwright/st_expander.py @@ -0,0 +1,28 @@ +# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import streamlit as st + +expander = st.expander("Collapse me!", expanded=True) +expander.write("I can collapse") +expander.slider("I don't get cut off") +expander.button("I'm also not cut off (while focused)") + +collapsed = st.expander("Expand me!") +collapsed.write("I am already collapsed") + +sidebar = st.sidebar.expander("Expand me!") +sidebar.write("I am in the sidebar") + +st.expander("Empty expander") diff --git a/e2e/playwright/st_expander_nested.py b/e2e/playwright/st_expander_nested.py new file mode 100644 index 000000000000..3db0ce5b2dbd --- /dev/null +++ b/e2e/playwright/st_expander_nested.py @@ -0,0 +1,22 @@ +# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import streamlit as st + +level1 = st.expander("See explanation") +level1.write("First level expander") +level1.image("https://static.streamlit.io/examples/dice.jpg") + +level2 = level1.expander("Nested expander") +level2.write("Second level expander") diff --git a/e2e/playwright/st_expander_nested_test.py b/e2e/playwright/st_expander_nested_test.py new file mode 100644 index 000000000000..7668c9435e2b --- /dev/null +++ b/e2e/playwright/st_expander_nested_test.py @@ -0,0 +1,24 @@ +# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from playwright.sync_api import Page, expect + + +def test_nested_expanders(app: Page): + """Test that st.expander may not be nested inside other expanders.""" + exception_message = app.locator(".stException .message") + + expect(exception_message).to_have_text( + "StreamlitAPIException: Expanders may not be nested inside other expanders." + ) diff --git a/e2e/playwright/st_expander_state.py b/e2e/playwright/st_expander_state.py new file mode 100644 index 000000000000..11ef7b2faadb --- /dev/null +++ b/e2e/playwright/st_expander_state.py @@ -0,0 +1,26 @@ +# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import streamlit as st + +b0 = st.button("b0") +b1 = st.button("b1") + +if b0: + with st.expander("b0_expander", expanded=False): + st.write("b0_write") + +if b1: + with st.expander("b1_expander", expanded=False): + st.write("b1_write") diff --git a/e2e/playwright/st_expander_state_test.py b/e2e/playwright/st_expander_state_test.py new file mode 100644 index 000000000000..b7bd6017b890 --- /dev/null +++ b/e2e/playwright/st_expander_state_test.py @@ -0,0 +1,28 @@ +# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from playwright.sync_api import Page, expect + + +def test_expandable_state(app: Page): + """Test whether expander state is not retained for a distinct expander.""" + app.locator(".stButton button").nth(0).click() + app.locator("[data-testid='stExpander']").click() + + expect(app.locator("[data-testid='stExpander']")).to_contain_text("b0_write") + + app.locator(".stButton button").nth(1).click() + + expect(app.locator("[data-testid='stExpander']")).not_to_contain_text("b0_write") + expect(app.locator("[data-testid='stExpander']")).not_to_contain_text("b1_write") diff --git a/e2e/playwright/st_expander_test.py b/e2e/playwright/st_expander_test.py new file mode 100644 index 000000000000..34800e289770 --- /dev/null +++ b/e2e/playwright/st_expander_test.py @@ -0,0 +1,77 @@ +# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from playwright.sync_api import Page, expect + +from conftest import ImageCompareFunction + +EXPANDER_HEADER_IDENTIFIER = ".streamlit-expanderHeader" + + +def test_displays_expander_and_regular_containers_properly(app: Page): + """Test that expanders and regular containers are displayed properly.""" + + main_expanders = app.locator(".main [data-testid='stExpander']") + expect(main_expanders).to_have_count(2) + + for expander in main_expanders.all(): + expect(expander.locator(EXPANDER_HEADER_IDENTIFIER)).to_be_visible() + + sidebar_expander = app.locator( + "[data-testid='stSidebar'] [data-testid='stExpander']" + ).first + expect(sidebar_expander.locator(EXPANDER_HEADER_IDENTIFIER)).to_be_visible() + + +def test_expander_displays_correctly( + themed_app: Page, assert_snapshot: ImageCompareFunction +): + """Test that sidebar and main container expanders are displayed correctly.""" + # Focus the button, then ensure it's not cut off + themed_app.locator(".stButton button").focus() + assert_snapshot(themed_app.locator(".main"), name="expanders-in-main") + assert_snapshot( + themed_app.locator("[data-testid='stSidebar']"), + name="expanders-in-sidebar", + ) + + +def test_expander_collapses_and_expands(app: Page): + """Test that an expander collapses and expands.""" + main_expanders = app.locator(".main [data-testid='stExpander']") + expect(main_expanders).to_have_count(2) + + expanders = main_expanders.all() + # Starts expanded + expander_header = expanders[0].locator(EXPANDER_HEADER_IDENTIFIER) + expect(expander_header).to_be_visible() + toggle = expander_header.locator("svg").first + expect(toggle).to_be_visible() + expander_header.click() + toggle = expander_header.locator("svg").first + expect(toggle).to_be_visible() + + # Starts collapsed + expander_header = expanders[1].locator(EXPANDER_HEADER_IDENTIFIER) + expect(expander_header).to_be_visible() + toggle = expander_header.locator("svg").first + expect(toggle).to_be_visible() + expander_header.click() + toggle = expander_header.locator("svg").first + expect(toggle).to_be_visible() + + +def test_empty_expander_not_rendered(app: Page): + """Test that an empty expander is not rendered.""" + expect(app.get_by_text("Empty expander")).not_to_be_attached() diff --git a/e2e/playwright/st_headings_divider.py b/e2e/playwright/st_headings_divider.py new file mode 100644 index 000000000000..7091ff0d06a5 --- /dev/null +++ b/e2e/playwright/st_headings_divider.py @@ -0,0 +1,66 @@ +# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import streamlit as st + +# Headers with specified colors +st.header("Blue Divider:", divider="blue") +st.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit") + +st.header("Green Divider:", divider="green") +st.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit") + +st.header("Orange Divider:", divider="orange") +st.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit") + +st.header("Red Divider:", divider="red") +st.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit") + +st.header("Violet Divider:", divider="violet") +st.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit") + +st.header("Gray Divider:", divider="gray") +st.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit") + +st.header("Rainbow Divider:", divider="rainbow") +st.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit") + +st.header("Grey Divider:", divider="grey") +st.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit") + + +# Subheaders with specified colors +st.subheader("Blue Divider:", divider="blue") +st.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit") + +st.subheader("Green Divider:", divider="green") +st.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit") + +st.subheader("Orange Divider:", divider="orange") +st.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit") + +st.subheader("Red Divider:", divider="red") +st.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit") + +st.subheader("Violet Divider:", divider="violet") +st.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit") + +st.subheader("Gray Divider:", divider="gray") +st.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit") + +st.subheader("Rainbow Divider:", divider="rainbow") +st.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit") + +st.subheader("Grey Divider:", divider="grey") +st.write("Lorem ipsum dolor sit amet, consectetur adipiscing elit") diff --git a/e2e/playwright/st_headings_divider_test.py b/e2e/playwright/st_headings_divider_test.py new file mode 100644 index 000000000000..3714c955c092 --- /dev/null +++ b/e2e/playwright/st_headings_divider_test.py @@ -0,0 +1,38 @@ +# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +from playwright.sync_api import Page, expect + +from conftest import ImageCompareFunction + + +def test_header_display(app: Page, assert_snapshot: ImageCompareFunction): + """Test that st.header renders correctly with dividers.""" + header_elements = app.locator(".stHeadingContainer") + expect(header_elements).to_have_count(16) + + for i, element in enumerate(header_elements.all()): + if i < 8: + assert_snapshot(element, name=f"header-divider-{i}") + + +def test_subheader_display(app: Page, assert_snapshot: ImageCompareFunction): + """Test that st.subheader renders correctly with dividers.""" + subheader_elements = app.locator(".stHeadingContainer") + expect(subheader_elements).to_have_count(16) + + for i, element in enumerate(subheader_elements.all()): + if i > 7: + assert_snapshot(element, name=f"subheader-divider-{i}") diff --git a/e2e/playwright/st_metric.py b/e2e/playwright/st_metric.py new file mode 100644 index 000000000000..1ed651084fc6 --- /dev/null +++ b/e2e/playwright/st_metric.py @@ -0,0 +1,47 @@ +# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import streamlit as st + +col1, col2, col3 = st.columns(3) + +with col1: + st.metric("User growth", 123, 123, "normal") +with col2: + st.metric("S&P 500", -4.56, -50) +with col3: + st.metric("Apples I've eaten", "23k", " -20", "off") + +with col1: + st.metric("Test 3", -4.56, 1.23, label_visibility="visible") +with col2: + st.metric("Test 4", -4.56, 1.23, label_visibility="hidden") +with col3: + st.metric("Test 5", -4.56, 1.23, label_visibility="collapsed") + +st.metric( + "User growth and a relatively long title", 123, help="testing help without a column" +) + +st.metric("label title", None, None, help="testing help without a column") + +col1, col2, col3, col4, col5, col6, col7, col8 = st.columns(8) + +with col1: + st.metric( + label="Example metric", + help="Something should feel right", + value=150.59, + delta="Very high", + ) diff --git a/e2e/playwright/st_metric_test.py b/e2e/playwright/st_metric_test.py new file mode 100644 index 000000000000..238f7177b71e --- /dev/null +++ b/e2e/playwright/st_metric_test.py @@ -0,0 +1,112 @@ +# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from playwright.sync_api import Page, expect + +from conftest import ImageCompareFunction + + +def test_first_metric_in_first_row(app: Page): + expect(app.locator("[data-testid='stMetricLabel']").nth(0)).to_have_text( + "User growth" + ) + expect(app.locator("[data-testid='stMetricValue']").nth(0)).to_have_text(" 123 ") + expect(app.locator("[data-testid='stMetricDelta']").nth(0)).to_have_text(" 123 ") + + +def test_second_metric_in_first_row(app: Page): + expect(app.locator("[data-testid='stMetricLabel']").nth(2)).to_have_text("S&P 500") + expect(app.locator("[data-testid='stMetricValue']").nth(2)).to_have_text(" -4.56 ") + expect(app.locator("[data-testid='stMetricDelta']").nth(2)).to_have_text(" -50 ") + + +def test_third_metric_in_first_row(app: Page): + expect(app.locator("[data-testid='stMetricLabel']").nth(4)).to_have_text( + "Apples I've eaten" + ) + expect(app.locator("[data-testid='stMetricValue']").nth(4)).to_have_text(" 23k ") + expect(app.locator("[data-testid='stMetricDelta']").nth(4)).to_have_text(" -20 ") + + +def test_green_up_arrow_render(themed_app: Page, assert_snapshot: ImageCompareFunction): + assert_snapshot( + themed_app.locator('[data-testid="metric-container"]').nth(0), + name="metric-container-green", + ) + + +def test_red_down_arrow_render(themed_app: Page, assert_snapshot: ImageCompareFunction): + assert_snapshot( + themed_app.locator('[data-testid="metric-container"]').nth(2), + name="metric-container-red", + ) + + +def test_gray_down_arrow_render( + themed_app: Page, assert_snapshot: ImageCompareFunction +): + assert_snapshot( + themed_app.locator('[data-testid="metric-container"]').nth(4), + name="metric-container-gray", + ) + + +def test_help_shows_up_without_columns( + themed_app: Page, assert_snapshot: ImageCompareFunction +): + assert_snapshot( + themed_app.locator('[data-testid="metric-container"]').nth(6), + name="metric-with-help", + ) + + +def test_none_results_in_dash_in_value( + themed_app: Page, assert_snapshot: ImageCompareFunction +): + assert_snapshot( + themed_app.locator('[data-testid="metric-container"]').nth(7), + name="metric-with-none-value", + ) + + +def test_label_visibility_set_to_hidden( + themed_app: Page, assert_snapshot: ImageCompareFunction +): + expect(themed_app.locator("[data-testid='stMetricLabel']").nth(3)).to_have_text( + "Test 4" + ) + assert_snapshot( + themed_app.locator('[data-testid="metric-container"]').nth(3), + name="metric-label-hidden", + ) + + +def test_label_visibility_set_to_collapse( + themed_app: Page, assert_snapshot: ImageCompareFunction +): + expect(themed_app.locator("[data-testid='stMetricLabel']").nth(5)).to_have_text( + "Test 5" + ) + assert_snapshot( + themed_app.locator('[data-testid="metric-container"]').nth(5), + name="metric-label-collapse", + ) + + +def test_ellipses_and_help_shows_up_properly( + themed_app: Page, assert_snapshot: ImageCompareFunction +): + assert_snapshot( + themed_app.locator('[data-testid="metric-container"]').nth(8), + name="metric-help-and-ellipses", + ) diff --git a/e2e/playwright/st_multiselect.py b/e2e/playwright/st_multiselect.py new file mode 100644 index 000000000000..8ba1eb604492 --- /dev/null +++ b/e2e/playwright/st_multiselect.py @@ -0,0 +1,84 @@ +# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import Any, List + +import streamlit as st +from streamlit import runtime +from tests.streamlit import pyspark_mocks + + +def set_multiselect_9_to_have_bad_state(): + if "multiselect 9" in st.session_state: + st.session_state["multiselect 9"] = ["male", "female"] + + +options = ("male", "female") + +i1 = st.multiselect("multiselect 1", options, placeholder="Please select") +st.text(f"value 1: {i1}") + +i2 = st.multiselect("multiselect 2", options, format_func=lambda x: x.capitalize()) +st.text(f"value 2: {i2}") + +i3: List[Any] = st.multiselect("multiselect 3", []) +st.text(f"value 3: {i3}") + +i4 = st.multiselect("multiselect 4", ["coffee", "tea", "water"], ["tea", "water"]) +st.text(f"value 4: {i4}") + +i5 = st.multiselect( + "multiselect 5", + list( + map( + lambda x: f"{x} I am a ridiculously long string to have in a multiselect, so perhaps I should just not wrap and go to the next line.", + range(5), + ) + ), +) +st.text(f"value 5: {i5}") + +i6 = st.multiselect("multiselect 6", options, disabled=True) +st.text(f"value 6: {i6}") + +i7 = st.multiselect("Hidden label", options, label_visibility="hidden") +st.text(f"value 7: {i7}") + +i8 = st.multiselect("Collapsed label", options, label_visibility="collapsed") +st.text(f"value 8: {i8}") + +set_multiselect_9 = st.checkbox( + "set_multiselect_9", on_change=set_multiselect_9_to_have_bad_state +) + +i9 = st.multiselect("multiselect 9", options, max_selections=1, key="multiselect 9") +st.text(f"value 9: {i9}") + +with st.form("my_max_selections_ms_in_form"): + i10 = st.multiselect( + "multiselect 10", options, max_selections=1, key="multiselect 10" + ) + st.text(f"value 10: {i10}") + submitted = st.form_submit_button("Submit") + +if runtime.exists(): + + def on_change(): + st.session_state.multiselect_changed = True + + st.multiselect("multiselect 11", options, key="multiselect11", on_change=on_change) + st.text(f"value 11: {st.session_state.multiselect11}") + st.text(f"multiselect changed: {'multiselect_changed' in st.session_state}") + +st.multiselect("PySpark DataFrame", options=pyspark_mocks.DataFrame()) # type: ignore diff --git a/e2e/playwright/st_multiselect_test.py b/e2e/playwright/st_multiselect_test.py new file mode 100644 index 000000000000..97211847f8f8 --- /dev/null +++ b/e2e/playwright/st_multiselect_test.py @@ -0,0 +1,214 @@ +# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from playwright.sync_api import Page, expect + +from conftest import ImageCompareFunction + + +def select_for_kth_multiselect( + page: Page, option_text: str, k: int, close_after_selecting: bool +) -> None: + """Select an option from a multiselect widget. + + Parameters + ---------- + page : Page + The playwright page to use. + option_text : str + The text of the option to select. + k : int + The index of the multiselect widget to select from. + close_after_selecting : bool + Whether to close the dropdown after selecting the option. + """ + + multiselect_elem = page.locator(".stMultiSelect").nth(k) + multiselect_elem.locator("input").click() + page.locator("li").filter(has_text=option_text).first.click() + if close_after_selecting: + page.keyboard.press("Escape") + + +def del_from_kth_multiselect(page: Page, option_text: str, k: int): + """Delete an option from a multiselect widget. + + Parameters + ---------- + page : Page + The playwright page to use. + option_text : str + The text of the option to delete. + k : int + The index of the multiselect widget to delete from. + """ + multiselect_elem = page.locator(".stMultiSelect").nth(k) + multiselect_elem.locator( + f'span[data-baseweb="tag"] span[title="{option_text}"] + span[role="presentation"]' + ).first.click() + + +def test_multiselect_on_load(themed_app: Page, assert_snapshot: ImageCompareFunction): + """Should show widgets correctly when loaded.""" + multiselect_elements = themed_app.locator(".stMultiSelect") + expect(multiselect_elements).to_have_count(12) + for idx, el in enumerate(multiselect_elements.all()): + assert_snapshot(el, name="multiselect-" + str(idx)) + + +def test_multiselect_initial_value(app: Page): + """Should show the correct initial values.""" + text_elements = app.locator("[data-testid='stText']") + expect(text_elements).to_have_count(12) + text_elements = text_elements.all_inner_texts() + texts = [text.strip() for text in text_elements] + + expected = [ + "value 1: []", + "value 2: []", + "value 3: []", + "value 4: ['tea', 'water']", + "value 5: []", + "value 6: []", + "value 7: []", + "value 8: []", + "value 9: []", + "value 10: []", + "value 11: []", + "multiselect changed: False", + ] + assert texts == expected + + +def test_multiselect_clear_all(app: Page): + """Should clear all options when clicking clear all.""" + select_for_kth_multiselect(app, "Female", 1, True) + app.locator('.stMultiSelect [role="button"][aria-label="Clear all"]').first.click() + expect(app.locator("[data-testid='stText']").nth(1)).to_have_text("value 2: []") + + +def test_multiselect_show_values_in_dropdown( + app: Page, assert_snapshot: ImageCompareFunction +): + """Screenshot test to check that values are shown in dropdown.""" + multiselect_elem = app.locator(".stMultiSelect").nth(0) + multiselect_elem.locator("input").click() + dropdown_elems = app.locator("li").all() + assert len(dropdown_elems) == 2 + for idx, el in enumerate(dropdown_elems): + assert_snapshot(el, name="multiselect-dropdown-" + str(idx)) + + +def test_multiselect_long_values_in_dropdown( + app: Page, assert_snapshot: ImageCompareFunction +): + """Should show long values correctly (with ellipses) in the dropdown menu.""" + multiselect_elem = app.locator(".stMultiSelect").nth(4) + multiselect_elem.locator("input").click() + dropdown_elems = app.locator("li").all() + for idx, el in enumerate(dropdown_elems): + assert_snapshot(el, name="multiselect-dropdown-long-label-" + str(idx)) + + +def test_multiselect_register_callback(app: Page): + """Should call the callback when an option is selected.""" + app.locator(".stMultiSelect").nth(10).locator("input").click() + app.locator("li").first.click() + expect(app.locator("[data-testid='stText']").nth(10)).to_have_text( + "value 11: ['male']" + ) + expect(app.locator("[data-testid='stText']").nth(11)).to_have_text( + "multiselect changed: True" + ) + + +def test_multiselect_max_selections_form(app: Page): + """Should apply max selections when used in form.""" + select_for_kth_multiselect(app, "male", 8, False) + expect(app.locator("li")).to_have_text( + "You can only select up to 1 option. Remove an option first.", + use_inner_text=True, + ) + + +def test_multiselect_max_selections_1(app: Page): + """Should show the correct text when maxSelections is reached and closing after selecting.""" + select_for_kth_multiselect(app, "male", 9, True) + app.locator(".stMultiSelect").nth(9).click() + expect(app.locator("li")).to_have_text( + "You can only select up to 1 option. Remove an option first.", + use_inner_text=True, + ) + + +def test_multiselect_max_selections_2(app: Page): + """Should show the correct text when maxSelections is reached and not closing after selecting.""" + select_for_kth_multiselect(app, "male", 9, False) + expect(app.locator("li")).to_have_text( + "You can only select up to 1 option. Remove an option first.", + use_inner_text=True, + ) + + +def test_multiselect_valid_options(app: Page): + """Should allow selections when there are valid options.""" + expect(app.locator(".stMultiSelect").first).to_have_text( + "multiselect 1\n\nPlease select", use_inner_text=True + ) + + +def test_multiselect_no_valid_options(app: Page): + """Should show that their are no options.""" + expect(app.locator(".stMultiSelect").nth(2)).to_have_text( + "multiselect 3\n\nNo options to select.", use_inner_text=True + ) + + +def test_multiselect_single_selection(app: Page, assert_snapshot: ImageCompareFunction): + """Should allow selections.""" + select_for_kth_multiselect(app, "Female", 1, True) + expect(app.locator(".stMultiSelect span").nth(1)).to_have_text( + "Female", use_inner_text=True + ) + assert_snapshot(app.locator(".stMultiSelect").nth(1), name="multiselect-selection") + expect(app.locator("[data-testid='stText']").nth(1)).to_have_text( + "value 2: ['female']", use_inner_text=True + ) + + +def test_multiselect_deselect_option(app: Page): + """Should deselect an option when deselecting it.""" + select_for_kth_multiselect(app, "Female", 1, True) + select_for_kth_multiselect(app, "Male", 1, True) + del_from_kth_multiselect(app, "Female", 1) + expect(app.locator("[data-testid='stText']").nth(1)).to_have_text( + "value 2: ['male']" + ) + + +def test_multiselect_option_over_max_selections(app: Page): + """Should show an error when more than max_selections got selected.""" + app.locator(".stCheckbox").first.click() + expect(app.locator(".element-container .stException")).to_contain_text( + "Multiselect has 2 options selected but max_selections\nis set to 1" + ) + + +def test_multiselect_double_selection(app: Page): + """Should allow multiple selections.""" + select_for_kth_multiselect(app, "Female", 1, True) + select_for_kth_multiselect(app, "Male", 1, True) + expect(app.locator("[data-testid='stText']").nth(1)).to_have_text( + "value 2: ['female', 'male']" + ) diff --git a/e2e/playwright/st_status.py b/e2e/playwright/st_status.py new file mode 100644 index 000000000000..71549c10b787 --- /dev/null +++ b/e2e/playwright/st_status.py @@ -0,0 +1,48 @@ +# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import streamlit as st + +running_status = st.status("Running status", expanded=True) +running_status.write("Doing some work...") + +with st.status("Completed status", expanded=True, state="complete"): + st.write("Hello world") + +with st.status("Error status", expanded=True, state="error"): + st.error("Oh no, something went wrong!") + +with st.status("Collapsed", state="complete"): + st.write("Hello world") + +with st.status("About to change label...", state="complete") as status: + st.write("Hello world") + status.update(label="Changed label") + +status = st.status("Without context manager", state="complete") +status.write("Hello world") +status.update(state="error", expanded=True) + +with st.status("Collapse via update...", state="complete", expanded=True) as status: + st.write("Hello world") + status.update(label="Collapsed", expanded=False) + +st.status("Empty state...", state="complete") + +try: + with st.status("Uncaught exception"): + st.write("Hello world") + raise Exception("Error!") +except Exception: + pass diff --git a/e2e/playwright/st_status_test.py b/e2e/playwright/st_status_test.py new file mode 100644 index 000000000000..74d803d9c884 --- /dev/null +++ b/e2e/playwright/st_status_test.py @@ -0,0 +1,61 @@ +# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +from playwright.sync_api import Page, expect + +from conftest import ImageCompareFunction + + +def test_status_container_rendering( + themed_app: Page, assert_snapshot: ImageCompareFunction +): + """Test that st.status renders correctly via screenshots.""" + status_containers = themed_app.get_by_test_id("stExpander") + expect(status_containers).to_have_count(9) + + # Don't check screenshot for first element, + # since we cannot reliably screenshot test the spinner icon. + + assert_snapshot(status_containers.nth(1), name="st_status-complete_state") + assert_snapshot(status_containers.nth(2), name="st_status-error_state") + assert_snapshot(status_containers.nth(3), name="st_status-collapsed") + assert_snapshot(status_containers.nth(4), name="st_status-changed_label") + assert_snapshot(status_containers.nth(5), name="st_status-without_cm") + assert_snapshot(status_containers.nth(6), name="st_status-collapsed_via_update") + assert_snapshot(status_containers.nth(7), name="st_status-empty_state") + assert_snapshot(status_containers.nth(8), name="st_status-uncaught_exception") + + +def test_running_state(app: Page): + """Test that st.status renders a spinner when in running state.""" + running_status = app.get_by_test_id("stExpander").nth(0) + # Check if it has a spinner icon: + expect(running_status.get_by_test_id("stExpanderIconSpinner")).to_be_visible() + + +def test_status_collapses_and_expands(app: Page): + """Test that a status collapses and expands.""" + expander_content = "Doing some work..." + running_status = app.get_by_test_id("stExpander").nth(0) + # Starts expanded: + expect(running_status.get_by_text(expander_content)).to_be_visible() + + expander_header = running_status.locator(".streamlit-expanderHeader") + # Collapse: + expander_header.click() + expect(running_status.get_by_text(expander_content)).not_to_be_attached() + # Expand: + expander_header.click() + expect(running_status.get_by_text(expander_content)).to_be_visible() diff --git a/e2e/playwright/st_toggle.py b/e2e/playwright/st_toggle.py new file mode 100644 index 000000000000..187d82f7e9b3 --- /dev/null +++ b/e2e/playwright/st_toggle.py @@ -0,0 +1,48 @@ +# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import streamlit as st +from streamlit import runtime + +i1 = st.toggle("toggle 1 (True)", True) +st.write("toggle 1 - value:", i1) + +i2 = st.toggle("toggle 2 (False)", False) +st.write("toggle 2 - value:", i2) + +i3 = st.toggle( + "toggle 3: This is a really really really really long label that should wrap eventually if we keep addding more text to it " +) +st.write("toggle 3 - value:", i3) + +if runtime.exists(): + + def on_change(): + st.session_state.toggle_clicked = True + + st.toggle("toggle 4 (with callback)", key="toggle4", on_change=on_change) + st.write("toggle 4 - value:", st.session_state.toggle4) + st.write("toggle 4 - clicked:", "toggle_clicked" in st.session_state) + +i5 = st.toggle("toggle 5 (False, disabled)", disabled=True) +st.write("toggle 5 - value:", i5) + +i6 = st.toggle("toggle 6 (True, disabled)", value=True, disabled=True) +st.write("toggle 6 - value:", i6) + +i7 = st.toggle("toggle 7 (label hidden)", label_visibility="hidden") +st.write("toggle 7 - value:", i7) + +i8 = st.toggle("toggle 8 (label collapsed)", label_visibility="collapsed") +st.write("toggle 8 - value:", i8) diff --git a/e2e/playwright/st_toggle_test.py b/e2e/playwright/st_toggle_test.py new file mode 100644 index 000000000000..8a0e67e76b4c --- /dev/null +++ b/e2e/playwright/st_toggle_test.py @@ -0,0 +1,73 @@ +# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +from playwright.sync_api import Page, expect + +from conftest import ImageCompareFunction + + +def test_toggle_widget_display(themed_app: Page, assert_snapshot: ImageCompareFunction): + """Test that st.toggle renders correctly.""" + toggle_elements = themed_app.locator(".stCheckbox") + expect(toggle_elements).to_have_count(8) + + for i, element in enumerate(toggle_elements.all()): + assert_snapshot(element, name=f"toggle-{i}") + + +def test_toggle_initial_values(app: Page): + """Test that st.toggle has the correct initial values.""" + markdown_elements = app.locator(".stMarkdown") + expect(markdown_elements).to_have_count(9) + + expected = [ + "toggle 1 - value: True", + "toggle 2 - value: False", + "toggle 3 - value: False", + "toggle 4 - value: False", + "toggle 4 - clicked: False", + "toggle 5 - value: False", + "toggle 6 - value: True", + "toggle 7 - value: False", + "toggle 8 - value: False", + ] + + for markdown_element, expected_text in zip(markdown_elements.all(), expected): + expect(markdown_element).to_have_text(expected_text, use_inner_text=True) + + +def test_toggle_values_on_click(app: Page): + """Test that st.toggle updates values correctly when user clicks.""" + toggle_elements = app.locator(".stCheckbox") + expect(toggle_elements).to_have_count(8) + + for toggle_element in toggle_elements.all(): + toggle_element.click(delay=50) + + markdown_elements = app.locator(".stMarkdown") + expected = [ + "toggle 1 - value: False", + "toggle 2 - value: True", + "toggle 3 - value: True", + "toggle 4 - value: True", + "toggle 4 - clicked: True", + "toggle 5 - value: False", + "toggle 6 - value: True", + "toggle 7 - value: True", + "toggle 8 - value: True", + ] + + for markdown_element, expected_text in zip(markdown_elements.all(), expected): + expect(markdown_element).to_have_text(expected_text, use_inner_text=True) diff --git a/e2e/scripts/deploy_button.py b/e2e/scripts/deploy_button.py index 2854a3a6bfc1..b7383c0635ae 100644 --- a/e2e/scripts/deploy_button.py +++ b/e2e/scripts/deploy_button.py @@ -12,7 +12,5 @@ # See the License for the specific language governing permissions and # limitations under the License. -import streamlit as st - -# no need to set it using this since we add ?_stcore_testing=true to the url param -# st.experimental_set_query_params(_stcore_testing="true") +# Nothing to do here since the deploy button is part of the frontend even +# without any Streamlit element being rendered. diff --git a/e2e/scripts/st_arrow_altair_chart.py b/e2e/scripts/st_arrow_altair_chart.py index 1027f1c9cf1b..9025ad750308 100644 --- a/e2e/scripts/st_arrow_altair_chart.py +++ b/e2e/scripts/st_arrow_altair_chart.py @@ -48,12 +48,6 @@ chart = alt.Chart(data).mark_bar().encode(x="a", y="b") -st.write("Bar chart with default theme:") -st._arrow_altair_chart(chart) - -st.write("Bar chart with streamlit theme:") -st._arrow_altair_chart(chart, theme="streamlit") - st.write("Bar chart with overwritten theme props:") st._arrow_altair_chart(chart.configure_mark(color="black"), theme="streamlit") @@ -77,3 +71,20 @@ st.write("Pie Chart with more than 4 Legend items") st._arrow_altair_chart(chart, theme="streamlit") + +# taken from vega_datasets barley example +barley = alt.UrlData( + "https://cdn.jsdelivr.net/npm/vega-datasets@v2.7.0/data/barley.json" +) + +barley_chart = ( + alt.Chart(barley) + .mark_bar() + .encode(x="year:O", y="sum(yield):Q", color="year:N", column="site:N") +) + +st.write("Grouped Bar Chart with default theme:") +st.altair_chart(barley_chart, theme=None) + +st.write("Grouped Bar Chart with streamlit theme:") +st.altair_chart(barley_chart, theme="streamlit") diff --git a/e2e/scripts/st_arrow_line_chart.py b/e2e/scripts/st_arrow_line_chart.py index b5868bd85cf4..2fe6c5e02fe3 100644 --- a/e2e/scripts/st_arrow_line_chart.py +++ b/e2e/scripts/st_arrow_line_chart.py @@ -31,4 +31,4 @@ st._arrow_line_chart(df, x="b", y="a") st._arrow_line_chart(df, x="a", y=["b", "c"]) -st._arrow_line_chart(pyspark_mocks.DataFrame()) +st._arrow_line_chart(pyspark_mocks.DataFrame(is_numpy_arr=True)) diff --git a/e2e/scripts/st_button.py b/e2e/scripts/st_button.py index 3043d3e14e2e..71ae7fca3c1e 100644 --- a/e2e/scripts/st_button.py +++ b/e2e/scripts/st_button.py @@ -51,7 +51,11 @@ def on_click(x, y): i5 = st.button("button 4", type="primary", disabled=True) st.write("value 4:", i5) -st.button("button 5", use_container_width=True) +st.button("button 5 - containerWidth", use_container_width=True) + +st.button( + "button 6 - containerWidth + help", use_container_width=True, help="help text" +) cols = st.columns(3) diff --git a/e2e/scripts/st_chat_message.py b/e2e/scripts/st_chat_message.py index 6deb542168a2..938da9915453 100644 --- a/e2e/scripts/st_chat_message.py +++ b/e2e/scripts/st_chat_message.py @@ -66,4 +66,4 @@ with st.expander("See more", expanded=True): st.write("Lorem ipsum dolor sit amet") -st.chat_message("user") +st.chat_message("human") diff --git a/e2e/scripts/st_download_button.py b/e2e/scripts/st_download_button.py index 6c313e9315c9..a37de2fa0e73 100644 --- a/e2e/scripts/st_download_button.py +++ b/e2e/scripts/st_download_button.py @@ -41,3 +41,18 @@ file_name="hello.txt", use_container_width=True, ) + +st.download_button( + "Download button with help text and use_container_width=True", + data="Hello world!", + file_name="hello.txt", + use_container_width=True, + help="Example help text", +) + +st.download_button( + "Primary download button", + data="Hello world!", + file_name="hello.txt", + type="primary", +) diff --git a/e2e/scripts/st_form_use_container_width_submit_button.py b/e2e/scripts/st_form_use_container_width_submit_button.py index 323d6abacc36..ef2ede73a84d 100644 --- a/e2e/scripts/st_form_use_container_width_submit_button.py +++ b/e2e/scripts/st_form_use_container_width_submit_button.py @@ -21,3 +21,13 @@ submitted = st.form_submit_button("Submit", use_container_width=True) if submitted: st.write("slider", slider_val, "checkbox", checkbox_val) + +with st.form("my_form_2"): + st.write("Inside the second form") + slider_val = st.slider("Form slider 2") + checkbox_val = st.checkbox("Form checkbox 2") + submitted = st.form_submit_button( + "Submit", help="Submit by clicking", use_container_width=True + ) + if submitted: + st.write("slider 2:", slider_val, "checkbox 2:", checkbox_val) diff --git a/e2e/scripts/st_markdown.py b/e2e/scripts/st_markdown.py index 239e18a8a00c..8d81ba1646f7 100644 --- a/e2e/scripts/st_markdown.py +++ b/e2e/scripts/st_markdown.py @@ -83,5 +83,8 @@ - :red[red] - :violet[violet] - :orange[orange] +- :gray[gray] +- :grey[grey] +- :rainbow[rainbow] """ ) diff --git a/e2e/scripts/st_radio.py b/e2e/scripts/st_radio.py index 2394c567ff76..586c292e5114 100644 --- a/e2e/scripts/st_radio.py +++ b/e2e/scripts/st_radio.py @@ -19,6 +19,16 @@ from tests.streamlit import pyspark_mocks options = ("female", "male") +markdown_options = ( + "**bold text**", + "*italics text*", + "~strikethrough text~", + "shortcode: :blush:", + # link should not work in radio options + "[link text](www.example.com)", + "`code text`", + ":red[red] :blue[blue] :green[green] :violet[violet] :orange[orange]", +) i1 = st.radio("radio 1", options, 1) st.write("value 1:", i1) @@ -43,14 +53,31 @@ i8 = st.radio("radio 8", options, label_visibility="collapsed") st.write("value 8:", i8) +i9 = st.radio("radio 9", markdown_options) +st.write("value 9:", i9) + +i10 = st.radio( + "radio 10 - captions", + ["A", "B", "C", "D", "E", "F", "G"], + captions=markdown_options, +) +st.write("value 10:", i10) + +i11 = st.radio( + "radio 11 - horizontal, captions", + ["yes", "maybe", "no"], + captions=["Opt in", "", "Opt out"], + horizontal=True, +) +st.write("value 11:", i11) if runtime.exists(): def on_change(): st.session_state.radio_changed = True - st.radio("radio 9", options, 1, key="radio9", on_change=on_change) - st.write("value 9:", st.session_state.radio9) + st.radio("radio 12", options, 1, key="radio10", on_change=on_change) + st.write("value 12:", st.session_state.radio10) st.write("radio changed:", "radio_changed" in st.session_state) st.radio("PySpark radio", pyspark_mocks.DataFrame()) # type: ignore diff --git a/e2e/scripts/st_text_area.py b/e2e/scripts/st_text_area.py index 5de3e399f924..e967ba551ebc 100644 --- a/e2e/scripts/st_text_area.py +++ b/e2e/scripts/st_text_area.py @@ -42,11 +42,14 @@ i9 = st.text_area("text area 9", "default text", label_visibility="collapsed") st.write('value 9: "', i9, '"') +i10 = st.text_area("text area 10 - 250px height", height=250) +st.write('value 10: "', i10, '"') + if runtime.exists(): def on_change(): st.session_state.text_area_changed = True - st.text_area("text area 10", key="text_area10", on_change=on_change) - st.write('value 10: "', st.session_state.text_area10, '"') + st.text_area("text area 11", key="text_area11", on_change=on_change) + st.write('value 11: "', st.session_state.text_area11, '"') st.write("text area changed:", "text_area_changed" in st.session_state) diff --git a/e2e/scripts/st_toast.py b/e2e/scripts/st_toast.py index c9d178677072..596b5ef6a8f8 100644 --- a/e2e/scripts/st_toast.py +++ b/e2e/scripts/st_toast.py @@ -14,6 +14,8 @@ import streamlit as st +st.set_page_config(layout="wide") +st.chat_input("input here") st.toast("This is a default toast message", icon="🐶") st.toast( "Random toast message that is a really really really really really really really long message, going way past the 3 line limit", diff --git a/e2e/scripts/st_toggle.py b/e2e/scripts/st_toggle.py new file mode 100644 index 000000000000..584291345504 --- /dev/null +++ b/e2e/scripts/st_toggle.py @@ -0,0 +1,46 @@ +# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import streamlit as st +from streamlit import runtime + +i1 = st.toggle("toggle 1", True) +st.write("value 1:", i1) + +i2 = st.toggle("toggle 2", False) +st.write("value 2:", i2) + +i3 = st.toggle("toggle 3") +st.write("value 3:", i3) + +if runtime.exists(): + + def on_change(): + st.session_state.toggle_clicked = True + + st.toggle("toggle 4", key="toggle4", on_change=on_change) + st.write("value 4:", st.session_state.toggle4) + st.write("toggle clicked:", "toggle_clicked" in st.session_state) + +i5 = st.toggle("toggle 5", disabled=True) +st.write("value 5:", i5) + +i6 = st.toggle("toggle 6", value=True, disabled=True) +st.write("value 6:", i6) + +i7 = st.toggle("toggle 7", label_visibility="hidden") +st.write("value 7:", i7) + +i8 = st.toggle("toggle 8", label_visibility="collapsed") +st.write("value 8:", i8) diff --git a/e2e/scripts/websocket_reconnects.py b/e2e/scripts/websocket_reconnects.py index 037fdc4c4e15..eb0404796cfb 100644 --- a/e2e/scripts/websocket_reconnects.py +++ b/e2e/scripts/websocket_reconnects.py @@ -25,6 +25,8 @@ st.write(f"count: {st.session_state.counter}") - # TODO(vdonato): Add st.file_uploader and st.camera_input tests once we're able to - # teach those widgets how to retrieve previously uploaded files after a session - # disconnect/reconnect. + if f := st.file_uploader("Upload a file"): + st.text(f.read()) + + if img := st.camera_input("Take a picture"): + st.image(img) diff --git a/e2e/specs/deploy_button.spec.js b/e2e/specs/deploy_button.spec.js index 980337eba909..1707ba4d2df1 100644 --- a/e2e/specs/deploy_button.spec.js +++ b/e2e/specs/deploy_button.spec.js @@ -16,7 +16,7 @@ describe("deploy button and modal", () => { beforeEach(() => { - cy.loadApp("http://localhost:3000/?_stcore_testing=true"); + cy.loadApp("http://localhost:3000/"); cy.prepForElementSnapshots(); }); @@ -30,9 +30,7 @@ describe("deploy button and modal", () => { it("renders the light deploy dialog correctly", () => { cy.get("div[class='stDeployButton'] > button").click({ force: true }); - cy.get("div[role='dialog']").matchImageSnapshot( - "deploy_dialog_opened" - ); + cy.get("div[role='dialog']").matchImageSnapshot("deploy_dialog_opened"); }); it("renders the dark deploy dialog correctly", () => { diff --git a/e2e/specs/st_button.spec.js b/e2e/specs/st_button.spec.js index d2018c5c4957..9f977f0c8daf 100644 --- a/e2e/specs/st_button.spec.js +++ b/e2e/specs/st_button.spec.js @@ -14,7 +14,7 @@ * limitations under the License. */ -const NO_OF_BUTTONS = 13 +const NO_OF_BUTTONS = 14 /** * Order of CONN_TYPES_BUTTONs matters as they are rendered in order in st_button.py */ @@ -70,9 +70,18 @@ describe("st.button", () => { .matchThemedSnapshots("use-container-width-button"); }); + it("renders useContainerWidth button with help correctly", () => { + cy.get(".stButton").should("have.length", NO_OF_BUTTONS); + + cy.getIndexed(".stButton", 5) + .trigger('mouseover').matchThemedSnapshots("use-container-width-and-help-button", { padding: [60, 0, 0, 0] }); + }); + it("has correct default values", () => { - cy.get(".stButton button").should("have.text", - "button 1" + "button 2" + "button 3" + "button 4" + "button 5" + CONN_TYPES_BUTTONS.join("")); + cy.get(".stButton > button").should("have.text", + "button 1" + "button 2" + "button 3" + "button 4" + "button 5 - containerWidth" + CONN_TYPES_BUTTONS.join("")); + // button w/ help tooltip isn't direct decendent of stButton div + cy.getIndexed(".stButton button", 5).should("have.text", "button 6 - containerWidth + help"); }); it("sets value correctly when user clicks", () => { diff --git a/e2e/specs/st_camera_input.spec.js b/e2e/specs/st_camera_input.spec.js index d4681cca662a..8f69ec4d823c 100644 --- a/e2e/specs/st_camera_input.spec.js +++ b/e2e/specs/st_camera_input.spec.js @@ -16,8 +16,11 @@ describe("st.camera_input", () => { before(() => { + // Increasing timeout since uploading and rendering images can be slow. + Cypress.config("defaultCommandTimeout", 30000); + Cypress.Cookies.defaults({ - preserve: ["_xsrf"] + preserve: ["_xsrf"], }); cy.loadApp("http://localhost:3000/"); }); @@ -27,6 +30,10 @@ describe("st.camera_input", () => { }); it("capture photo when 'Take photo' button clicked", () => { + // Be generous with some of the timeouts in this test as uploading and + // rendering images can be quite slow. + const timeout = 30000; + cy.get("[data-testid='stCameraInput']") .contains("Learn how to allow access.") .should("not.exist"); @@ -41,7 +48,7 @@ describe("st.camera_input", () => { cy.get("img").should("have.length.at.least", 2); - cy.get("[data-testid='stImage']").should("have.length.at.least", 1); + cy.get("[data-testid='stImage']", { timeout }).should("have.length.at.least", 1); }); it("Remove photo when 'Clear photo' button clicked", () => { diff --git a/e2e/specs/st_download_button.spec.js b/e2e/specs/st_download_button.spec.js index e60ee2cbc8c3..3abde0ea1e85 100644 --- a/e2e/specs/st_download_button.spec.js +++ b/e2e/specs/st_download_button.spec.js @@ -15,7 +15,7 @@ */ const path = require("path"); -const NO_OF_BUTTONS = 4 +const NO_OF_BUTTONS = 6 describe("st.download_button", () => { beforeEach(() => { @@ -58,9 +58,21 @@ describe("st.download_button", () => { }); it("renders useContainerWidth st.download_button correctly", () => { - cy.get(".stDownloadButton button") + cy.getIndexed(".stDownloadButton button", 3) .should("have.length.at.least", 1) - .last() .click().matchThemedSnapshots("use-container-width-button"); }); + + it("renders useContainerWidth + help st.download_button correctly", () => { + cy.getIndexed(".stDownloadButton button", 4) + .trigger('mouseover').matchThemedSnapshots("container-width-help-button", { padding: [60, 0, 0, 0] }); + }); + + it("shows primary button correctly", () => { + cy.get(".stDownloadButton").should("have.length", NO_OF_BUTTONS); + + cy.getIndexed(".stDownloadButton", 5).matchThemedSnapshots( + "primary-download-button" + ); + }); }); diff --git a/e2e/specs/st_file_uploader.spec.js b/e2e/specs/st_file_uploader.spec.js index 4d6e8293fa13..4c76e171da84 100644 --- a/e2e/specs/st_file_uploader.spec.js +++ b/e2e/specs/st_file_uploader.spec.js @@ -17,10 +17,10 @@ describe("st.file_uploader", () => { beforeEach(() => { Cypress.Cookies.defaults({ - preserve: ["_xsrf"] + preserve: ["_xsrf"], }); cy.server(); - cy.route("POST", "**/upload_file").as("uploadFile"); + cy.route("PUT", "**/upload_file/**").as("uploadFile"); cy.loadApp("http://localhost:3000/"); @@ -53,14 +53,13 @@ describe("st.file_uploader", () => { cy.getIndexed("[data-testid='stFileUploader']", 5).matchThemedSnapshots( "collapsed_label_file_uploader" ); - }); it("shows error message for disallowed files", () => { const fileName = "example.json"; const uploaderIndex = 0; - cy.fixture(fileName).then(fileContent => { + cy.fixture(fileName).then((fileContent) => { cy.get("[data-testid='stFileUploadDropzone']") .eq(uploaderIndex) .attachFile( @@ -73,7 +72,7 @@ describe("st.file_uploader", () => { // the page may start re-rendering after the "drop" event completes, // which causes a cypress error due to the element being detached // from the DOM when "dragleave" is emitted. - events: ["dragenter", "drop"] + events: ["dragenter", "drop"], } ); @@ -100,11 +99,11 @@ describe("st.file_uploader", () => { // Why can’t I use async / await? // If you’re a modern JS programmer you might hear “asynchronous” and think: why can’t I just use async/await instead of learning some proprietary API? // https://docs.cypress.io/guides/core-concepts/introduction-to-cypress.html#Commands-Are-Asynchronous - cy.fixture(fileName1).then(file1 => { - cy.fixture(fileName2).then(file2 => { + cy.fixture(fileName1).then((file1) => { + cy.fixture(fileName2).then((file2) => { const files = [ { fileContent: file1, fileName: fileName1, mimeType: "text/plain" }, - { fileContent: file2, fileName: fileName2, mimeType: "text/plain" } + { fileContent: file2, fileName: fileName2, mimeType: "text/plain" }, ]; cy.getIndexed( @@ -113,7 +112,7 @@ describe("st.file_uploader", () => { ).attachFile(files[0], { force: true, subjectType: "drag-n-drop", - events: ["dragenter", "drop"] + events: ["dragenter", "drop"], }); // The script should have printed the contents of the first files @@ -125,10 +124,10 @@ describe("st.file_uploader", () => { file1 ); - cy.getIndexed( - "[data-testid='stMarkdownContainer']", - 1 - ).should("contain.text", "True"); + cy.getIndexed("[data-testid='stMarkdownContainer']", 1).should( + "contain.text", + "True" + ); cy.getIndexed( "[data-testid='stFileUploader']", @@ -142,7 +141,7 @@ describe("st.file_uploader", () => { ).attachFile(files[1], { force: true, subjectType: "drag-n-drop", - events: ["dragenter", "drop"] + events: ["dragenter", "drop"], }); cy.get(".uploadedFileName") @@ -152,10 +151,10 @@ describe("st.file_uploader", () => { .should("contain.text", file2) .should("not.contain.text", file1); - cy.getIndexed( - "[data-testid='stMarkdownContainer']", - 1 - ).should("contain.text", "True"); + cy.getIndexed("[data-testid='stMarkdownContainer']", 1).should( + "contain.text", + "True" + ); // On rerun, make sure file is still returned cy.get("body").type("r"); @@ -188,11 +187,11 @@ describe("st.file_uploader", () => { // https://github.com/cypress-io/cypress-example-recipes/blob/master/examples/fundamentals__fixtures/cypress/integration/multiple-fixtures-spec.js // Why can’t I use async / await? // https://docs.cypress.io/guides/core-concepts/introduction-to-cypress.html#Commands-Are-Asynchronous - cy.fixture(fileName1).then(file1 => { - cy.fixture(fileName2).then(file2 => { + cy.fixture(fileName1).then((file1) => { + cy.fixture(fileName2).then((file2) => { const files = [ { fileContent: file1, fileName: fileName1, mimeType: "text/plain" }, - { fileContent: file2, fileName: fileName2, mimeType: "text/plain" } + { fileContent: file2, fileName: fileName2, mimeType: "text/plain" }, ]; cy.getIndexed( @@ -201,10 +200,10 @@ describe("st.file_uploader", () => { ).attachFile(files[0], { force: true, subjectType: "drag-n-drop", - events: ["dragenter", "drop"] + events: ["dragenter", "drop"], }); - cy.get(".uploadedFileName").each(uploadedFileName => { + cy.get(".uploadedFileName").each((uploadedFileName) => { cy.get(uploadedFileName).should("have.text", fileName1); }); @@ -214,7 +213,7 @@ describe("st.file_uploader", () => { ).attachFile(files[1], { force: true, subjectType: "drag-n-drop", - events: ["dragenter", "drop"] + events: ["dragenter", "drop"], }); // Wait for the HTTP request to complete @@ -243,17 +242,15 @@ describe("st.file_uploader", () => { // Delete the second file. The second file is on top because it was // most recently uploaded. The first file should still exist. - cy.get("[data-testid='fileDeleteBtn'] button") - .first() - .click(); + cy.get("[data-testid='fileDeleteBtn'] button").first().click(); cy.getIndexed("[data-testid='stText']", uploaderIndex).should( "contain.text", file1 ); - cy.getIndexed( - "[data-testid='stMarkdownContainer']", - 5 - ).should("contain.text", "True"); + cy.getIndexed("[data-testid='stMarkdownContainer']", 5).should( + "contain.text", + "True" + ); }); }); }); @@ -273,11 +270,11 @@ describe("st.file_uploader", () => { // https://github.com/cypress-io/cypress-example-recipes/blob/master/examples/fundamentals__fixtures/cypress/integration/multiple-fixtures-spec.js // Why can’t I use async / await? // https://docs.cypress.io/guides/core-concepts/introduction-to-cypress.html#Commands-Are-Asynchronous - cy.fixture(fileName1).then(file1 => { - cy.fixture(fileName2).then(file2 => { + cy.fixture(fileName1).then((file1) => { + cy.fixture(fileName2).then((file2) => { const files = [ { fileContent: file1, fileName: fileName1, mimeType: "text/plain" }, - { fileContent: file2, fileName: fileName2, mimeType: "text/plain" } + { fileContent: file2, fileName: fileName2, mimeType: "text/plain" }, ]; cy.getIndexed( @@ -286,14 +283,15 @@ describe("st.file_uploader", () => { ).attachFile(files[0], { force: true, subjectType: "drag-n-drop", - events: ["dragenter", "drop"] + events: ["dragenter", "drop"], }); - cy.get(".uploadedFileName").each(uploadedFileName => { + cy.get(".uploadedFileName").each((uploadedFileName) => { cy.get(uploadedFileName).should("have.text", fileName1); }); - cy.wait(1000); + // Wait for the HTTP request to complete + cy.wait("@uploadFile"); cy.getIndexed( "[data-testid='stFileUploadDropzone']", @@ -301,7 +299,7 @@ describe("st.file_uploader", () => { ).attachFile(files[1], { force: true, subjectType: "drag-n-drop", - events: ["dragenter", "drop"] + events: ["dragenter", "drop"], }); // Wait for the HTTP request to complete @@ -325,17 +323,15 @@ describe("st.file_uploader", () => { // Delete the second file. The second file is on top because it was // most recently uploaded. The first file should still exist. - cy.get("[data-testid='fileDeleteBtn'] button") - .first() - .click(); + cy.get("[data-testid='fileDeleteBtn'] button").first().click(); cy.getIndexed("[data-testid='stText']", uploaderIndex).should( "contain.text", file1 ); - cy.getIndexed( - "[data-testid='stMarkdownContainer']", - 5 - ).should("contain.text", "True"); + cy.getIndexed("[data-testid='stMarkdownContainer']", 5).should( + "contain.text", + "True" + ); }); }); }); @@ -344,9 +340,9 @@ describe("st.file_uploader", () => { const fileName1 = "file1.txt"; const uploaderIndex = 3; - cy.fixture(fileName1).then(file1 => { + cy.fixture(fileName1).then((file1) => { const files = [ - { fileContent: file1, fileName: fileName1, mimeType: "text/plain" } + { fileContent: file1, fileName: fileName1, mimeType: "text/plain" }, ]; cy.getIndexed( @@ -355,7 +351,7 @@ describe("st.file_uploader", () => { ).attachFile(files[0], { force: true, subjectType: "drag-n-drop", - events: ["dragenter", "drop"] + events: ["dragenter", "drop"], }); // Wait for the HTTP request to complete @@ -382,9 +378,7 @@ describe("st.file_uploader", () => { // Press the delete button. Again, nothing should happen - we // should still see the file's contents. - cy.get("[data-testid='fileDeleteBtn'] button") - .first() - .click(); + cy.get("[data-testid='fileDeleteBtn'] button").first().click(); cy.getIndexed("[data-testid='stText']", uploaderIndex).should( "contain.text", @@ -406,9 +400,9 @@ describe("st.file_uploader", () => { const fileName1 = "file1.txt"; const uploaderIndex = 6; - cy.fixture(fileName1).then(file1 => { + cy.fixture(fileName1).then((file1) => { const files = [ - { fileContent: file1, fileName: fileName1, mimeType: "text/plain" } + { fileContent: file1, fileName: fileName1, mimeType: "text/plain" }, ]; // Script contains counter variable stored in session_state with @@ -427,7 +421,7 @@ describe("st.file_uploader", () => { ).attachFile(files[0], { force: true, subjectType: "drag-n-drop", - events: ["dragenter", "drop"] + events: ["dragenter", "drop"], }); // Make sure callback called diff --git a/e2e/specs/st_form_use_container_width_submit_button.spec.js b/e2e/specs/st_form_use_container_width_submit_button.spec.js index 94e213f52f4c..7b654d4e4bb5 100644 --- a/e2e/specs/st_form_use_container_width_submit_button.spec.js +++ b/e2e/specs/st_form_use_container_width_submit_button.spec.js @@ -16,17 +16,21 @@ const path = require("path"); -describe("st.form with use_container_width=True button", () => { +describe("st.form_submit_button", () => { beforeEach(() => { cy.loadApp("http://localhost:3000/"); cy.prepForElementSnapshots(); }); - - it("renders use_container_width=True st.submit_form_button correctly", () => { + it("renders correctly with use_container_width=True", () => { cy.get("[data-testid='stFormSubmitButton'] button") .should("have.length.at.least", 1) .first().matchThemedSnapshots("use-container-width-submit-form-button"); }); + + it("renders correctly with use_container_width=True and help text", () => { + cy.getIndexed("[data-testid='stFormSubmitButton'] button", 1) + .trigger('mouseover').matchThemedSnapshots("form-submit-button-container-and-help", { padding: [60, 0, 0, 0] }); + }); }); diff --git a/e2e/specs/st_radio.spec.js b/e2e/specs/st_radio.spec.js index 87373c438a00..3374ad5d9b41 100644 --- a/e2e/specs/st_radio.spec.js +++ b/e2e/specs/st_radio.spec.js @@ -22,7 +22,7 @@ describe("st.radio", () => { }); it("shows widget correctly", () => { - cy.get(".stRadio").should("have.length", 10); + cy.get(".stRadio").should("have.length", 13); cy.get(".stRadio").each((el, idx) => { return cy.wrap(el).matchThemedSnapshots("radio" + idx); @@ -95,11 +95,31 @@ describe("st.radio", () => { "value 6: female" + "value 7: female" + "value 8: female" + - "value 9: male" + + "value 9: bold text" + + "value 10: A" + + "value 11: yes" + + "value 12: male" + "radio changed: False" ); }); + it("has correct caption values", () => { + const captions = [ "bold text", + "italics text", + "strikethrough text", + "shortcode: 😊", + "link text", + "code text", + "red blue green violet orange", + "Opt in", + "\u00a0", + "Opt out", + ] + captions.forEach((expected, idx) => { + cy.getIndexed("[data-testid='stCaptionContainer']", idx).should('contain.text', expected) + }) + }); + it("formats display values", () => { cy.getIndexed('.stRadio [role="radiogroup"]', 1).should( "have.text", @@ -139,13 +159,16 @@ describe("st.radio", () => { "value 6: male" + "value 7: male" + "value 8: male" + - "value 9: male" + + "value 9: red blue green violet orange" + + "value 10: G" + + "value 11: no" + + "value 12: male" + "radio changed: False" ); }); it("calls callback if one is registered", () => { - cy.getIndexed(".stRadio", 8).then(el => { + cy.getIndexed(".stRadio", 11).then(el => { return cy .wrap(el) .find("input") @@ -163,7 +186,10 @@ describe("st.radio", () => { "value 6: female" + "value 7: female" + "value 8: female" + - "value 9: female" + + "value 9: bold text" + + "value 10: A" + + "value 11: yes" + + "value 12: female" + "radio changed: True" ); }); diff --git a/e2e/specs/st_text_area.spec.js b/e2e/specs/st_text_area.spec.js index 5265eaa8c493..b8bc70b5d902 100644 --- a/e2e/specs/st_text_area.spec.js +++ b/e2e/specs/st_text_area.spec.js @@ -22,7 +22,7 @@ describe("st.text_area", () => { }); it("shows widget correctly", () => { - cy.get(".stTextArea").should("have.length", 10); + cy.get(".stTextArea").should("have.length", 11); cy.get(".stTextArea").each((el, idx) => { return cy.wrap(el).matchThemedSnapshots("text_area" + idx); @@ -42,6 +42,7 @@ describe("st.text_area", () => { 'value 8: " default text "' + 'value 9: " default text "' + 'value 10: " "' + + 'value 11: " "' + "text area changed: False" ); }); @@ -63,6 +64,7 @@ describe("st.text_area", () => { 'value 8: " default text "' + 'value 9: " default text "' + 'value 10: " "' + + 'value 11: " "' + "text area changed: False" ); }); @@ -84,6 +86,7 @@ describe("st.text_area", () => { 'value 8: " default text "' + 'value 9: " default text "' + 'value 10: " "' + + 'value 11: " "' + "text area changed: False" ); }); @@ -105,6 +108,7 @@ describe("st.text_area", () => { 'value 8: " default text "' + 'value 9: " default text "' + 'value 10: " "' + + 'value 11: " "' + "text area changed: False" ); }); @@ -127,6 +131,7 @@ describe("st.text_area", () => { 'value 8: " default text "' + 'value 9: " default text "' + 'value 10: " "' + + 'value 11: " "' + "text area changed: False" ); }); @@ -148,6 +153,7 @@ describe("st.text_area", () => { 'value 8: " default text "' + 'value 9: " default text "' + 'value 10: " "' + + 'value 11: " "' + "text area changed: False" ); }); @@ -169,7 +175,8 @@ describe("st.text_area", () => { 'value 7: " default text "' + 'value 8: " default text "' + 'value 9: " default text "' + - 'value 10: " text area! "' + + 'value 10: " "' + + 'value 11: " text area! "' + "text area changed: True" ); }); diff --git a/e2e/specs/st_toast.spec.js b/e2e/specs/st_toast.spec.js index 037f4e361e78..a3960b9f801a 100644 --- a/e2e/specs/st_toast.spec.js +++ b/e2e/specs/st_toast.spec.js @@ -67,5 +67,9 @@ describe("st.toast", () => { cy.getIndexed("[data-testid='stToast']", 0) .matchImageSnapshot(`toast-expanded-${theme}`); }); + + it(`overlays toasts with st.chat_input - ${theme}`, () => { + cy.get(".stChatFloatingInputContainer").matchImageSnapshot(`toast+chatInput-${theme}`) + }); }) }); diff --git a/e2e/specs/websocket_reconnects.spec.js b/e2e/specs/websocket_reconnects.spec.js index 0225f0c49ce4..6be9e0adf1be 100644 --- a/e2e/specs/websocket_reconnects.spec.js +++ b/e2e/specs/websocket_reconnects.spec.js @@ -19,10 +19,16 @@ const NUM_DISCONNECTS = 20; describe("websocket reconnects", () => { beforeEach(() => { + Cypress.Cookies.defaults({ + preserve: ["_xsrf"], + }); + cy.server(); + cy.route("PUT", "**/upload_file/**").as("uploadFile"); + cy.loadApp("http://localhost:3000/"); }); - it("persists session state when the websocket connection is dropped and reconnects", () => { + it("retains session state when the websocket connection is dropped and reconnects", () => { let expectedCount = 0; for (let i = 0; i < NUM_DISCONNECTS; i++) { @@ -49,4 +55,95 @@ describe("websocket reconnects", () => { cy.get(".stMarkdown").contains(`count: ${expectedCount}`); } }); + + it("retains uploaded files when the websocket connection is dropped and reconnects", () => { + const fileName1 = "file1.txt"; + const uploaderIndex = 0; + + cy.fixture(fileName1).then((file1) => { + cy.getIndexed( + "[data-testid='stFileUploadDropzone']", + uploaderIndex + ).attachFile( + { + fileContent: file1, + fileName: fileName1, + mimeType: "text/plain", + }, + { + force: true, + subjectType: "drag-n-drop", + events: ["dragenter", "drop"], + } + ); + + cy.wait("@uploadFile"); + + // The script should have printed the contents of the first files + // into an st.text. (This tests that the upload actually went + // through.) + cy.get(".uploadedFileName").should("have.text", fileName1); + cy.getIndexed("[data-testid='stText']", uploaderIndex).should( + "contain.text", + file1 + ); + + cy.window().then((win) => { + setTimeout(() => { + win.streamlitDebug.disconnectWebsocket(); + }, 100); + }); + + // Wait until we've disconnected. + cy.get("[data-testid='stStatusWidget']").should( + "have.text", + "Connecting" + ); + // Wait until we've reconnected and rerun the script. + cy.get("[data-testid='stStatusWidget']").should("not.exist"); + + // Confirm that our uploaded file is still there. + cy.getIndexed("[data-testid='stText']", uploaderIndex).should( + "contain.text", + file1 + ); + }); + }); + + it("retains captured pictures when the websocket connection is dropped and reconnects", () => { + // Be generous with some of the timeouts in this test as uploading and + // rendering images can be quite slow. + const timeout = 30000; + + cy.get("[data-testid='stCameraInputButton']", { timeout }) + .should("have.length", 1) + .first() + .wait(1000) + .should("not.be.disabled") + .contains("Take Photo") + .click(); + + cy.wait("@uploadFile", { timeout }); + + cy.get("img").should("have.length.at.least", 2); + + cy.get("[data-testid='stImage']", { timeout }).should( + "have.length.at.least", + 1 + ); + + cy.window().then((win) => { + setTimeout(() => { + win.streamlitDebug.disconnectWebsocket(); + }, 100); + }); + + // Wait until we've disconnected. + cy.get("[data-testid='stStatusWidget']").should("have.text", "Connecting"); + // Wait until we've reconnected and rerun the script. + cy.get("[data-testid='stStatusWidget']").should("not.exist"); + + // Confirm that our picture is still there. + cy.get("[data-testid='stImage']").should("have.length.at.least", 1); + }); }); diff --git a/frontend/.eslintrc.js b/frontend/.eslintrc.js index d72239b1c92a..b92bd54dbdb0 100644 --- a/frontend/.eslintrc.js +++ b/frontend/.eslintrc.js @@ -36,6 +36,8 @@ module.exports = { "plugin:prettier/recommended", // Recommended Jest configuration to enforce good testing practices "plugin:jest/recommended", + // Uses the recommended rules from React Testing Library: + "plugin:testing-library/react", ], // Specifies the ESLint parser parser: "@typescript-eslint/parser", diff --git a/frontend/app/package.json b/frontend/app/package.json index 28a52a53df00..8980a80a5dc8 100644 --- a/frontend/app/package.json +++ b/frontend/app/package.json @@ -1,6 +1,6 @@ { "name": "@streamlit/app", - "version": "1.24.1", + "version": "1.26.0", "license": "Apache-2.0", "private": true, "homepage": "./", @@ -33,7 +33,7 @@ "@emotion/react": "^11.10.5", "@emotion/serialize": "^1.1.1", "@emotion/styled": "^11.10.5", - "@streamlit/lib": "1.24.1", + "@streamlit/lib": "1.26.0", "axios": "^0.27.2", "baseui": "12.2.0", "classnames": "^2.3.2", diff --git a/frontend/app/src/App.test.tsx b/frontend/app/src/App.test.tsx index 7a1667dc8c34..e708b824e39a 100644 --- a/frontend/app/src/App.test.tsx +++ b/frontend/app/src/App.test.tsx @@ -16,7 +16,7 @@ import React from "react" import { ReactWrapper, ShallowWrapper } from "enzyme" -import { waitFor } from "@testing-library/dom" +import { waitFor } from "@testing-library/react" import cloneDeep from "lodash/cloneDeep" import { LocalStore, @@ -61,7 +61,6 @@ jest.mock("@streamlit/app/src/connection/ConnectionManager") jest.mock("@streamlit/lib/src/baseconsts", () => { return { ...jest.requireActual("@streamlit/lib/src/baseconsts"), - SHOW_DEPLOY_BUTTON: true, } }) @@ -931,15 +930,14 @@ describe("App.onHistoryChange", () => { pushStateSpy.mockRestore() }) - it("does rerun when we are navigating to a different page and the last window history url contains an anchor", () => { + it("does rerun when we are navigating to a different page and the last window history url contains an anchor", async () => { const pushStateSpy = jest.spyOn(window.history, "pushState") - - jest.spyOn(instance, "onPageChange") + const pageChangeSpy = jest.spyOn(instance, "onPageChange") // navigate to current page with anchor window.history.pushState({}, "", "#foo_bar") instance.onHistoryChange() - expect(instance.onPageChange).not.toHaveBeenCalled() + expect(pageChangeSpy).not.toHaveBeenCalled() // navigate to new page instance.handleNewSession( @@ -947,8 +945,9 @@ describe("App.onHistoryChange", () => { ) window.history.back() - waitFor(() => { - expect(instance.onPageChange).toHaveBeenLastCalledWith("sub_hash") + // Check for rerun + await waitFor(() => { + expect(pageChangeSpy).toHaveBeenLastCalledWith("top_hash") }) pushStateSpy.mockRestore() @@ -1229,6 +1228,54 @@ describe("App.handleDeltaMessage", () => { }) }) +describe("App.requestFileURLs", () => { + let wrapper: ShallowWrapper + let instance: App + + beforeEach(() => { + wrapper = shallow() + instance = wrapper.instance() as App + + // @ts-expect-error + instance.sendBackMsg = jest.fn() + + // @ts-expect-error + instance.sessionInfo.setCurrent(mockSessionInfoProps()) + }) + + it("properly constructs fileUrlsRequest BackMsg", () => { + instance.isServerConnected = jest.fn().mockReturnValue(true) + + instance.requestFileURLs( + "myRequestId", + // @ts-expect-error + [{ name: "file1.txt" }, { name: "file2.txt" }, { name: "file3.txt" }] + ) + + // @ts-expect-error + expect(instance.sendBackMsg).toHaveBeenCalledWith({ + fileUrlsRequest: { + fileNames: ["file1.txt", "file2.txt", "file3.txt"], + requestId: "myRequestId", + sessionId: "mockSessionId", + }, + }) + }) + + it("does nothing if server is disconnected", () => { + instance.isServerConnected = jest.fn().mockReturnValue(false) + + instance.requestFileURLs( + "myRequestId", + // @ts-expect-error + [{ name: "file1.txt" }, { name: "file2.txt" }, { name: "file3.txt" }] + ) + + // @ts-expect-error + expect(instance.sendBackMsg).not.toHaveBeenCalled() + }) +}) + describe("Test Main Menu shortcut functionality", () => { let prevWindowLocation: Location beforeEach(() => { diff --git a/frontend/app/src/App.tsx b/frontend/app/src/App.tsx index edfe7b30268d..62927bc81e5d 100644 --- a/frontend/app/src/App.tsx +++ b/frontend/app/src/App.tsx @@ -51,13 +51,11 @@ import { isPaddingDisplayed, isScrollingHidden, isToolbarDisplayed, - isTesting, notUndefined, setCookie, extractPageNameFromPathName, BaseUriParts, RERUN_PROMPT_MODAL_DIALOG, - SHOW_DEPLOY_BUTTON, SessionInfo, FileUploadClient, logError, @@ -80,6 +78,7 @@ import { Config, CustomThemeConfig, Delta, + FileURLsResponse, ForwardMsg, ForwardMsgMetadata, GitInfo, @@ -330,6 +329,7 @@ export class App extends PureComponent { // reads the state. formsWithPendingRequestsChanged: formIds => this.widgetMgr.setFormsWithUploads(formIds), + requestFileURLs: this.requestFileURLs, }) this.componentRegistry = new ComponentRegistry(this.endpoints) @@ -575,6 +575,8 @@ export class App extends PureComponent { this.handleScriptFinished(status), pageProfile: (pageProfile: PageProfile) => this.handlePageProfileMsg(pageProfile), + fileUrlsResponse: (fileURLsResponse: FileURLsResponse) => + this.uploadClient.onFileURLsResponse(fileURLsResponse), }) } catch (e) { const err = ensureError(e) @@ -1336,7 +1338,6 @@ export class App extends PureComponent { type: DialogType.DEPLOY_DIALOG, onClose: this.closeDialog, showDeployError: this.showDeployError, - gitInfo: this.state.gitInfo, isDeployErrorModalOpen: this.state.dialog?.type === DialogType.DEPLOY_ERROR, metricsMgr: this.metricsMgr, @@ -1508,23 +1509,35 @@ export class App extends PureComponent { showDeployButton = (): boolean => { return ( - isTesting() || - (SHOW_DEPLOY_BUTTON && - showDevelopmentOptions(this.state.isOwner, this.state.toolbarMode) && - !this.isInCloudEnvironment() && - this.sessionInfo.isSet && - !this.sessionInfo.isHello) + showDevelopmentOptions(this.state.isOwner, this.state.toolbarMode) && + !this.isInCloudEnvironment() && + this.sessionInfo.isSet && + !this.sessionInfo.isHello ) } deployButtonClicked = (): void => { - if (!isTesting()) { - this.metricsMgr.enqueue("deployButtonInApp", { clicked: true }) - } + this.metricsMgr.enqueue("menuClick", { + label: "deployButtonInApp", + }) this.sendLoadGitInfoBackMsg() this.openDeployDialog() } + requestFileURLs = (requestId: string, files: File[]): void => { + if (this.isServerConnected()) { + const backMsg = new BackMsg({ + fileUrlsRequest: { + requestId, + fileNames: files.map(f => f.name), + sessionId: this.sessionInfo.current.sessionId, + }, + }) + backMsg.type = "fileUrlsRequest" + this.sendBackMsg(backMsg) + } + } + render(): JSX.Element { const { allowRunOnSave, @@ -1537,7 +1550,6 @@ export class App extends PureComponent { scriptRunId, scriptRunState, userSettings, - gitInfo, hideTopBar, hideSidebarNav, currentPageScriptHash, @@ -1587,6 +1599,7 @@ export class App extends PureComponent { pageLinkBaseUrl, sidebarChevronDownshift, toastAdjustment: hostToolbarItems.length > 0, + gitInfo: this.state.gitInfo, }} > { sendMessageToHost={ this.hostCommunicationMgr.sendMessageToHost } - gitInfo={gitInfo} - showDeployError={this.showDeployError} - closeDialog={this.closeDialog} - isDeployErrorModalOpen={ - this.state.dialog?.type === DialogType.DEPLOY_ERROR - } - loadGitInfo={this.sendLoadGitInfoBackMsg} - canDeploy={ - this.sessionInfo.isSet && !this.sessionInfo.isHello - } menuItems={menuItems} metricsMgr={this.metricsMgr} toolbarMode={this.state.toolbarMode} diff --git a/frontend/app/src/StreamlitLib.test.tsx b/frontend/app/src/StreamlitLib.test.tsx index 6e4683cc3f81..b6d97f015967 100644 --- a/frontend/app/src/StreamlitLib.test.tsx +++ b/frontend/app/src/StreamlitLib.test.tsx @@ -53,6 +53,10 @@ class Endpoints implements StreamlitEndpoints { return url } + public buildFileUploadURL(url: string): string { + return url + } + public buildAppPageURL( pageLinkBaseURL: string | undefined, page: IAppPage, @@ -62,12 +66,16 @@ class Endpoints implements StreamlitEndpoints { } public uploadFileUploaderFile( + fileUploadUrl: string, file: File, - widgetId: string, sessionId: string, onUploadProgress?: (progressEvent: any) => void, cancelToken?: CancelToken - ): Promise { + ): Promise { + return Promise.reject(new Error("Unimplemented")) + } + + public deleteFileAtURL(fileUrl: string, sessionId: string): Promise { return Promise.reject(new Error("Unimplemented")) } @@ -115,6 +123,7 @@ class StreamlitLibExample extends PureComponent { // reads the state. formsWithPendingRequestsChanged: formIds => this.widgetMgr.setFormsWithUploads(formIds), + requestFileURLs: jest.fn(), }) this.sessionInfo.setCurrent({ diff --git a/frontend/app/src/ThemedApp.tsx b/frontend/app/src/ThemedApp.tsx index 450e6fdc9bc7..ae2e721611d7 100644 --- a/frontend/app/src/ThemedApp.tsx +++ b/frontend/app/src/ThemedApp.tsx @@ -15,8 +15,6 @@ */ import React from "react" -import { BaseProvider } from "baseui" -import { Global, ThemeProvider as EmotionThemeProvider } from "@emotion/react" import FontFaceDeclaration from "@streamlit/app/src/components/FontFaceDeclaration" import { @@ -25,7 +23,6 @@ import { createAutoTheme, createPresetThemes, getDefaultTheme, - globalStyles, isPresetTheme, removeCachedTheme, setCachedTheme, @@ -33,6 +30,7 @@ import { createTheme, CustomThemeConfig, ICustomThemeConfig, + RootStyleProvider, } from "@streamlit/lib" import AppWithScreencast from "./App" @@ -101,28 +99,22 @@ const ThemedApp = (): JSX.Element => { }, [theme, availableThemes, updateAutoTheme]) return ( - - - - {theme.name === CUSTOM_THEME_NAME && fontFaces && ( - - )} - - {/* The data grid requires one root level portal element for rendering cell overlays */} - - - + + {theme.name === CUSTOM_THEME_NAME && fontFaces && ( + + )} + + {/* The data grid requires one root level portal element for rendering cell overlays */} + + ) } diff --git a/frontend/app/src/components/AppContext.tsx b/frontend/app/src/components/AppContext.tsx index 4b701e2d00e0..0fc0ab12c982 100644 --- a/frontend/app/src/components/AppContext.tsx +++ b/frontend/app/src/components/AppContext.tsx @@ -16,7 +16,7 @@ import React from "react" -import { PageConfig } from "@streamlit/lib" +import { PageConfig, IGitInfo } from "@streamlit/lib" export interface Props { /** @@ -90,6 +90,11 @@ export interface Props { * @see EventContainer */ toastAdjustment: boolean + + /** + * The latest state of the git information related to the app. + */ + gitInfo: IGitInfo | null } export const AppContext = React.createContext({ @@ -104,4 +109,5 @@ export const AppContext = React.createContext({ pageLinkBaseUrl: "", sidebarChevronDownshift: 0, toastAdjustment: false, + gitInfo: null, }) diff --git a/frontend/app/src/components/AppView/AppView.test.tsx b/frontend/app/src/components/AppView/AppView.test.tsx index f19d5dd78f74..acf6f58f9d46 100644 --- a/frontend/app/src/components/AppView/AppView.test.tsx +++ b/frontend/app/src/components/AppView/AppView.test.tsx @@ -15,8 +15,8 @@ */ import React from "react" -import { screen } from "@testing-library/react" import "@testing-library/jest-dom" +import { screen } from "@testing-library/react" import { AppContext, Props as AppContextProps, @@ -80,6 +80,7 @@ function getProps(props: Partial = {}): AppViewProps { sessionInfo: sessionInfo, endpoints: endpoints, formsWithPendingRequestsChanged: () => {}, + requestFileURLs: jest.fn(), }), widgetsDisabled: true, componentRegistry: new ComponentRegistry(endpoints), @@ -206,9 +207,11 @@ describe("AppView element", () => { const props = getProps({ elements: new AppRoot(new BlockNode([main, sidebar, event])), }) - const { getByTestId } = render() + render() - const style = window.getComputedStyle(getByTestId("block-container")) + const style = window.getComputedStyle( + screen.getByTestId("block-container") + ) expect(style.maxWidth).not.toEqual("initial") }) @@ -221,9 +224,10 @@ describe("AppView element", () => { return realUseContext(input) }) - const { getByTestId } = render() - const style = window.getComputedStyle(getByTestId("block-container")) - + render() + const style = window.getComputedStyle( + screen.getByTestId("block-container") + ) expect(style.maxWidth).toEqual("initial") }) @@ -244,10 +248,10 @@ describe("AppView element", () => { return realUseContext(input) }) - const { getByRole, getByTestId } = render() + render() - expect(getByTestId("AppViewBlockSpacer")).toBeInTheDocument() - expect(getByRole("contentinfo")).toBeInTheDocument() + expect(screen.getByTestId("AppViewBlockSpacer")).toBeInTheDocument() + expect(screen.getByRole("contentinfo")).toBeInTheDocument() }) it("does not render the Spacer and Footer when embedded", () => { @@ -260,10 +264,10 @@ describe("AppView element", () => { return realUseContext(input) }) - const { queryByRole, queryByTestId } = render() + render() - expect(queryByTestId("AppViewBlockSpacer")).not.toBeInTheDocument() - expect(queryByRole("contentinfo")).not.toBeInTheDocument() + expect(screen.queryByTestId("AppViewBlockSpacer")).not.toBeInTheDocument() + expect(screen.queryByRole("contentinfo")).not.toBeInTheDocument() }) describe("when window.location.hash changes", () => { diff --git a/frontend/app/src/components/EventContainer/EventContainer.tsx b/frontend/app/src/components/EventContainer/EventContainer.tsx index 3c3988733c9e..eca2d03cb226 100644 --- a/frontend/app/src/components/EventContainer/EventContainer.tsx +++ b/frontend/app/src/components/EventContainer/EventContainer.tsx @@ -41,8 +41,10 @@ function EventContainer({ overrides={{ Root: { style: { - // If deployed in Community Cloud, move toasts up to avoid blocking Manage App button + // Avoids blocking host elements at bottom of page bottom: toastAdjustment ? "45px" : "0px", + // Toasts overlap chatInput container + zIndex: 100, }, props: { "data-testid": "toastContainer", diff --git a/frontend/app/src/components/MainMenu/MainMenu.test.tsx b/frontend/app/src/components/MainMenu/MainMenu.test.tsx index 1d47bab99106..d8c6679ccc98 100644 --- a/frontend/app/src/components/MainMenu/MainMenu.test.tsx +++ b/frontend/app/src/components/MainMenu/MainMenu.test.tsx @@ -15,30 +15,25 @@ */ import React from "react" - +import "@testing-library/jest-dom" +import { + screen, + waitFor, + fireEvent, + RenderResult, + Screen, +} from "@testing-library/react" import { mount, render, IMenuItem, mockSessionInfo, Config, - GitInfo, - IGitInfo, } from "@streamlit/lib" -import { IDeployErrorDialog } from "@streamlit/app/src/components/StreamlitDialog/DeployErrorDialogs/types" -import { - DetachedHead, - ModuleIsNotAdded, - NoRepositoryDetected, -} from "@streamlit/app/src/components/StreamlitDialog/DeployErrorDialogs" import { SegmentMetricsManager } from "@streamlit/app/src/SegmentMetricsManager" import MainMenu, { Props } from "./MainMenu" -import { waitFor } from "@testing-library/dom" -import { fireEvent, RenderResult } from "@testing-library/react" - -const { GitStates } = GitInfo const getProps = (extend?: Partial): Props => ({ aboutCallback: jest.fn(), @@ -51,22 +46,18 @@ const getProps = (extend?: Partial): Props => ({ screenCastState: "", sendMessageToHost: jest.fn(), settingsCallback: jest.fn(), - isDeployErrorModalOpen: false, - showDeployError: jest.fn(), - loadGitInfo: jest.fn(), - closeDialog: jest.fn(), - canDeploy: true, menuItems: {}, developmentMode: true, - gitInfo: null, metricsMgr: new SegmentMetricsManager(mockSessionInfo()), toolbarMode: Config.ToolbarMode.AUTO, ...extend, }) -async function openMenu(wrapper: RenderResult): Promise { - fireEvent.click(wrapper.getByRole("button")) - await waitFor(() => expect(wrapper.findByRole("listbox")).toBeDefined()) +async function openMenu(screen: Screen): Promise { + fireEvent.click(screen.getByRole("button")) + // Each SubMenu is a listbox, so need to use findAllByRole (findByRole throws error if multiple matches) + const menu = await screen.findAllByRole("listbox") + expect(menu).toBeDefined() } function getMenuStructure( @@ -117,143 +108,47 @@ describe("MainMenu", () => { const props = getProps({ hostMenuItems: items, }) - const wrapper = render() - await openMenu(wrapper) + render() + await openMenu(screen) - await waitFor(() => - expect( - wrapper - .getAllByRole("option") - .map(item => item.querySelector("span:first-of-type")?.textContent) - ).toEqual([ - "Rerun", - "Settings", - "Print", - "Record a screencast", - "View app source", - "Report bug with app", - "About", - "Developer options", - "Clear cache", - ]) - ) - }) + const menuOptions = await screen.findAllByRole("option") - it("should render core set of menu elements", async () => { - const props = getProps() - const wrapper = render() - await openMenu(wrapper) - - await waitFor(() => - expect( - wrapper - .getAllByRole("option") - .map(item => item.querySelector("span:first-of-type")?.textContent) - ).toEqual([ - "Rerun", - "Settings", - "Print", - "Record a screencast", - "About", - "Developer options", - "Clear cache", - "Deploy this app", - ]) - ) - }) - - it("should render deploy app menu item", async () => { - const props = getProps({ gitInfo: {} }) - const wrapper = render() - await openMenu(wrapper) + const expectedLabels = [ + "Rerun", + "Settings", + "Print", + "Record a screencast", + "View app source", + "Report bug with app", + "About", + "Developer options", + "Clear cache", + ] - await waitFor(() => - expect( - wrapper.getByRole("option", { name: "Deploy this app" }) - ).toBeDefined() - ) + expectedLabels.forEach((label, index) => { + expect(menuOptions[index]).toHaveTextContent(label) + }) }) - describe("Onclick deploy button", () => { - function testDeployErrorModal( - gitInfo: Partial, - dialogComponent: (module: string) => IDeployErrorDialog - ): void { - const props = getProps({ - gitInfo, - }) - const wrapper = mount() - const popoverContent = wrapper.find("StatefulPopover").prop("content") - - // @ts-expect-error - const menuWrapper = mount(popoverContent(() => {})) - const items: any = menuWrapper.find("StatefulMenu").at(1).prop("items") - - const deployOption = items.find( - // @ts-expect-error - ({ label }) => label === "Deploy this app" - ) - - deployOption.onClick() - - // @ts-expect-error - const dialog = dialogComponent(props.gitInfo.module) - // @ts-expect-error - expect(props.showDeployError.mock.calls[0][0]).toStrictEqual( - dialog.title - ) - // @ts-expect-error - expect(props.showDeployError.mock.calls[0][1]).toStrictEqual(dialog.body) - } - - // eslint-disable-next-line jest/expect-expect -- underlying testDeployErrorModal function has expect statements - it("should display the correct modal if there is no repo or remote", () => { - testDeployErrorModal( - { - state: GitStates.DEFAULT, - }, - NoRepositoryDetected - ) - }) + it("should render core set of menu elements", async () => { + const props = getProps() + render() + await openMenu(screen) - // eslint-disable-next-line jest/expect-expect - it("should display the correct modal if there is an empty repo", () => { - testDeployErrorModal( - { - repository: "", - branch: "", - module: "", - state: GitStates.DEFAULT, - }, - NoRepositoryDetected - ) - }) + const menuOptions = await screen.findAllByRole("option") - // eslint-disable-next-line jest/expect-expect - it("should display the correct modal if the repo is detached", () => { - testDeployErrorModal( - { - repository: "repo", - branch: "branch", - module: "module", - state: GitStates.HEAD_DETACHED, - }, - DetachedHead - ) - }) + const expectedLabels = [ + "Rerun", + "Settings", + "Print", + "Record a screencast", + "About", + "Developer options", + "Clear cache", + ] - // eslint-disable-next-line jest/expect-expect - it("should display the correct modal if the script is not added to the repo", () => { - testDeployErrorModal( - { - repository: "repo", - branch: "branch", - module: "module.py", - state: GitStates.DEFAULT, - untrackedFiles: ["module.py"], - }, - ModuleIsNotAdded - ) + expectedLabels.forEach((label, index) => { + expect(menuOptions[index]).toHaveTextContent(label) }) }) @@ -274,7 +169,6 @@ describe("MainMenu", () => { .find("MenuStatefulContainer") .at(0) .prop("items") - // @ts-expect-error .map(item => item.label) expect(menuLabels).toEqual([ "Rerun", @@ -293,13 +187,11 @@ describe("MainMenu", () => { aboutSectionMd: "", } const props = getProps({ menuItems }) - const wrapper = render() - await openMenu(wrapper) + render() + await openMenu(screen) await waitFor(() => - expect( - wrapper.queryByRole("option", { name: "Report a bug" }) - ).toBeNull() + expect(screen.queryByRole("option", { name: "Report a bug" })).toBeNull() ) }) @@ -311,14 +203,13 @@ describe("MainMenu", () => { aboutSectionMd: "", } const props = getProps({ menuItems }) - const wrapper = render() - await openMenu(wrapper) + render() + await openMenu(screen) - await waitFor(() => - expect( - wrapper.getByRole("option", { name: "Report a bug" }) - ).toBeDefined() - ) + const reportOption = await screen.findByRole("option", { + name: "Report a bug", + }) + expect(reportOption).toBeDefined() }) it("should not render dev menu when developmentMode is false", () => { @@ -333,7 +224,6 @@ describe("MainMenu", () => { .find("MenuStatefulContainer") // make sure that we only have one menu otherwise prop will fail .prop("items") - // @ts-expect-error .map(item => item.label) expect(menuLabels).toEqual([ "Rerun", @@ -356,10 +246,10 @@ describe("MainMenu", () => { { label: "Host menu item", key: "host-item", type: "text" }, ], }) - const wrapper = render() - await openMenu(wrapper) + const view = render() + await openMenu(screen) - const menuStructure = getMenuStructure(wrapper) + const menuStructure = getMenuStructure(view) expect(menuStructure[0]).toContainEqual({ type: "option", label: "Host menu item", @@ -373,9 +263,9 @@ describe("MainMenu", () => { hostMenuItems: [], }) - const wrapper = render() + render() - expect(wrapper.queryByRole("button")).toBeNull() + expect(screen.queryByRole("button")).toBeNull() }) it("should skip divider from host menu items if it is at the beginning and end", async () => { @@ -390,10 +280,10 @@ describe("MainMenu", () => { { type: "separator" }, ], }) - const wrapper = render() - await openMenu(wrapper) + const view = render() + await openMenu(screen) - const menuStructure = getMenuStructure(wrapper) + const menuStructure = getMenuStructure(view) expect(menuStructure).toEqual([ [{ type: "option", label: "View all apps" }], ]) @@ -463,10 +353,10 @@ describe("MainMenu", () => { ), }) - const wrapper = render() - await openMenu(wrapper) + const view = render() + await openMenu(screen) - const menuStructure = getMenuStructure(wrapper) + const menuStructure = getMenuStructure(view) expect(menuStructure).toEqual([expectedMenuItems]) } ) @@ -488,10 +378,10 @@ describe("MainMenu", () => { aboutSectionMd: "# This is a header. This is an *extremely* cool app!", }, }) - const wrapper = render() - await openMenu(wrapper) + const view = render() + await openMenu(screen) - const menuStructure = getMenuStructure(wrapper) + const menuStructure = getMenuStructure(view) expect(menuStructure).toEqual([ [ { diff --git a/frontend/app/src/components/MainMenu/MainMenu.tsx b/frontend/app/src/components/MainMenu/MainMenu.tsx index 50ff72641b10..81bdb335c053 100644 --- a/frontend/app/src/components/MainMenu/MainMenu.tsx +++ b/frontend/app/src/components/MainMenu/MainMenu.tsx @@ -14,19 +14,12 @@ * limitations under the License. */ -import React, { - forwardRef, - memo, - MouseEvent, - ReactElement, - ReactNode, - useCallback, - useEffect, -} from "react" +import React, { forwardRef, memo, MouseEvent, ReactElement } from "react" import { StatefulMenu } from "baseui/menu" +import { PLACEMENT, StatefulPopover } from "baseui/popover" import { MoreVert } from "@emotion-icons/material-rounded" - import { useTheme } from "@emotion/react" + import { EmotionTheme, BaseButton, @@ -35,18 +28,10 @@ import { IGuestToHostMessage, IMenuItem, Config, - GitInfo, - IGitInfo, PageConfig, } from "@streamlit/lib" -import { PLACEMENT, StatefulPopover } from "baseui/popover" -import { - DetachedHead, - ModuleIsNotAdded, - NoRepositoryDetected, -} from "@streamlit/app/src/components/StreamlitDialog/DeployErrorDialogs" -import { DEPLOY_URL, STREAMLIT_CLOUD_URL } from "@streamlit/app/src/urls" import { SegmentMetricsManager } from "@streamlit/app/src/SegmentMetricsManager" + import { StyledCoreItem, StyledDevItem, @@ -59,8 +44,6 @@ import { StyledMainMenuContainer, } from "./styled-components" -const { GitStates } = GitInfo - const SCREENCAST_LABEL: { [s: string]: string } = { COUNTDOWN: "Cancel screencast", RECORDING: "Stop recording", @@ -73,9 +56,6 @@ export interface Props { /** Rerun the current script. */ quickRerunCallback: () => void - /** Reload git information message */ - loadGitInfo: () => void - /** Clear the cache. */ clearCacheCallback: () => void @@ -97,20 +77,6 @@ export interface Props { sendMessageToHost: (message: IGuestToHostMessage) => void - gitInfo: IGitInfo | null - - showDeployError: ( - title: string, - errorNode: ReactNode, - onContinue?: () => void - ) => void - - closeDialog: () => void - - isDeployErrorModalOpen: boolean - - canDeploy: boolean - menuItems?: PageConfig.IMenuItems | null developmentMode: boolean @@ -124,23 +90,6 @@ const getOpenInWindowCallback = (url: string) => (): void => { window.open(url, "_blank") } -export const getDeployAppUrl = (gitInfo: IGitInfo | null): (() => void) => { - // If the app was run inside a GitHub repo, autofill for a one-click deploy. - // E.g.: https://share.streamlit.io/deploy?repository=melon&branch=develop&mainModule=streamlit_app.py - if (gitInfo) { - const deployUrl = new URL(DEPLOY_URL) - - deployUrl.searchParams.set("repository", gitInfo.repository || "") - deployUrl.searchParams.set("branch", gitInfo.branch || "") - deployUrl.searchParams.set("mainModule", gitInfo.module || "") - - return getOpenInWindowCallback(deployUrl.toString()) - } - - // Otherwise, just direct them to the Streamlit Cloud page. - return getOpenInWindowCallback(STREAMLIT_CLOUD_URL) -} - export const isLocalhost = (): boolean => { return ( window.location.hostname === "localhost" || @@ -270,7 +219,11 @@ const SubMenu = (props: SubMenuProps): ReactElement => { }, style: { backgroundColor: "inherit", - borderRadius: 0, + + borderBottomRadius: 0, + borderTopRadius: 0, + borderLeftRadius: 0, + borderRightRadius: 0, ":focus": { outline: "none", @@ -283,15 +236,11 @@ const SubMenu = (props: SubMenuProps): ReactElement => { ) } -function getDevMenuItems( - coreDevMenuItems: Record, - showDeploy: boolean -): any[] { +function getDevMenuItems(coreDevMenuItems: Record): any[] { const devMenuItems = [] const preferredDevMenuOrder: any[] = [ coreDevMenuItems.developerOptions, coreDevMenuItems.clearCache, - showDeploy && coreDevMenuItems.deployApp, ] let devLastMenuItem = null @@ -373,67 +322,6 @@ function getPreferredMenuOrder( function MainMenu(props: Props): ReactElement { const isServerDisconnected = !props.isServerConnected - const onClickDeployApp = useCallback((): void => { - const { showDeployError, isDeployErrorModalOpen, gitInfo, closeDialog } = - props - - if (!gitInfo) { - const dialog = NoRepositoryDetected() - - showDeployError(dialog.title, dialog.body) - - return - } - - const { - repository, - branch, - module, - untrackedFiles, - state: gitState, - } = gitInfo - const hasMissingGitInfo = !repository || !branch || !module - - if (hasMissingGitInfo && gitState === GitStates.DEFAULT) { - const dialog = NoRepositoryDetected() - - showDeployError(dialog.title, dialog.body) - - return - } - - if (gitState === GitStates.HEAD_DETACHED) { - const dialog = DetachedHead() - - showDeployError(dialog.title, dialog.body) - - return - } - - if (module && untrackedFiles?.includes(module)) { - const dialog = ModuleIsNotAdded(module) - - showDeployError(dialog.title, dialog.body) - - return - } - - // We should close the modal when we try again and everything goes fine - if (isDeployErrorModalOpen) { - closeDialog() - } - - getDeployAppUrl(gitInfo)() - }, [props]) - - useEffect(() => { - if (!props.gitInfo || !props.isDeployErrorModalOpen) { - return - } - - onClickDeployApp() - }, [props.gitInfo, props.isDeployErrorModalOpen, onClickDeployApp]) - const showAboutMenu = props.toolbarMode != Config.ToolbarMode.MINIMAL || (props.toolbarMode == Config.ToolbarMode.MINIMAL && @@ -480,10 +368,6 @@ function MainMenu(props: Props): ReactElement { const coreDevMenuItems = { DIVIDER: { isDivider: true }, - deployApp: { - onClick: onClickDeployApp, - label: "Deploy this app", - }, developerOptions: { label: "Developer options", noHighlight: true, @@ -530,8 +414,6 @@ function MainMenu(props: Props): ReactElement { } }, [] as any[]) - const shouldShowHostMenu = !!hostMenuItems.length - const showDeploy = isLocalhost() && !shouldShowHostMenu && props.canDeploy const preferredMenuOrder = getPreferredMenuOrder( props, hostMenuItems, @@ -556,7 +438,7 @@ function MainMenu(props: Props): ReactElement { } const devMenuItems: any[] = props.developmentMode - ? getDevMenuItems(coreDevMenuItems, showDeploy) + ? getDevMenuItems(coreDevMenuItems) : [] if (menuItems.length == 0 && devMenuItems.length == 0) { @@ -567,11 +449,6 @@ function MainMenu(props: Props): ReactElement { return ( { - if (showDeploy) { - props.loadGitInfo() - } - }} placement={PLACEMENT.bottomRight} content={({ close }) => ( diff --git a/frontend/app/src/components/Sidebar/Sidebar.test.tsx b/frontend/app/src/components/Sidebar/Sidebar.test.tsx index 24f8797547b2..064085727207 100644 --- a/frontend/app/src/components/Sidebar/Sidebar.test.tsx +++ b/frontend/app/src/components/Sidebar/Sidebar.test.tsx @@ -30,7 +30,7 @@ import SidebarNav from "./SidebarNav" expect.extend(matchers) -function renderSideBar(props: Partial = {}): ReactWrapper { +function mountSidebar(props: Partial = {}): ReactWrapper { return mount( = {}): ReactWrapper { describe("Sidebar Component", () => { it("should render without crashing", () => { - const wrapper = renderSideBar({}) + const wrapper = mountSidebar({}) expect(wrapper.find("StyledSidebar").exists()).toBe(true) }) it("should render expanded", () => { - const wrapper = renderSideBar({ + const wrapper = mountSidebar({ initialSidebarState: PageConfig.SidebarState.EXPANDED, }) @@ -62,7 +62,7 @@ describe("Sidebar Component", () => { }) it("should render collapsed", () => { - const wrapper = renderSideBar({ + const wrapper = mountSidebar({ initialSidebarState: PageConfig.SidebarState.COLLAPSED, }) @@ -70,7 +70,7 @@ describe("Sidebar Component", () => { }) it("should collapse on toggle if expanded", () => { - const wrapper = renderSideBar({ + const wrapper = mountSidebar({ initialSidebarState: PageConfig.SidebarState.EXPANDED, }) @@ -79,7 +79,7 @@ describe("Sidebar Component", () => { }) it("should expand on toggle if collapsed", () => { - const wrapper = renderSideBar({ + const wrapper = mountSidebar({ initialSidebarState: PageConfig.SidebarState.COLLAPSED, }) @@ -91,7 +91,7 @@ describe("Sidebar Component", () => { }) it("chevron does not render if sidebar expanded", () => { - const wrapper = renderSideBar({ + const wrapper = mountSidebar({ initialSidebarState: PageConfig.SidebarState.EXPANDED, }) @@ -99,7 +99,7 @@ describe("Sidebar Component", () => { }) it("hides scrollbar when hideScrollbar is called", () => { - const wrapper = renderSideBar({}) + const wrapper = mountSidebar({}) expect(wrapper.find("StyledSidebarContent")).toHaveStyleRule( "overflow", @@ -116,7 +116,7 @@ describe("Sidebar Component", () => { }) it("has extra top and bottom padding if no SidebarNav is displayed", () => { - const wrapper = renderSideBar({ + const wrapper = mountSidebar({ appPages: [{ pageName: "streamlit_app", pageScriptHash: "page_hash" }], }) @@ -127,7 +127,7 @@ describe("Sidebar Component", () => { }) it("has less padding if the SidebarNav is displayed", () => { - const wrapper = renderSideBar({ + const wrapper = mountSidebar({ appPages: [ { pageName: "streamlit_app", pageScriptHash: "page_hash" }, { pageName: "streamlit_app2", pageScriptHash: "page_hash2" }, @@ -141,7 +141,7 @@ describe("Sidebar Component", () => { }) it("uses the default chevron spacing if chevronDownshift is zero", () => { - const wrapper = renderSideBar({ + const wrapper = mountSidebar({ chevronDownshift: 0, initialSidebarState: PageConfig.SidebarState.COLLAPSED, }) @@ -153,7 +153,7 @@ describe("Sidebar Component", () => { }) it("uses the given chevron spacing if chevronDownshift is nonzero", () => { - const wrapper = renderSideBar({ + const wrapper = mountSidebar({ chevronDownshift: 50, initialSidebarState: PageConfig.SidebarState.COLLAPSED, }) @@ -169,7 +169,7 @@ describe("Sidebar Component", () => { { pageName: "streamlit_app", pageScriptHash: "page_hash" }, { pageName: "streamlit_app2", pageScriptHash: "page_hash2" }, ] - const wrapper = renderSideBar({ appPages }) + const wrapper = mountSidebar({ appPages }) expect(wrapper.find(SidebarNav).exists()).toBe(true) expect(wrapper.find(SidebarNav).prop("appPages")).toEqual(appPages) @@ -186,7 +186,7 @@ describe("Sidebar Component", () => { { pageName: "streamlit_app", pageScriptHash: "page_hash" }, { pageName: "streamlit_app2", pageScriptHash: "page_hash2" }, ] - const wrapper = renderSideBar({ appPages, hideSidebarNav: true }) + const wrapper = mountSidebar({ appPages, hideSidebarNav: true }) expect(wrapper.find(SidebarNav).exists()).toBe(false) expect( diff --git a/frontend/app/src/components/Sidebar/SidebarNav.test.tsx b/frontend/app/src/components/Sidebar/SidebarNav.test.tsx index 1ac2d7bf35c9..6e13b2267d99 100644 --- a/frontend/app/src/components/Sidebar/SidebarNav.test.tsx +++ b/frontend/app/src/components/Sidebar/SidebarNav.test.tsx @@ -43,7 +43,7 @@ expect.extend(matchers) jest.mock("@streamlit/lib/src/util/Hooks", () => ({ __esModule: true, - ...jest.requireActual("@streamlit/lib/dist/util/Hooks"), + ...jest.requireActual("@streamlit/lib/src/util/Hooks"), useIsOverflowing: jest.fn(), })) diff --git a/frontend/app/src/components/StreamlitDialog/DeployDialog/DeployCard.tsx b/frontend/app/src/components/StreamlitDialog/DeployDialog/DeployCard.tsx index a7c9f215b87d..ceaee389c72e 100644 --- a/frontend/app/src/components/StreamlitDialog/DeployDialog/DeployCard.tsx +++ b/frontend/app/src/components/StreamlitDialog/DeployDialog/DeployCard.tsx @@ -33,21 +33,42 @@ function DeployCard( overrides={{ Root: { style: { - borderWidth: "1px", - borderStyle: "solid", - borderColor: colors.fadedText10, - borderRadius: radii.lg, + borderTopWidth: "1px", + borderBottomWidth: "1px", + borderLeftWidth: "1px", + borderRightWidth: "1px", + + borderTopStyle: "solid", + borderBottomStyle: "solid", + borderLeftStyle: "solid", + borderRightStyle: "solid", + + borderTopColor: colors.fadedText10, + borderBottomColor: colors.fadedText10, + borderLeftColor: colors.fadedText10, + borderRightColor: colors.fadedText10, + + borderRadiusBottom: radii.lg, + borderRadiusTop: radii.lg, + borderRadiusLeft: radii.lg, + borderRadiusRight: radii.lg, }, }, Contents: { style: { - margin: 0, + marginBottom: 0, + marginTop: 0, + marginLeft: 0, + marginRight: 0, }, }, Body: { style: { padding: spacing.threeXL, - margin: 0, + marginBottom: 0, + marginTop: 0, + marginLeft: 0, + marginRight: 0, [`@media (max-width: ${breakpoints.md})`]: { padding: spacing.xl, diff --git a/frontend/app/src/components/StreamlitDialog/DeployDialog/DeployDialog.tsx b/frontend/app/src/components/StreamlitDialog/DeployDialog/DeployDialog.tsx index cd65c95ed78e..c98e10e995e0 100644 --- a/frontend/app/src/components/StreamlitDialog/DeployDialog/DeployDialog.tsx +++ b/frontend/app/src/components/StreamlitDialog/DeployDialog/DeployDialog.tsx @@ -14,37 +14,60 @@ * limitations under the License. */ -import React, { ReactElement, ReactNode, useCallback } from "react" -import { SegmentMetricsManager } from "@streamlit/app/src/SegmentMetricsManager" -import Modal from "./DeployModal" -import Card from "./DeployCard" -import ListElement from "./DeployListElement" +import React, { ReactElement, ReactNode, useCallback, useContext } from "react" import { StyledBody, StyledAction } from "baseui/card" -import { - StyledSubheader, - StyledActionsWrapper, - StyledCardContainer, -} from "./styled-components" + +import { BaseButton, BaseButtonKind, GitInfo, IGitInfo } from "@streamlit/lib" +import { SegmentMetricsManager } from "@streamlit/app/src/SegmentMetricsManager" import { DialogType, PlainEventHandler, } from "@streamlit/app/src/components/StreamlitDialog/StreamlitDialog" -import { BaseButton, BaseButtonKind, GitInfo, IGitInfo } from "@streamlit/lib" +import { AppContext } from "@streamlit/app/src/components/AppContext" import StreamlitLogo from "@streamlit/app/src/assets/svg/logo.svg" import Rocket from "@streamlit/app/src/assets/svg/rocket.svg" import { STREAMLIT_COMMUNITY_CLOUD_DOCS_URL, STREAMLIT_DEPLOY_TUTORIAL_URL, + DEPLOY_URL, + STREAMLIT_CLOUD_URL, } from "@streamlit/app/src/urls" import { DetachedHead, ModuleIsNotAdded, NoRepositoryDetected, } from "@streamlit/app/src/components/StreamlitDialog/DeployErrorDialogs" -import { getDeployAppUrl } from "@streamlit/app/src/components/MainMenu/MainMenu" + +import Modal from "./DeployModal" +import Card from "./DeployCard" +import ListElement from "./DeployListElement" +import { + StyledSubheader, + StyledActionsWrapper, + StyledCardContainer, +} from "./styled-components" const { GitStates } = GitInfo +const openUrl = (url: string): void => { + window.open(url, "_blank") +} + +const getDeployAppUrl = (gitInfo: IGitInfo | null): string => { + if (gitInfo) { + // If the app was run inside a GitHub repo, autofill for a one-click deploy. + // E.g.: https://share.streamlit.io/deploy?repository=melon&branch=develop&mainModule=streamlit_app.py + const deployUrl = new URL(DEPLOY_URL) + + deployUrl.searchParams.set("repository", gitInfo.repository || "") + deployUrl.searchParams.set("branch", gitInfo.branch || "") + deployUrl.searchParams.set("mainModule", gitInfo.module || "") + return deployUrl.toString() + } + // If not in git repo, direct them to the Streamlit Cloud page. + return STREAMLIT_CLOUD_URL +} + export interface DeployDialogProps { type: DialogType.DEPLOY_DIALOG onClose: PlainEventHandler @@ -54,16 +77,18 @@ export interface DeployDialogProps { onContinue?: () => void ) => void isDeployErrorModalOpen: boolean - gitInfo: IGitInfo | null metricsMgr: SegmentMetricsManager } export function DeployDialog(props: DeployDialogProps): ReactElement { + // Get latest git info from AppContext: + const { gitInfo } = useContext(AppContext) const { onClose, metricsMgr } = props const onClickDeployApp = useCallback((): void => { - const { showDeployError, isDeployErrorModalOpen, gitInfo, metricsMgr } = - props - metricsMgr.enqueue("deployButtonInDialog", { clicked: true }) + const { showDeployError, isDeployErrorModalOpen, metricsMgr } = props + metricsMgr.enqueue("menuClick", { + label: "deployButtonInDialog", + }) if (!gitInfo) { const dialog = NoRepositoryDetected() @@ -111,8 +136,8 @@ export function DeployDialog(props: DeployDialogProps): ReactElement { onClose() } - getDeployAppUrl(gitInfo)() - }, [props, onClose]) + openUrl(getDeployAppUrl(gitInfo)) + }, [props, onClose, gitInfo]) return ( @@ -140,10 +165,10 @@ export function DeployDialog(props: DeployDialogProps): ReactElement { { - metricsMgr.enqueue("readMoreCommunityCloudInDeployDialog", { - clicked: true, + metricsMgr.enqueue("menuClick", { + label: "readMoreCommunityCloudInDeployDialog", }) - window.open(STREAMLIT_COMMUNITY_CLOUD_DOCS_URL, "_blank") + openUrl(STREAMLIT_COMMUNITY_CLOUD_DOCS_URL) }} kind={BaseButtonKind.MINIMAL} > @@ -167,10 +192,10 @@ export function DeployDialog(props: DeployDialogProps): ReactElement { { - metricsMgr.enqueue("readMoreDeployTutorialInDeployDialog", { - clicked: true, + metricsMgr.enqueue("menuClick", { + label: "readMoreDeployTutorialInDeployDialog", }) - window.open(STREAMLIT_DEPLOY_TUTORIAL_URL, "_blank") + openUrl(STREAMLIT_DEPLOY_TUTORIAL_URL) }} kind={BaseButtonKind.MINIMAL} > diff --git a/frontend/app/src/components/StreamlitDialog/DeployErrorDialogs/RepoIsAhead.test.tsx b/frontend/app/src/components/StreamlitDialog/DeployErrorDialogs/RepoIsAhead.test.tsx deleted file mode 100644 index 64ca1a2f597a..000000000000 --- a/frontend/app/src/components/StreamlitDialog/DeployErrorDialogs/RepoIsAhead.test.tsx +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import RepoIsAhead from "./RepoIsAhead" - -describe("DeployErrorDialog - RepoIsAhead", () => { - it("should render without crashing", () => { - const dialog = RepoIsAhead() - - expect(dialog).toMatchSnapshot() - }) -}) diff --git a/frontend/app/src/components/StreamlitDialog/DeployErrorDialogs/RepoIsAhead.tsx b/frontend/app/src/components/StreamlitDialog/DeployErrorDialogs/RepoIsAhead.tsx deleted file mode 100644 index e803ba40738f..000000000000 --- a/frontend/app/src/components/StreamlitDialog/DeployErrorDialogs/RepoIsAhead.tsx +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React from "react" -import { IDeployErrorDialog } from "./types" - -function RepoIsAhead(): IDeployErrorDialog { - return { - title: "Unable to deploy", - body: ( - <> -

- This Git repo has uncommitted changes. You may want to commit them - before continuing. -

- - ), - } -} - -export default RepoIsAhead diff --git a/frontend/app/src/components/StreamlitDialog/DeployErrorDialogs/UncommittedChanges.test.tsx b/frontend/app/src/components/StreamlitDialog/DeployErrorDialogs/UncommittedChanges.test.tsx deleted file mode 100644 index a13d81a9c033..000000000000 --- a/frontend/app/src/components/StreamlitDialog/DeployErrorDialogs/UncommittedChanges.test.tsx +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import UncommittedChanges from "./UncommittedChanges" - -describe("DeployErrorDialog - RepoIsAhead", () => { - it("should render without crashing", () => { - const dialog = UncommittedChanges() - - expect(dialog).toMatchSnapshot() - }) -}) diff --git a/frontend/app/src/components/StreamlitDialog/DeployErrorDialogs/UncommittedChanges.tsx b/frontend/app/src/components/StreamlitDialog/DeployErrorDialogs/UncommittedChanges.tsx deleted file mode 100644 index e25461f3379d..000000000000 --- a/frontend/app/src/components/StreamlitDialog/DeployErrorDialogs/UncommittedChanges.tsx +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React from "react" -import { IDeployErrorDialog } from "./types" -import { StyledParagraph } from "./styled-components" - -function UncommittedChanges(): IDeployErrorDialog { - return { - title: "Unsynced changes", - body: ( - - The Git repo has uncommitted changes. You may want to commit them - before continuing. - - ), - } -} - -export default UncommittedChanges diff --git a/frontend/app/src/components/StreamlitDialog/DeployErrorDialogs/UntrackedFiles.test.tsx b/frontend/app/src/components/StreamlitDialog/DeployErrorDialogs/UntrackedFiles.test.tsx deleted file mode 100644 index 4ceb37075e98..000000000000 --- a/frontend/app/src/components/StreamlitDialog/DeployErrorDialogs/UntrackedFiles.test.tsx +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import UntrackedFiles from "./UntrackedFiles" - -describe("DeployErrorDialog - UntrackedFiles", () => { - it("should render without crashing", () => { - const dialog = UntrackedFiles() - - expect(dialog).toMatchSnapshot() - }) -}) diff --git a/frontend/app/src/components/StreamlitDialog/DeployErrorDialogs/UntrackedFiles.tsx b/frontend/app/src/components/StreamlitDialog/DeployErrorDialogs/UntrackedFiles.tsx deleted file mode 100644 index aa8f34e533b1..000000000000 --- a/frontend/app/src/components/StreamlitDialog/DeployErrorDialogs/UntrackedFiles.tsx +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React from "react" -import { IDeployErrorDialog } from "./types" -import { StyledParagraph } from "./styled-components" - -function UntrackedFiles(): IDeployErrorDialog { - return { - title: "Unsynced changes", - body: ( - - Some code changes are not pushed to GitHub. You can continue but the - deployed app might look different than your local app. - - ), - } -} - -export default UntrackedFiles diff --git a/frontend/app/src/components/StreamlitDialog/DeployErrorDialogs/__snapshots__/RepoIsAhead.test.tsx.snap b/frontend/app/src/components/StreamlitDialog/DeployErrorDialogs/__snapshots__/RepoIsAhead.test.tsx.snap deleted file mode 100644 index 6c5fa5f7f850..000000000000 --- a/frontend/app/src/components/StreamlitDialog/DeployErrorDialogs/__snapshots__/RepoIsAhead.test.tsx.snap +++ /dev/null @@ -1,12 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`DeployErrorDialog - RepoIsAhead should render without crashing 1`] = ` -Object { - "body": -

- This Git repo has uncommitted changes. You may want to commit them before continuing. -

-
, - "title": "Unable to deploy", -} -`; diff --git a/frontend/app/src/components/StreamlitDialog/DeployErrorDialogs/__snapshots__/UncommittedChanges.test.tsx.snap b/frontend/app/src/components/StreamlitDialog/DeployErrorDialogs/__snapshots__/UncommittedChanges.test.tsx.snap deleted file mode 100644 index bb8bdcf4e4c6..000000000000 --- a/frontend/app/src/components/StreamlitDialog/DeployErrorDialogs/__snapshots__/UncommittedChanges.test.tsx.snap +++ /dev/null @@ -1,10 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`DeployErrorDialog - RepoIsAhead should render without crashing 1`] = ` -Object { - "body": - The Git repo has uncommitted changes. You may want to commit them before continuing. - , - "title": "Unsynced changes", -} -`; diff --git a/frontend/app/src/components/StreamlitDialog/DeployErrorDialogs/__snapshots__/UntrackedFiles.test.tsx.snap b/frontend/app/src/components/StreamlitDialog/DeployErrorDialogs/__snapshots__/UntrackedFiles.test.tsx.snap deleted file mode 100644 index cd16fd6251f7..000000000000 --- a/frontend/app/src/components/StreamlitDialog/DeployErrorDialogs/__snapshots__/UntrackedFiles.test.tsx.snap +++ /dev/null @@ -1,10 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`DeployErrorDialog - UntrackedFiles should render without crashing 1`] = ` -Object { - "body": - Some code changes are not pushed to GitHub. You can continue but the deployed app might look different than your local app. - , - "title": "Unsynced changes", -} -`; diff --git a/frontend/app/src/components/StreamlitDialog/DeployErrorDialogs/index.ts b/frontend/app/src/components/StreamlitDialog/DeployErrorDialogs/index.ts index b20d85d7a66f..84f1b25e8904 100644 --- a/frontend/app/src/components/StreamlitDialog/DeployErrorDialogs/index.ts +++ b/frontend/app/src/components/StreamlitDialog/DeployErrorDialogs/index.ts @@ -14,9 +14,6 @@ * limitations under the License. */ -export { default as RepoIsAhead } from "./RepoIsAhead" export { default as DetachedHead } from "./DetachedHead" -export { default as UntrackedFiles } from "./UntrackedFiles" export { default as ModuleIsNotAdded } from "./ModuleIsNotAdded" -export { default as UncommittedChanges } from "./UncommittedChanges" export { default as NoRepositoryDetected } from "./NoRepositoryDetected" diff --git a/frontend/app/src/components/StreamlitDialog/__snapshots__/StreamlitDialog.test.tsx.snap b/frontend/app/src/components/StreamlitDialog/__snapshots__/StreamlitDialog.test.tsx.snap index 36cbb560f458..4979c9ef8c1b 100644 --- a/frontend/app/src/components/StreamlitDialog/__snapshots__/StreamlitDialog.test.tsx.snap +++ b/frontend/app/src/components/StreamlitDialog/__snapshots__/StreamlitDialog.test.tsx.snap @@ -3,6 +3,7 @@ exports[`StreamlitDialog renders secondary dialog buttons properly 1`] = ` - .css-2v1jym-StyledBaseButton-StyledTertiaryButton{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;font-weight:400;padding:0.375rem 0.75rem;border-radius:0.5rem;min-height:38.4px;margin:0;line-height:1.6;color:inherit;width:auto;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;}/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0eWxlZC1jb21wb25lbnRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQW1Kb0MiLCJmaWxlIjoic3R5bGVkLWNvbXBvbmVudHMudHMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENvcHlyaWdodCAoYykgU3RyZWFtbGl0IEluYy4gKDIwMTgtMjAyMikgU25vd2ZsYWtlIEluYy4gKDIwMjIpXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IE1vdXNlRXZlbnQsIFJlYWN0Tm9kZSB9IGZyb20gXCJyZWFjdFwiXG5pbXBvcnQgc3R5bGVkLCB7IENTU09iamVjdCB9IGZyb20gXCJAZW1vdGlvbi9zdHlsZWRcIlxuaW1wb3J0IHsgZGFya2VuLCB0cmFuc3BhcmVudGl6ZSB9IGZyb20gXCJjb2xvcjJrXCJcbmltcG9ydCB7IEVtb3Rpb25UaGVtZSB9IGZyb20gXCJAc3RyZWFtbGl0L2xpYi9zcmMvdGhlbWVcIlxuXG5leHBvcnQgZW51bSBCYXNlQnV0dG9uS2luZCB7XG4gIFBSSU1BUlkgPSBcInByaW1hcnlcIixcbiAgU0VDT05EQVJZID0gXCJzZWNvbmRhcnlcIixcbiAgVEVSVElBUlkgPSBcInRlcnRpYXJ5XCIsXG4gIExJTksgPSBcImxpbmtcIixcbiAgSUNPTiA9IFwiaWNvblwiLFxuICBCT1JERVJMRVNTX0lDT04gPSBcImJvcmRlcmxlc3NJY29uXCIsXG4gIE1JTklNQUwgPSBcIm1pbmltYWxcIixcbiAgUFJJTUFSWV9GT1JNX1NVQk1JVCA9IFwicHJpbWFyeUZvcm1TdWJtaXRcIixcbiAgU0VDT05EQVJZX0ZPUk1fU1VCTUlUID0gXCJzZWNvbmRhcnlGb3JtU3VibWl0XCIsXG4gIEhFQURFUl9CVVRUT04gPSBcImhlYWRlclwiLFxuICBIRUFERVJfTk9fUEFERElORyA9IFwiaGVhZGVyTm9QYWRkaW5nXCIsXG59XG5cbmV4cG9ydCBlbnVtIEJhc2VCdXR0b25TaXplIHtcbiAgWFNNQUxMID0gXCJ4c21hbGxcIixcbiAgU01BTEwgPSBcInNtYWxsXCIsXG4gIE1FRElVTSA9IFwibWVkaXVtXCIsXG4gIExBUkdFID0gXCJsYXJnZVwiLFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJhc2VCdXR0b25Qcm9wcyB7XG4gIGtpbmQ6IEJhc2VCdXR0b25LaW5kXG4gIHNpemU/OiBCYXNlQnV0dG9uU2l6ZVxuICBvbkNsaWNrPzogKGV2ZW50OiBNb3VzZUV2ZW50PEhUTUxCdXR0b25FbGVtZW50PikgPT4gYW55XG4gIGRpc2FibGVkPzogYm9vbGVhblxuICBmbHVpZFdpZHRoPzogYm9vbGVhblxuICBjaGlsZHJlbjogUmVhY3ROb2RlXG4gIGF1dG9Gb2N1cz86IGJvb2xlYW5cbn1cblxudHlwZSBSZXF1aXJlZEJhc2VCdXR0b25Qcm9wcyA9IFJlcXVpcmVkPEJhc2VCdXR0b25Qcm9wcz5cblxuZnVuY3Rpb24gZ2V0U2l6ZVN0eWxlKHNpemU6IEJhc2VCdXR0b25TaXplLCB0aGVtZTogRW1vdGlvblRoZW1lKTogQ1NTT2JqZWN0IHtcbiAgc3dpdGNoIChzaXplKSB7XG4gICAgY2FzZSBCYXNlQnV0dG9uU2l6ZS5YU01BTEw6XG4gICAgICByZXR1cm4ge1xuICAgICAgICBwYWRkaW5nOiBgJHt0aGVtZS5zcGFjaW5nLnR3b1hTfSAke3RoZW1lLnNwYWNpbmcuc219YCxcbiAgICAgICAgZm9udFNpemU6IHRoZW1lLmZvbnRTaXplcy5zbSxcbiAgICAgIH1cbiAgICBjYXNlIEJhc2VCdXR0b25TaXplLlNNQUxMOlxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcGFkZGluZzogYCR7dGhlbWUuc3BhY2luZy50d29YU30gJHt0aGVtZS5zcGFjaW5nLm1kfWAsXG4gICAgICB9XG4gICAgY2FzZSBCYXNlQnV0dG9uU2l6ZS5MQVJHRTpcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHBhZGRpbmc6IGAke3RoZW1lLnNwYWNpbmcubWR9ICR7dGhlbWUuc3BhY2luZy5tZH1gLFxuICAgICAgfVxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4ge1xuICAgICAgICBwYWRkaW5nOiBgJHt0aGVtZS5zcGFjaW5nLnhzfSAke3RoZW1lLnNwYWNpbmcubWR9YCxcbiAgICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3QgU3R5bGVkQmFzZUJ1dHRvbiA9IHN0eWxlZC5idXR0b248UmVxdWlyZWRCYXNlQnV0dG9uUHJvcHM+KFxuICAoeyBmbHVpZFdpZHRoLCBzaXplLCB0aGVtZSB9KSA9PiAoe1xuICAgIGRpc3BsYXk6IFwiaW5saW5lLWZsZXhcIixcbiAgICBhbGlnbkl0ZW1zOiBcImNlbnRlclwiLFxuICAgIGp1c3RpZnlDb250ZW50OiBcImNlbnRlclwiLFxuICAgIGZvbnRXZWlnaHQ6IHRoZW1lLmZvbnRXZWlnaHRzLm5vcm1hbCxcbiAgICBwYWRkaW5nOiBgJHt0aGVtZS5zcGFjaW5nLnhzfSAke3RoZW1lLnNwYWNpbmcubWR9YCxcbiAgICBib3JkZXJSYWRpdXM6IHRoZW1lLnJhZGlpLmxnLFxuICAgIG1pbkhlaWdodDogXCIzOC40cHhcIixcbiAgICBtYXJnaW46IDAsXG4gICAgbGluZUhlaWdodDogdGhlbWUubGluZUhlaWdodHMuYmFzZSxcbiAgICBjb2xvcjogXCJpbmhlcml0XCIsXG4gICAgd2lkdGg6IGZsdWlkV2lkdGggPyBcIjEwMCVcIiA6IFwiYXV0b1wiLFxuICAgIHVzZXJTZWxlY3Q6IFwibm9uZVwiLFxuICAgIFwiJjpmb2N1c1wiOiB7XG4gICAgICBvdXRsaW5lOiBcIm5vbmVcIixcbiAgICB9LFxuICAgIFwiJjpmb2N1cy12aXNpYmxlXCI6IHtcbiAgICAgIGJveFNoYWRvdzogYDAgMCAwIDAuMnJlbSAke3RyYW5zcGFyZW50aXplKHRoZW1lLmNvbG9ycy5wcmltYXJ5LCAwLjUpfWAsXG4gICAgfSxcbiAgICAuLi5nZXRTaXplU3R5bGUoc2l6ZSwgdGhlbWUpLFxuICB9KVxuKVxuXG5leHBvcnQgY29uc3QgU3R5bGVkUHJpbWFyeUJ1dHRvbiA9IHN0eWxlZChcbiAgU3R5bGVkQmFzZUJ1dHRvblxuKTxSZXF1aXJlZEJhc2VCdXR0b25Qcm9wcz4oKHsgdGhlbWUgfSkgPT4gKHtcbiAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgY29sb3I6IHRoZW1lLmNvbG9ycy53aGl0ZSxcbiAgYm9yZGVyOiBgMXB4IHNvbGlkICR7dGhlbWUuY29sb3JzLnByaW1hcnl9YCxcbiAgXCImOmhvdmVyXCI6IHtcbiAgICBiYWNrZ3JvdW5kQ29sb3I6IGRhcmtlbih0aGVtZS5jb2xvcnMucHJpbWFyeSwgMC4wNSksXG4gIH0sXG4gIFwiJjphY3RpdmVcIjoge1xuICAgIGJhY2tncm91bmRDb2xvcjogXCJ0cmFuc3BhcmVudFwiLFxuICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgfSxcbiAgXCImOmRpc2FibGVkLCAmOmRpc2FibGVkOmhvdmVyLCAmOmRpc2FibGVkOmFjdGl2ZVwiOiB7XG4gICAgYm9yZGVyQ29sb3I6IHRoZW1lLmNvbG9ycy5mYWRlZFRleHQxMCxcbiAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoZW1lLmNvbG9ycy50cmFuc3BhcmVudCxcbiAgICBjb2xvcjogdGhlbWUuY29sb3JzLmZhZGVkVGV4dDQwLFxuICAgIGN1cnNvcjogXCJub3QtYWxsb3dlZFwiLFxuICB9LFxufSkpXG5cbmV4cG9ydCBjb25zdCBTdHlsZWRTZWNvbmRhcnlCdXR0b24gPSBzdHlsZWQoXG4gIFN0eWxlZEJhc2VCdXR0b25cbik8UmVxdWlyZWRCYXNlQnV0dG9uUHJvcHM+KCh7IHRoZW1lIH0pID0+ICh7XG4gIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLmxpZ2h0ZW5lZEJnMDUsXG4gIGJvcmRlcjogYDFweCBzb2xpZCAke3RoZW1lLmNvbG9ycy5mYWRlZFRleHQxMH1gLFxuICBcIiY6aG92ZXJcIjoge1xuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICBjb2xvcjogdGhlbWUuY29sb3JzLnByaW1hcnksXG4gIH0sXG4gIFwiJjphY3RpdmVcIjoge1xuICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMud2hpdGUsXG4gICAgYm9yZGVyQ29sb3I6IHRoZW1lLmNvbG9ycy5wcmltYXJ5LFxuICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnByaW1hcnksXG4gIH0sXG4gIFwiJjpmb2N1czpub3QoOmFjdGl2ZSlcIjoge1xuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICBjb2xvcjogdGhlbWUuY29sb3JzLnByaW1hcnksXG4gIH0sXG4gIFwiJjpkaXNhYmxlZCwgJjpkaXNhYmxlZDpob3ZlciwgJjpkaXNhYmxlZDphY3RpdmVcIjoge1xuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMuZmFkZWRUZXh0MTAsXG4gICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gICAgY29sb3I6IHRoZW1lLmNvbG9ycy5mYWRlZFRleHQ0MCxcbiAgICBjdXJzb3I6IFwibm90LWFsbG93ZWRcIixcbiAgfSxcbn0pKVxuXG5leHBvcnQgY29uc3QgU3R5bGVkVGVydGlhcnlCdXR0b24gPSBzdHlsZWQoXG4gIFN0eWxlZEJhc2VCdXR0b25cbik8UmVxdWlyZWRCYXNlQnV0dG9uUHJvcHM+KCh7IHRoZW1lIH0pID0+ICh7XG4gIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICBib3JkZXI6IGAxcHggc29saWQgJHt0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnR9YCxcbiAgXCImOmhvdmVyXCI6IHtcbiAgICBib3JkZXJDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgfSxcbiAgXCImOmFjdGl2ZVwiOiB7XG4gICAgY29sb3I6IHRoZW1lLmNvbG9ycy5wcmltYXJ5LFxuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gIH0sXG4gIFwiJjpmb2N1czpub3QoOmFjdGl2ZSlcIjoge1xuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gICAgY29sb3I6IHRoZW1lLmNvbG9ycy5wcmltYXJ5LFxuICB9LFxuICBcIiY6ZGlzYWJsZWQsICY6ZGlzYWJsZWQ6aG92ZXIsICY6ZGlzYWJsZWQ6YWN0aXZlXCI6IHtcbiAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoZW1lLmNvbG9ycy5saWdodEdyYXksXG4gICAgYm9yZGVyQ29sb3I6IHRoZW1lLmNvbG9ycy50cmFuc3BhcmVudCxcbiAgICBjb2xvcjogdGhlbWUuY29sb3JzLmdyYXksXG4gIH0sXG59KSlcblxuZXhwb3J0IGNvbnN0IFN0eWxlZExpbmtCdXR0b24gPSBzdHlsZWQoXG4gIFN0eWxlZEJhc2VCdXR0b25cbik8UmVxdWlyZWRCYXNlQnV0dG9uUHJvcHM+KCh7IHRoZW1lIH0pID0+ICh7XG4gIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICBwYWRkaW5nOiAwLFxuICBib3JkZXI6IFwibm9uZVwiLFxuICBjb2xvcjogdGhlbWUuY29sb3JzLnByaW1hcnksXG4gIFwiJjpob3ZlclwiOiB7XG4gICAgdGV4dERlY29yYXRpb246IFwidW5kZXJsaW5lXCIsXG4gIH0sXG4gIFwiJjphY3RpdmVcIjoge1xuICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICB0ZXh0RGVjb3JhdGlvbjogXCJ1bmRlcmxpbmVcIixcbiAgfSxcbiAgXCImOmRpc2FibGVkLCAmOmRpc2FibGVkOmhvdmVyLCAmOmRpc2FibGVkOmFjdGl2ZVwiOiB7XG4gICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMubGlnaHRHcmF5LFxuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gICAgY29sb3I6IHRoZW1lLmNvbG9ycy5ncmF5LFxuICB9LFxufSkpXG5cbmV4cG9ydCBjb25zdCBTdHlsZWRNaW5pbWFsQnV0dG9uID0gc3R5bGVkKFxuICBTdHlsZWRCYXNlQnV0dG9uXG4pPFJlcXVpcmVkQmFzZUJ1dHRvblByb3BzPigoeyB0aGVtZSB9KSA9PiAoe1xuICBiYWNrZ3JvdW5kQ29sb3I6IHRoZW1lLmNvbG9ycy50cmFuc3BhcmVudCxcbiAgYm9yZGVyOiBcIm5vbmVcIixcbiAgYm94U2hhZG93OiBcIm5vbmVcIixcbiAgcGFkZGluZzogMCxcbiAgXCImOmhvdmVyLCAmOmFjdGl2ZSwgJjpmb2N1cy12aXNpYmxlXCI6IHtcbiAgICBjb2xvcjogdGhlbWUuY29sb3JzLnByaW1hcnksXG4gIH0sXG59KSlcblxuZXhwb3J0IGNvbnN0IFN0eWxlZFByaW1hcnlGb3JtU3VibWl0QnV0dG9uID1cbiAgc3R5bGVkKFN0eWxlZFByaW1hcnlCdXR0b24pPFJlcXVpcmVkQmFzZUJ1dHRvblByb3BzPigpXG5cbmV4cG9ydCBjb25zdCBTdHlsZWRTZWNvbmRhcnlGb3JtU3VibWl0QnV0dG9uID0gc3R5bGVkKFxuICBTdHlsZWRTZWNvbmRhcnlCdXR0b25cbik8UmVxdWlyZWRCYXNlQnV0dG9uUHJvcHM+KClcblxuZXhwb3J0IGNvbnN0IFN0eWxlZEljb25CdXR0b24gPSBzdHlsZWQoXG4gIFN0eWxlZEJhc2VCdXR0b25cbik8UmVxdWlyZWRCYXNlQnV0dG9uUHJvcHM+KCh7IHNpemUsIHRoZW1lIH0pID0+IHtcbiAgY29uc3QgaWNvblBhZGRpbmc6IFJlY29yZDxCYXNlQnV0dG9uU2l6ZSwgc3RyaW5nPiA9IHtcbiAgICBbQmFzZUJ1dHRvblNpemUuWFNNQUxMXTogdGhlbWUuc3BhY2luZy50aHJlZVhTLFxuICAgIFtCYXNlQnV0dG9uU2l6ZS5TTUFMTF06IHRoZW1lLnNwYWNpbmcudHdvWFMsXG4gICAgW0Jhc2VCdXR0b25TaXplLk1FRElVTV06IHRoZW1lLnNwYWNpbmcubWQsXG4gICAgW0Jhc2VCdXR0b25TaXplLkxBUkdFXTogdGhlbWUuc3BhY2luZy5sZyxcbiAgfVxuICByZXR1cm4ge1xuICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICAgIGJvcmRlcjogYDFweCBzb2xpZCAke3RoZW1lLmNvbG9ycy50cmFuc3BhcmVudH1gLFxuICAgIHBhZGRpbmc6IGljb25QYWRkaW5nW3NpemVdLFxuXG4gICAgXCImOmhvdmVyXCI6IHtcbiAgICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICB9LFxuICAgIFwiJjphY3RpdmVcIjoge1xuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMud2hpdGUsXG4gICAgfSxcbiAgICBcIiY6bm90KDphY3RpdmUpXCI6IHtcbiAgICAgIGJveFNoYWRvdzogXCJub25lXCIsXG4gICAgfSxcbiAgICBcIiY6ZGlzYWJsZWQsICY6ZGlzYWJsZWQ6aG92ZXIsICY6ZGlzYWJsZWQ6YWN0aXZlXCI6IHtcbiAgICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLmxpZ2h0R3JheSxcbiAgICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gICAgICBjb2xvcjogdGhlbWUuY29sb3JzLmdyYXksXG4gICAgfSxcbiAgfVxufSlcblxuZXhwb3J0IGNvbnN0IFN0eWxlZEhlYWRlckJ1dHRvbiA9IHN0eWxlZChcbiAgU3R5bGVkQmFzZUJ1dHRvblxuKTxSZXF1aXJlZEJhc2VCdXR0b25Qcm9wcz4oKHsgdGhlbWUgfSkgPT4ge1xuICByZXR1cm4ge1xuICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICAgIGJvcmRlcjogXCJub25lXCIsXG4gICAgcGFkZGluZzogdGhlbWUuc3BhY2luZy5zbSxcbiAgICBmb250U2l6ZTogdGhlbWUuZm9udFNpemVzLnNtLFxuICAgIG1hcmdpbkxlZnQ6IHRoZW1lLnNwYWNpbmcudGhyZWVYUyxcbiAgICBtYXJnaW5SaWdodDogdGhlbWUuc3BhY2luZy50aHJlZVhTLFxuICAgIGxpbmVIZWlnaHQ6IDEsXG5cbiAgICAvLyBPdmVycmlkZSBidXR0b25zIG1pbiB3aWR0aCBhbmQgaGVpZ2h0LCB0byBlbnN1cmUgdGhlIGhvdmVyIHN0YXRlIGZvciBpY29uIGJ1dHRvbnMgb24gdGhlIGhlYWRlciBpcyBzcXVhcmVcbiAgICBtaW5XaWR0aDogdGhlbWUuc3BhY2luZy50aHJlZVhMLFxuICAgIG1pbkhlaWdodDogdGhlbWUuc3BhY2luZy50aHJlZVhMLFxuXG4gICAgXCImOmZvY3VzXCI6IHtcbiAgICAgIG91dGxpbmU6IFwibm9uZVwiLFxuICAgIH0sXG4gICAgXCImOmZvY3VzLXZpc2libGVcIjoge1xuICAgICAgYm94U2hhZG93OiBgMCAwIDAgMC4ycmVtICR7dHJhbnNwYXJlbnRpemUodGhlbWUuY29sb3JzLmdyYXk5MCwgMC44KX1gLFxuICAgIH0sXG4gICAgXCImOmhvdmVyXCI6IHtcbiAgICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLmRhcmtlbmVkQmdNaXgyNSxcbiAgICB9LFxuICAgIFwiJjpkaXNhYmxlZCwgJjpkaXNhYmxlZDpob3ZlciwgJjpkaXNhYmxlZDphY3RpdmVcIjoge1xuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMubGlnaHRHcmF5LFxuICAgICAgYm9yZGVyQ29sb3I6IHRoZW1lLmNvbG9ycy50cmFuc3BhcmVudCxcbiAgICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMuZ3JheSxcbiAgICB9LFxuICB9XG59KVxuXG4vLyBUYWtlIG91dCBwYWRkaW5nIGZvciB0aGlzIHNwZWNpZmljIGJ1dHRvbiwgc28gd2UgY2FuIGVuc3VyZSBpdCdzIDMyeDMycHggbGlrZSBvdGhlciBidXR0b25zIGluIENvbW11bml0eSBDbG91ZFxuZXhwb3J0IGNvbnN0IFN0eWxlZEhlYWRlck5vUGFkZGluZ0J1dHRvbiA9IHN0eWxlZChcbiAgU3R5bGVkSGVhZGVyQnV0dG9uXG4pPFJlcXVpcmVkQmFzZUJ1dHRvblByb3BzPigoKSA9PiB7XG4gIHJldHVybiB7XG4gICAgcGFkZGluZzogMCxcbiAgfVxufSlcblxuZXhwb3J0IGNvbnN0IFN0eWxlZEJvcmRlcmxlc3NJY29uQnV0dG9uID0gc3R5bGVkKFxuICBTdHlsZWRCYXNlQnV0dG9uXG4pPFJlcXVpcmVkQmFzZUJ1dHRvblByb3BzPigoeyBzaXplLCB0aGVtZSB9KSA9PiB7XG4gIGNvbnN0IGljb25QYWRkaW5nOiBSZWNvcmQ8QmFzZUJ1dHRvblNpemUsIHN0cmluZz4gPSB7XG4gICAgW0Jhc2VCdXR0b25TaXplLlhTTUFMTF06IHRoZW1lLnNwYWNpbmcudGhyZWVYUyxcbiAgICBbQmFzZUJ1dHRvblNpemUuU01BTExdOiB0aGVtZS5zcGFjaW5nLnR3b1hTLFxuICAgIFtCYXNlQnV0dG9uU2l6ZS5NRURJVU1dOiB0aGVtZS5zcGFjaW5nLm1kLFxuICAgIFtCYXNlQnV0dG9uU2l6ZS5MQVJHRV06IHRoZW1lLnNwYWNpbmcubGcsXG4gIH1cblxuICByZXR1cm4ge1xuICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICAgIGJvcmRlcjogYDFweCBzb2xpZCAke3RoZW1lLmNvbG9ycy50cmFuc3BhcmVudH1gLFxuICAgIHBhZGRpbmc6IGljb25QYWRkaW5nW3NpemVdLFxuXG4gICAgXCImOmZvY3VzXCI6IHtcbiAgICAgIGJveFNoYWRvdzogXCJub25lXCIsXG4gICAgICBvdXRsaW5lOiBcIm5vbmVcIixcbiAgICB9LFxuICAgIFwiJjpkaXNhYmxlZCwgJjpkaXNhYmxlZDpob3ZlciwgJjpkaXNhYmxlZDphY3RpdmVcIjoge1xuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMubGlnaHRHcmF5LFxuICAgICAgYm9yZGVyQ29sb3I6IHRoZW1lLmNvbG9ycy50cmFuc3BhcmVudCxcbiAgICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMuZ3JheSxcbiAgICB9LFxuICB9XG59KVxuXG5leHBvcnQgY29uc3QgU3R5bGVkVG9vbHRpcE5vcm1hbCA9IHN0eWxlZC5kaXYoKHsgdGhlbWUgfSkgPT4gKHtcbiAgZGlzcGxheTogXCJibG9ja1wiLFxuICBbYEBtZWRpYSAobWF4LXdpZHRoOiAke3RoZW1lLmJyZWFrcG9pbnRzLnNtfSlgXToge1xuICAgIGRpc3BsYXk6IFwibm9uZVwiLFxuICB9LFxufSkpXG5cbmV4cG9ydCBjb25zdCBTdHlsZWRUb29sdGlwTW9iaWxlID0gc3R5bGVkLmRpdigoeyB0aGVtZSB9KSA9PiAoe1xuICBkaXNwbGF5OiBcIm5vbmVcIixcbiAgW2BAbWVkaWEgKG1heC13aWR0aDogJHt0aGVtZS5icmVha3BvaW50cy5zbX0pYF06IHtcbiAgICBkaXNwbGF5OiBcImJsb2NrXCIsXG4gIH0sXG59KSlcbiJdfQ== */ + .css-2v1jym-StyledBaseButton-StyledTertiaryButton{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;font-weight:400;padding:0.375rem 0.75rem;border-radius:0.5rem;min-height:38.4px;margin:0;line-height:1.6;color:inherit;width:auto;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;}/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0eWxlZC1jb21wb25lbnRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQXlKb0MiLCJmaWxlIjoic3R5bGVkLWNvbXBvbmVudHMudHMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENvcHlyaWdodCAoYykgU3RyZWFtbGl0IEluYy4gKDIwMTgtMjAyMikgU25vd2ZsYWtlIEluYy4gKDIwMjIpXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IE1vdXNlRXZlbnQsIFJlYWN0Tm9kZSB9IGZyb20gXCJyZWFjdFwiXG5pbXBvcnQgc3R5bGVkLCB7IENTU09iamVjdCB9IGZyb20gXCJAZW1vdGlvbi9zdHlsZWRcIlxuaW1wb3J0IHsgZGFya2VuLCB0cmFuc3BhcmVudGl6ZSB9IGZyb20gXCJjb2xvcjJrXCJcbmltcG9ydCB7IEVtb3Rpb25UaGVtZSB9IGZyb20gXCJAc3RyZWFtbGl0L2xpYi9zcmMvdGhlbWVcIlxuXG5leHBvcnQgZW51bSBCYXNlQnV0dG9uS2luZCB7XG4gIFBSSU1BUlkgPSBcInByaW1hcnlcIixcbiAgU0VDT05EQVJZID0gXCJzZWNvbmRhcnlcIixcbiAgVEVSVElBUlkgPSBcInRlcnRpYXJ5XCIsXG4gIExJTksgPSBcImxpbmtcIixcbiAgSUNPTiA9IFwiaWNvblwiLFxuICBCT1JERVJMRVNTX0lDT04gPSBcImJvcmRlcmxlc3NJY29uXCIsXG4gIE1JTklNQUwgPSBcIm1pbmltYWxcIixcbiAgUFJJTUFSWV9GT1JNX1NVQk1JVCA9IFwicHJpbWFyeUZvcm1TdWJtaXRcIixcbiAgU0VDT05EQVJZX0ZPUk1fU1VCTUlUID0gXCJzZWNvbmRhcnlGb3JtU3VibWl0XCIsXG4gIEhFQURFUl9CVVRUT04gPSBcImhlYWRlclwiLFxuICBIRUFERVJfTk9fUEFERElORyA9IFwiaGVhZGVyTm9QYWRkaW5nXCIsXG59XG5cbmV4cG9ydCBlbnVtIEJhc2VCdXR0b25TaXplIHtcbiAgWFNNQUxMID0gXCJ4c21hbGxcIixcbiAgU01BTEwgPSBcInNtYWxsXCIsXG4gIE1FRElVTSA9IFwibWVkaXVtXCIsXG4gIExBUkdFID0gXCJsYXJnZVwiLFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJhc2VCdXR0b25Qcm9wcyB7XG4gIGtpbmQ6IEJhc2VCdXR0b25LaW5kXG4gIHNpemU/OiBCYXNlQnV0dG9uU2l6ZVxuICBvbkNsaWNrPzogKGV2ZW50OiBNb3VzZUV2ZW50PEhUTUxCdXR0b25FbGVtZW50PikgPT4gYW55XG4gIGRpc2FibGVkPzogYm9vbGVhblxuICAvLyBJZiB0cnVlIG9yIG51bWJlciwgdGhlIGJ1dHRvbiBzaG91bGQgdGFrZSB1cCBjb250YWluZXIncyBmdWxsIHdpZHRoXG4gIGZsdWlkV2lkdGg/OiBib29sZWFuIHwgbnVtYmVyXG4gIGNoaWxkcmVuOiBSZWFjdE5vZGVcbiAgYXV0b0ZvY3VzPzogYm9vbGVhblxufVxuXG50eXBlIFJlcXVpcmVkQmFzZUJ1dHRvblByb3BzID0gUmVxdWlyZWQ8QmFzZUJ1dHRvblByb3BzPlxuXG5mdW5jdGlvbiBnZXRTaXplU3R5bGUoc2l6ZTogQmFzZUJ1dHRvblNpemUsIHRoZW1lOiBFbW90aW9uVGhlbWUpOiBDU1NPYmplY3Qge1xuICBzd2l0Y2ggKHNpemUpIHtcbiAgICBjYXNlIEJhc2VCdXR0b25TaXplLlhTTUFMTDpcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHBhZGRpbmc6IGAke3RoZW1lLnNwYWNpbmcudHdvWFN9ICR7dGhlbWUuc3BhY2luZy5zbX1gLFxuICAgICAgICBmb250U2l6ZTogdGhlbWUuZm9udFNpemVzLnNtLFxuICAgICAgfVxuICAgIGNhc2UgQmFzZUJ1dHRvblNpemUuU01BTEw6XG4gICAgICByZXR1cm4ge1xuICAgICAgICBwYWRkaW5nOiBgJHt0aGVtZS5zcGFjaW5nLnR3b1hTfSAke3RoZW1lLnNwYWNpbmcubWR9YCxcbiAgICAgIH1cbiAgICBjYXNlIEJhc2VCdXR0b25TaXplLkxBUkdFOlxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcGFkZGluZzogYCR7dGhlbWUuc3BhY2luZy5tZH0gJHt0aGVtZS5zcGFjaW5nLm1kfWAsXG4gICAgICB9XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHBhZGRpbmc6IGAke3RoZW1lLnNwYWNpbmcueHN9ICR7dGhlbWUuc3BhY2luZy5tZH1gLFxuICAgICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBTdHlsZWRCYXNlQnV0dG9uID0gc3R5bGVkLmJ1dHRvbjxSZXF1aXJlZEJhc2VCdXR0b25Qcm9wcz4oXG4gICh7IGZsdWlkV2lkdGgsIHNpemUsIHRoZW1lIH0pID0+IHtcbiAgICBjb25zdCBidXR0b25XaWR0aCA9XG4gICAgICB0eXBlb2YgZmx1aWRXaWR0aCA9PSBcIm51bWJlclwiID8gYCR7Zmx1aWRXaWR0aH1weGAgOiBcIjEwMCVcIlxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGRpc3BsYXk6IFwiaW5saW5lLWZsZXhcIixcbiAgICAgIGFsaWduSXRlbXM6IFwiY2VudGVyXCIsXG4gICAgICBqdXN0aWZ5Q29udGVudDogXCJjZW50ZXJcIixcbiAgICAgIGZvbnRXZWlnaHQ6IHRoZW1lLmZvbnRXZWlnaHRzLm5vcm1hbCxcbiAgICAgIHBhZGRpbmc6IGAke3RoZW1lLnNwYWNpbmcueHN9ICR7dGhlbWUuc3BhY2luZy5tZH1gLFxuICAgICAgYm9yZGVyUmFkaXVzOiB0aGVtZS5yYWRpaS5sZyxcbiAgICAgIG1pbkhlaWdodDogXCIzOC40cHhcIixcbiAgICAgIG1hcmdpbjogMCxcbiAgICAgIGxpbmVIZWlnaHQ6IHRoZW1lLmxpbmVIZWlnaHRzLmJhc2UsXG4gICAgICBjb2xvcjogXCJpbmhlcml0XCIsXG4gICAgICB3aWR0aDogZmx1aWRXaWR0aCA/IGJ1dHRvbldpZHRoIDogXCJhdXRvXCIsXG4gICAgICB1c2VyU2VsZWN0OiBcIm5vbmVcIixcbiAgICAgIFwiJjpmb2N1c1wiOiB7XG4gICAgICAgIG91dGxpbmU6IFwibm9uZVwiLFxuICAgICAgfSxcbiAgICAgIFwiJjpmb2N1cy12aXNpYmxlXCI6IHtcbiAgICAgICAgYm94U2hhZG93OiBgMCAwIDAgMC4ycmVtICR7dHJhbnNwYXJlbnRpemUodGhlbWUuY29sb3JzLnByaW1hcnksIDAuNSl9YCxcbiAgICAgIH0sXG4gICAgICAuLi5nZXRTaXplU3R5bGUoc2l6ZSwgdGhlbWUpLFxuICAgIH1cbiAgfVxuKVxuXG5leHBvcnQgY29uc3QgU3R5bGVkUHJpbWFyeUJ1dHRvbiA9IHN0eWxlZChcbiAgU3R5bGVkQmFzZUJ1dHRvblxuKTxSZXF1aXJlZEJhc2VCdXR0b25Qcm9wcz4oKHsgdGhlbWUgfSkgPT4gKHtcbiAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgY29sb3I6IHRoZW1lLmNvbG9ycy53aGl0ZSxcbiAgYm9yZGVyOiBgMXB4IHNvbGlkICR7dGhlbWUuY29sb3JzLnByaW1hcnl9YCxcbiAgXCImOmhvdmVyXCI6IHtcbiAgICBiYWNrZ3JvdW5kQ29sb3I6IGRhcmtlbih0aGVtZS5jb2xvcnMucHJpbWFyeSwgMC4wNSksXG4gIH0sXG4gIFwiJjphY3RpdmVcIjoge1xuICAgIGJhY2tncm91bmRDb2xvcjogXCJ0cmFuc3BhcmVudFwiLFxuICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgfSxcbiAgXCImOmRpc2FibGVkLCAmOmRpc2FibGVkOmhvdmVyLCAmOmRpc2FibGVkOmFjdGl2ZVwiOiB7XG4gICAgYm9yZGVyQ29sb3I6IHRoZW1lLmNvbG9ycy5mYWRlZFRleHQxMCxcbiAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoZW1lLmNvbG9ycy50cmFuc3BhcmVudCxcbiAgICBjb2xvcjogdGhlbWUuY29sb3JzLmZhZGVkVGV4dDQwLFxuICAgIGN1cnNvcjogXCJub3QtYWxsb3dlZFwiLFxuICB9LFxufSkpXG5cbmV4cG9ydCBjb25zdCBTdHlsZWRTZWNvbmRhcnlCdXR0b24gPSBzdHlsZWQoXG4gIFN0eWxlZEJhc2VCdXR0b25cbik8UmVxdWlyZWRCYXNlQnV0dG9uUHJvcHM+KCh7IHRoZW1lIH0pID0+ICh7XG4gIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLmxpZ2h0ZW5lZEJnMDUsXG4gIGJvcmRlcjogYDFweCBzb2xpZCAke3RoZW1lLmNvbG9ycy5mYWRlZFRleHQxMH1gLFxuICBcIiY6aG92ZXJcIjoge1xuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICBjb2xvcjogdGhlbWUuY29sb3JzLnByaW1hcnksXG4gIH0sXG4gIFwiJjphY3RpdmVcIjoge1xuICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMud2hpdGUsXG4gICAgYm9yZGVyQ29sb3I6IHRoZW1lLmNvbG9ycy5wcmltYXJ5LFxuICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnByaW1hcnksXG4gIH0sXG4gIFwiJjpmb2N1czpub3QoOmFjdGl2ZSlcIjoge1xuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICBjb2xvcjogdGhlbWUuY29sb3JzLnByaW1hcnksXG4gIH0sXG4gIFwiJjpkaXNhYmxlZCwgJjpkaXNhYmxlZDpob3ZlciwgJjpkaXNhYmxlZDphY3RpdmVcIjoge1xuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMuZmFkZWRUZXh0MTAsXG4gICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gICAgY29sb3I6IHRoZW1lLmNvbG9ycy5mYWRlZFRleHQ0MCxcbiAgICBjdXJzb3I6IFwibm90LWFsbG93ZWRcIixcbiAgfSxcbn0pKVxuXG5leHBvcnQgY29uc3QgU3R5bGVkVGVydGlhcnlCdXR0b24gPSBzdHlsZWQoXG4gIFN0eWxlZEJhc2VCdXR0b25cbik8UmVxdWlyZWRCYXNlQnV0dG9uUHJvcHM+KCh7IHRoZW1lIH0pID0+ICh7XG4gIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICBib3JkZXI6IGAxcHggc29saWQgJHt0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnR9YCxcbiAgXCImOmhvdmVyXCI6IHtcbiAgICBib3JkZXJDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgfSxcbiAgXCImOmFjdGl2ZVwiOiB7XG4gICAgY29sb3I6IHRoZW1lLmNvbG9ycy5wcmltYXJ5LFxuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gIH0sXG4gIFwiJjpmb2N1czpub3QoOmFjdGl2ZSlcIjoge1xuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gICAgY29sb3I6IHRoZW1lLmNvbG9ycy5wcmltYXJ5LFxuICB9LFxuICBcIiY6ZGlzYWJsZWQsICY6ZGlzYWJsZWQ6aG92ZXIsICY6ZGlzYWJsZWQ6YWN0aXZlXCI6IHtcbiAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoZW1lLmNvbG9ycy5saWdodEdyYXksXG4gICAgYm9yZGVyQ29sb3I6IHRoZW1lLmNvbG9ycy50cmFuc3BhcmVudCxcbiAgICBjb2xvcjogdGhlbWUuY29sb3JzLmdyYXksXG4gIH0sXG59KSlcblxuZXhwb3J0IGNvbnN0IFN0eWxlZExpbmtCdXR0b24gPSBzdHlsZWQoXG4gIFN0eWxlZEJhc2VCdXR0b25cbik8UmVxdWlyZWRCYXNlQnV0dG9uUHJvcHM+KCh7IHRoZW1lIH0pID0+ICh7XG4gIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICBwYWRkaW5nOiAwLFxuICBib3JkZXI6IFwibm9uZVwiLFxuICBjb2xvcjogdGhlbWUuY29sb3JzLnByaW1hcnksXG4gIFwiJjpob3ZlclwiOiB7XG4gICAgdGV4dERlY29yYXRpb246IFwidW5kZXJsaW5lXCIsXG4gIH0sXG4gIFwiJjphY3RpdmVcIjoge1xuICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICB0ZXh0RGVjb3JhdGlvbjogXCJ1bmRlcmxpbmVcIixcbiAgfSxcbiAgXCImOmRpc2FibGVkLCAmOmRpc2FibGVkOmhvdmVyLCAmOmRpc2FibGVkOmFjdGl2ZVwiOiB7XG4gICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMubGlnaHRHcmF5LFxuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gICAgY29sb3I6IHRoZW1lLmNvbG9ycy5ncmF5LFxuICB9LFxufSkpXG5cbmV4cG9ydCBjb25zdCBTdHlsZWRNaW5pbWFsQnV0dG9uID0gc3R5bGVkKFxuICBTdHlsZWRCYXNlQnV0dG9uXG4pPFJlcXVpcmVkQmFzZUJ1dHRvblByb3BzPigoeyB0aGVtZSB9KSA9PiAoe1xuICBiYWNrZ3JvdW5kQ29sb3I6IHRoZW1lLmNvbG9ycy50cmFuc3BhcmVudCxcbiAgYm9yZGVyOiBcIm5vbmVcIixcbiAgYm94U2hhZG93OiBcIm5vbmVcIixcbiAgcGFkZGluZzogMCxcbiAgXCImOmhvdmVyLCAmOmFjdGl2ZSwgJjpmb2N1cy12aXNpYmxlXCI6IHtcbiAgICBjb2xvcjogdGhlbWUuY29sb3JzLnByaW1hcnksXG4gIH0sXG59KSlcblxuZXhwb3J0IGNvbnN0IFN0eWxlZFByaW1hcnlGb3JtU3VibWl0QnV0dG9uID1cbiAgc3R5bGVkKFN0eWxlZFByaW1hcnlCdXR0b24pPFJlcXVpcmVkQmFzZUJ1dHRvblByb3BzPigpXG5cbmV4cG9ydCBjb25zdCBTdHlsZWRTZWNvbmRhcnlGb3JtU3VibWl0QnV0dG9uID0gc3R5bGVkKFxuICBTdHlsZWRTZWNvbmRhcnlCdXR0b25cbik8UmVxdWlyZWRCYXNlQnV0dG9uUHJvcHM+KClcblxuZXhwb3J0IGNvbnN0IFN0eWxlZEljb25CdXR0b24gPSBzdHlsZWQoXG4gIFN0eWxlZEJhc2VCdXR0b25cbik8UmVxdWlyZWRCYXNlQnV0dG9uUHJvcHM+KCh7IHNpemUsIHRoZW1lIH0pID0+IHtcbiAgY29uc3QgaWNvblBhZGRpbmc6IFJlY29yZDxCYXNlQnV0dG9uU2l6ZSwgc3RyaW5nPiA9IHtcbiAgICBbQmFzZUJ1dHRvblNpemUuWFNNQUxMXTogdGhlbWUuc3BhY2luZy50aHJlZVhTLFxuICAgIFtCYXNlQnV0dG9uU2l6ZS5TTUFMTF06IHRoZW1lLnNwYWNpbmcudHdvWFMsXG4gICAgW0Jhc2VCdXR0b25TaXplLk1FRElVTV06IHRoZW1lLnNwYWNpbmcubWQsXG4gICAgW0Jhc2VCdXR0b25TaXplLkxBUkdFXTogdGhlbWUuc3BhY2luZy5sZyxcbiAgfVxuICByZXR1cm4ge1xuICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICAgIGJvcmRlcjogYDFweCBzb2xpZCAke3RoZW1lLmNvbG9ycy50cmFuc3BhcmVudH1gLFxuICAgIHBhZGRpbmc6IGljb25QYWRkaW5nW3NpemVdLFxuXG4gICAgXCImOmhvdmVyXCI6IHtcbiAgICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICB9LFxuICAgIFwiJjphY3RpdmVcIjoge1xuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMud2hpdGUsXG4gICAgfSxcbiAgICBcIiY6bm90KDphY3RpdmUpXCI6IHtcbiAgICAgIGJveFNoYWRvdzogXCJub25lXCIsXG4gICAgfSxcbiAgICBcIiY6ZGlzYWJsZWQsICY6ZGlzYWJsZWQ6aG92ZXIsICY6ZGlzYWJsZWQ6YWN0aXZlXCI6IHtcbiAgICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLmxpZ2h0R3JheSxcbiAgICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gICAgICBjb2xvcjogdGhlbWUuY29sb3JzLmdyYXksXG4gICAgfSxcbiAgfVxufSlcblxuZXhwb3J0IGNvbnN0IFN0eWxlZEhlYWRlckJ1dHRvbiA9IHN0eWxlZChcbiAgU3R5bGVkQmFzZUJ1dHRvblxuKTxSZXF1aXJlZEJhc2VCdXR0b25Qcm9wcz4oKHsgdGhlbWUgfSkgPT4ge1xuICByZXR1cm4ge1xuICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICAgIGJvcmRlcjogXCJub25lXCIsXG4gICAgcGFkZGluZzogdGhlbWUuc3BhY2luZy5zbSxcbiAgICBmb250U2l6ZTogdGhlbWUuZm9udFNpemVzLnNtLFxuICAgIG1hcmdpbkxlZnQ6IHRoZW1lLnNwYWNpbmcudGhyZWVYUyxcbiAgICBtYXJnaW5SaWdodDogdGhlbWUuc3BhY2luZy50aHJlZVhTLFxuICAgIGxpbmVIZWlnaHQ6IDEsXG5cbiAgICAvLyBPdmVycmlkZSBidXR0b25zIG1pbiB3aWR0aCBhbmQgaGVpZ2h0LCB0byBlbnN1cmUgdGhlIGhvdmVyIHN0YXRlIGZvciBpY29uIGJ1dHRvbnMgb24gdGhlIGhlYWRlciBpcyBzcXVhcmVcbiAgICBtaW5XaWR0aDogdGhlbWUuc3BhY2luZy50aHJlZVhMLFxuICAgIG1pbkhlaWdodDogdGhlbWUuc3BhY2luZy50aHJlZVhMLFxuXG4gICAgXCImOmZvY3VzXCI6IHtcbiAgICAgIG91dGxpbmU6IFwibm9uZVwiLFxuICAgIH0sXG4gICAgXCImOmZvY3VzLXZpc2libGVcIjoge1xuICAgICAgYm94U2hhZG93OiBgMCAwIDAgMC4ycmVtICR7dHJhbnNwYXJlbnRpemUodGhlbWUuY29sb3JzLmdyYXk5MCwgMC44KX1gLFxuICAgIH0sXG4gICAgXCImOmhvdmVyXCI6IHtcbiAgICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLmRhcmtlbmVkQmdNaXgyNSxcbiAgICB9LFxuICAgIFwiJjpkaXNhYmxlZCwgJjpkaXNhYmxlZDpob3ZlciwgJjpkaXNhYmxlZDphY3RpdmVcIjoge1xuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMubGlnaHRHcmF5LFxuICAgICAgYm9yZGVyQ29sb3I6IHRoZW1lLmNvbG9ycy50cmFuc3BhcmVudCxcbiAgICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMuZ3JheSxcbiAgICB9LFxuICB9XG59KVxuXG4vLyBUYWtlIG91dCBwYWRkaW5nIGZvciB0aGlzIHNwZWNpZmljIGJ1dHRvbiwgc28gd2UgY2FuIGVuc3VyZSBpdCdzIDMyeDMycHggbGlrZSBvdGhlciBidXR0b25zIGluIENvbW11bml0eSBDbG91ZFxuZXhwb3J0IGNvbnN0IFN0eWxlZEhlYWRlck5vUGFkZGluZ0J1dHRvbiA9IHN0eWxlZChcbiAgU3R5bGVkSGVhZGVyQnV0dG9uXG4pPFJlcXVpcmVkQmFzZUJ1dHRvblByb3BzPigoKSA9PiB7XG4gIHJldHVybiB7XG4gICAgcGFkZGluZzogMCxcbiAgfVxufSlcblxuZXhwb3J0IGNvbnN0IFN0eWxlZEJvcmRlcmxlc3NJY29uQnV0dG9uID0gc3R5bGVkKFxuICBTdHlsZWRCYXNlQnV0dG9uXG4pPFJlcXVpcmVkQmFzZUJ1dHRvblByb3BzPigoeyBzaXplLCB0aGVtZSB9KSA9PiB7XG4gIGNvbnN0IGljb25QYWRkaW5nOiBSZWNvcmQ8QmFzZUJ1dHRvblNpemUsIHN0cmluZz4gPSB7XG4gICAgW0Jhc2VCdXR0b25TaXplLlhTTUFMTF06IHRoZW1lLnNwYWNpbmcudGhyZWVYUyxcbiAgICBbQmFzZUJ1dHRvblNpemUuU01BTExdOiB0aGVtZS5zcGFjaW5nLnR3b1hTLFxuICAgIFtCYXNlQnV0dG9uU2l6ZS5NRURJVU1dOiB0aGVtZS5zcGFjaW5nLm1kLFxuICAgIFtCYXNlQnV0dG9uU2l6ZS5MQVJHRV06IHRoZW1lLnNwYWNpbmcubGcsXG4gIH1cblxuICByZXR1cm4ge1xuICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICAgIGJvcmRlcjogYDFweCBzb2xpZCAke3RoZW1lLmNvbG9ycy50cmFuc3BhcmVudH1gLFxuICAgIHBhZGRpbmc6IGljb25QYWRkaW5nW3NpemVdLFxuXG4gICAgXCImOmZvY3VzXCI6IHtcbiAgICAgIGJveFNoYWRvdzogXCJub25lXCIsXG4gICAgICBvdXRsaW5lOiBcIm5vbmVcIixcbiAgICB9LFxuICAgIFwiJjpkaXNhYmxlZCwgJjpkaXNhYmxlZDpob3ZlciwgJjpkaXNhYmxlZDphY3RpdmVcIjoge1xuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMubGlnaHRHcmF5LFxuICAgICAgYm9yZGVyQ29sb3I6IHRoZW1lLmNvbG9ycy50cmFuc3BhcmVudCxcbiAgICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMuZ3JheSxcbiAgICB9LFxuICB9XG59KVxuXG5leHBvcnQgY29uc3QgU3R5bGVkVG9vbHRpcE5vcm1hbCA9IHN0eWxlZC5kaXYoKHsgdGhlbWUgfSkgPT4gKHtcbiAgZGlzcGxheTogXCJibG9ja1wiLFxuICBbYEBtZWRpYSAobWF4LXdpZHRoOiAke3RoZW1lLmJyZWFrcG9pbnRzLnNtfSlgXToge1xuICAgIGRpc3BsYXk6IFwibm9uZVwiLFxuICB9LFxufSkpXG5cbmV4cG9ydCBjb25zdCBTdHlsZWRUb29sdGlwTW9iaWxlID0gc3R5bGVkLmRpdigoeyB0aGVtZSB9KSA9PiAoe1xuICBkaXNwbGF5OiBcIm5vbmVcIixcbiAgW2BAbWVkaWEgKG1heC13aWR0aDogJHt0aGVtZS5icmVha3BvaW50cy5zbX0pYF06IHtcbiAgICBkaXNwbGF5OiBcImJsb2NrXCIsXG4gIH0sXG59KSlcbiJdfQ== */ , "ctr": 15, @@ -151,98 +152,98 @@ exports[`StreamlitDialog renders secondary dialog buttons properly 1`] = ` data-s="" > - .css-2v1jym-StyledBaseButton-StyledTertiaryButton{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;font-weight:400;padding:0.375rem 0.75rem;border-radius:0.5rem;min-height:38.4px;margin:0;line-height:1.6;color:inherit;width:auto;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;}/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0eWxlZC1jb21wb25lbnRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQW1Kb0MiLCJmaWxlIjoic3R5bGVkLWNvbXBvbmVudHMudHMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENvcHlyaWdodCAoYykgU3RyZWFtbGl0IEluYy4gKDIwMTgtMjAyMikgU25vd2ZsYWtlIEluYy4gKDIwMjIpXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IE1vdXNlRXZlbnQsIFJlYWN0Tm9kZSB9IGZyb20gXCJyZWFjdFwiXG5pbXBvcnQgc3R5bGVkLCB7IENTU09iamVjdCB9IGZyb20gXCJAZW1vdGlvbi9zdHlsZWRcIlxuaW1wb3J0IHsgZGFya2VuLCB0cmFuc3BhcmVudGl6ZSB9IGZyb20gXCJjb2xvcjJrXCJcbmltcG9ydCB7IEVtb3Rpb25UaGVtZSB9IGZyb20gXCJAc3RyZWFtbGl0L2xpYi9zcmMvdGhlbWVcIlxuXG5leHBvcnQgZW51bSBCYXNlQnV0dG9uS2luZCB7XG4gIFBSSU1BUlkgPSBcInByaW1hcnlcIixcbiAgU0VDT05EQVJZID0gXCJzZWNvbmRhcnlcIixcbiAgVEVSVElBUlkgPSBcInRlcnRpYXJ5XCIsXG4gIExJTksgPSBcImxpbmtcIixcbiAgSUNPTiA9IFwiaWNvblwiLFxuICBCT1JERVJMRVNTX0lDT04gPSBcImJvcmRlcmxlc3NJY29uXCIsXG4gIE1JTklNQUwgPSBcIm1pbmltYWxcIixcbiAgUFJJTUFSWV9GT1JNX1NVQk1JVCA9IFwicHJpbWFyeUZvcm1TdWJtaXRcIixcbiAgU0VDT05EQVJZX0ZPUk1fU1VCTUlUID0gXCJzZWNvbmRhcnlGb3JtU3VibWl0XCIsXG4gIEhFQURFUl9CVVRUT04gPSBcImhlYWRlclwiLFxuICBIRUFERVJfTk9fUEFERElORyA9IFwiaGVhZGVyTm9QYWRkaW5nXCIsXG59XG5cbmV4cG9ydCBlbnVtIEJhc2VCdXR0b25TaXplIHtcbiAgWFNNQUxMID0gXCJ4c21hbGxcIixcbiAgU01BTEwgPSBcInNtYWxsXCIsXG4gIE1FRElVTSA9IFwibWVkaXVtXCIsXG4gIExBUkdFID0gXCJsYXJnZVwiLFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJhc2VCdXR0b25Qcm9wcyB7XG4gIGtpbmQ6IEJhc2VCdXR0b25LaW5kXG4gIHNpemU/OiBCYXNlQnV0dG9uU2l6ZVxuICBvbkNsaWNrPzogKGV2ZW50OiBNb3VzZUV2ZW50PEhUTUxCdXR0b25FbGVtZW50PikgPT4gYW55XG4gIGRpc2FibGVkPzogYm9vbGVhblxuICBmbHVpZFdpZHRoPzogYm9vbGVhblxuICBjaGlsZHJlbjogUmVhY3ROb2RlXG4gIGF1dG9Gb2N1cz86IGJvb2xlYW5cbn1cblxudHlwZSBSZXF1aXJlZEJhc2VCdXR0b25Qcm9wcyA9IFJlcXVpcmVkPEJhc2VCdXR0b25Qcm9wcz5cblxuZnVuY3Rpb24gZ2V0U2l6ZVN0eWxlKHNpemU6IEJhc2VCdXR0b25TaXplLCB0aGVtZTogRW1vdGlvblRoZW1lKTogQ1NTT2JqZWN0IHtcbiAgc3dpdGNoIChzaXplKSB7XG4gICAgY2FzZSBCYXNlQnV0dG9uU2l6ZS5YU01BTEw6XG4gICAgICByZXR1cm4ge1xuICAgICAgICBwYWRkaW5nOiBgJHt0aGVtZS5zcGFjaW5nLnR3b1hTfSAke3RoZW1lLnNwYWNpbmcuc219YCxcbiAgICAgICAgZm9udFNpemU6IHRoZW1lLmZvbnRTaXplcy5zbSxcbiAgICAgIH1cbiAgICBjYXNlIEJhc2VCdXR0b25TaXplLlNNQUxMOlxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcGFkZGluZzogYCR7dGhlbWUuc3BhY2luZy50d29YU30gJHt0aGVtZS5zcGFjaW5nLm1kfWAsXG4gICAgICB9XG4gICAgY2FzZSBCYXNlQnV0dG9uU2l6ZS5MQVJHRTpcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHBhZGRpbmc6IGAke3RoZW1lLnNwYWNpbmcubWR9ICR7dGhlbWUuc3BhY2luZy5tZH1gLFxuICAgICAgfVxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4ge1xuICAgICAgICBwYWRkaW5nOiBgJHt0aGVtZS5zcGFjaW5nLnhzfSAke3RoZW1lLnNwYWNpbmcubWR9YCxcbiAgICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3QgU3R5bGVkQmFzZUJ1dHRvbiA9IHN0eWxlZC5idXR0b248UmVxdWlyZWRCYXNlQnV0dG9uUHJvcHM+KFxuICAoeyBmbHVpZFdpZHRoLCBzaXplLCB0aGVtZSB9KSA9PiAoe1xuICAgIGRpc3BsYXk6IFwiaW5saW5lLWZsZXhcIixcbiAgICBhbGlnbkl0ZW1zOiBcImNlbnRlclwiLFxuICAgIGp1c3RpZnlDb250ZW50OiBcImNlbnRlclwiLFxuICAgIGZvbnRXZWlnaHQ6IHRoZW1lLmZvbnRXZWlnaHRzLm5vcm1hbCxcbiAgICBwYWRkaW5nOiBgJHt0aGVtZS5zcGFjaW5nLnhzfSAke3RoZW1lLnNwYWNpbmcubWR9YCxcbiAgICBib3JkZXJSYWRpdXM6IHRoZW1lLnJhZGlpLmxnLFxuICAgIG1pbkhlaWdodDogXCIzOC40cHhcIixcbiAgICBtYXJnaW46IDAsXG4gICAgbGluZUhlaWdodDogdGhlbWUubGluZUhlaWdodHMuYmFzZSxcbiAgICBjb2xvcjogXCJpbmhlcml0XCIsXG4gICAgd2lkdGg6IGZsdWlkV2lkdGggPyBcIjEwMCVcIiA6IFwiYXV0b1wiLFxuICAgIHVzZXJTZWxlY3Q6IFwibm9uZVwiLFxuICAgIFwiJjpmb2N1c1wiOiB7XG4gICAgICBvdXRsaW5lOiBcIm5vbmVcIixcbiAgICB9LFxuICAgIFwiJjpmb2N1cy12aXNpYmxlXCI6IHtcbiAgICAgIGJveFNoYWRvdzogYDAgMCAwIDAuMnJlbSAke3RyYW5zcGFyZW50aXplKHRoZW1lLmNvbG9ycy5wcmltYXJ5LCAwLjUpfWAsXG4gICAgfSxcbiAgICAuLi5nZXRTaXplU3R5bGUoc2l6ZSwgdGhlbWUpLFxuICB9KVxuKVxuXG5leHBvcnQgY29uc3QgU3R5bGVkUHJpbWFyeUJ1dHRvbiA9IHN0eWxlZChcbiAgU3R5bGVkQmFzZUJ1dHRvblxuKTxSZXF1aXJlZEJhc2VCdXR0b25Qcm9wcz4oKHsgdGhlbWUgfSkgPT4gKHtcbiAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgY29sb3I6IHRoZW1lLmNvbG9ycy53aGl0ZSxcbiAgYm9yZGVyOiBgMXB4IHNvbGlkICR7dGhlbWUuY29sb3JzLnByaW1hcnl9YCxcbiAgXCImOmhvdmVyXCI6IHtcbiAgICBiYWNrZ3JvdW5kQ29sb3I6IGRhcmtlbih0aGVtZS5jb2xvcnMucHJpbWFyeSwgMC4wNSksXG4gIH0sXG4gIFwiJjphY3RpdmVcIjoge1xuICAgIGJhY2tncm91bmRDb2xvcjogXCJ0cmFuc3BhcmVudFwiLFxuICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgfSxcbiAgXCImOmRpc2FibGVkLCAmOmRpc2FibGVkOmhvdmVyLCAmOmRpc2FibGVkOmFjdGl2ZVwiOiB7XG4gICAgYm9yZGVyQ29sb3I6IHRoZW1lLmNvbG9ycy5mYWRlZFRleHQxMCxcbiAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoZW1lLmNvbG9ycy50cmFuc3BhcmVudCxcbiAgICBjb2xvcjogdGhlbWUuY29sb3JzLmZhZGVkVGV4dDQwLFxuICAgIGN1cnNvcjogXCJub3QtYWxsb3dlZFwiLFxuICB9LFxufSkpXG5cbmV4cG9ydCBjb25zdCBTdHlsZWRTZWNvbmRhcnlCdXR0b24gPSBzdHlsZWQoXG4gIFN0eWxlZEJhc2VCdXR0b25cbik8UmVxdWlyZWRCYXNlQnV0dG9uUHJvcHM+KCh7IHRoZW1lIH0pID0+ICh7XG4gIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLmxpZ2h0ZW5lZEJnMDUsXG4gIGJvcmRlcjogYDFweCBzb2xpZCAke3RoZW1lLmNvbG9ycy5mYWRlZFRleHQxMH1gLFxuICBcIiY6aG92ZXJcIjoge1xuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICBjb2xvcjogdGhlbWUuY29sb3JzLnByaW1hcnksXG4gIH0sXG4gIFwiJjphY3RpdmVcIjoge1xuICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMud2hpdGUsXG4gICAgYm9yZGVyQ29sb3I6IHRoZW1lLmNvbG9ycy5wcmltYXJ5LFxuICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnByaW1hcnksXG4gIH0sXG4gIFwiJjpmb2N1czpub3QoOmFjdGl2ZSlcIjoge1xuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICBjb2xvcjogdGhlbWUuY29sb3JzLnByaW1hcnksXG4gIH0sXG4gIFwiJjpkaXNhYmxlZCwgJjpkaXNhYmxlZDpob3ZlciwgJjpkaXNhYmxlZDphY3RpdmVcIjoge1xuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMuZmFkZWRUZXh0MTAsXG4gICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gICAgY29sb3I6IHRoZW1lLmNvbG9ycy5mYWRlZFRleHQ0MCxcbiAgICBjdXJzb3I6IFwibm90LWFsbG93ZWRcIixcbiAgfSxcbn0pKVxuXG5leHBvcnQgY29uc3QgU3R5bGVkVGVydGlhcnlCdXR0b24gPSBzdHlsZWQoXG4gIFN0eWxlZEJhc2VCdXR0b25cbik8UmVxdWlyZWRCYXNlQnV0dG9uUHJvcHM+KCh7IHRoZW1lIH0pID0+ICh7XG4gIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICBib3JkZXI6IGAxcHggc29saWQgJHt0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnR9YCxcbiAgXCImOmhvdmVyXCI6IHtcbiAgICBib3JkZXJDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgfSxcbiAgXCImOmFjdGl2ZVwiOiB7XG4gICAgY29sb3I6IHRoZW1lLmNvbG9ycy5wcmltYXJ5LFxuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gIH0sXG4gIFwiJjpmb2N1czpub3QoOmFjdGl2ZSlcIjoge1xuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gICAgY29sb3I6IHRoZW1lLmNvbG9ycy5wcmltYXJ5LFxuICB9LFxuICBcIiY6ZGlzYWJsZWQsICY6ZGlzYWJsZWQ6aG92ZXIsICY6ZGlzYWJsZWQ6YWN0aXZlXCI6IHtcbiAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoZW1lLmNvbG9ycy5saWdodEdyYXksXG4gICAgYm9yZGVyQ29sb3I6IHRoZW1lLmNvbG9ycy50cmFuc3BhcmVudCxcbiAgICBjb2xvcjogdGhlbWUuY29sb3JzLmdyYXksXG4gIH0sXG59KSlcblxuZXhwb3J0IGNvbnN0IFN0eWxlZExpbmtCdXR0b24gPSBzdHlsZWQoXG4gIFN0eWxlZEJhc2VCdXR0b25cbik8UmVxdWlyZWRCYXNlQnV0dG9uUHJvcHM+KCh7IHRoZW1lIH0pID0+ICh7XG4gIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICBwYWRkaW5nOiAwLFxuICBib3JkZXI6IFwibm9uZVwiLFxuICBjb2xvcjogdGhlbWUuY29sb3JzLnByaW1hcnksXG4gIFwiJjpob3ZlclwiOiB7XG4gICAgdGV4dERlY29yYXRpb246IFwidW5kZXJsaW5lXCIsXG4gIH0sXG4gIFwiJjphY3RpdmVcIjoge1xuICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICB0ZXh0RGVjb3JhdGlvbjogXCJ1bmRlcmxpbmVcIixcbiAgfSxcbiAgXCImOmRpc2FibGVkLCAmOmRpc2FibGVkOmhvdmVyLCAmOmRpc2FibGVkOmFjdGl2ZVwiOiB7XG4gICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMubGlnaHRHcmF5LFxuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gICAgY29sb3I6IHRoZW1lLmNvbG9ycy5ncmF5LFxuICB9LFxufSkpXG5cbmV4cG9ydCBjb25zdCBTdHlsZWRNaW5pbWFsQnV0dG9uID0gc3R5bGVkKFxuICBTdHlsZWRCYXNlQnV0dG9uXG4pPFJlcXVpcmVkQmFzZUJ1dHRvblByb3BzPigoeyB0aGVtZSB9KSA9PiAoe1xuICBiYWNrZ3JvdW5kQ29sb3I6IHRoZW1lLmNvbG9ycy50cmFuc3BhcmVudCxcbiAgYm9yZGVyOiBcIm5vbmVcIixcbiAgYm94U2hhZG93OiBcIm5vbmVcIixcbiAgcGFkZGluZzogMCxcbiAgXCImOmhvdmVyLCAmOmFjdGl2ZSwgJjpmb2N1cy12aXNpYmxlXCI6IHtcbiAgICBjb2xvcjogdGhlbWUuY29sb3JzLnByaW1hcnksXG4gIH0sXG59KSlcblxuZXhwb3J0IGNvbnN0IFN0eWxlZFByaW1hcnlGb3JtU3VibWl0QnV0dG9uID1cbiAgc3R5bGVkKFN0eWxlZFByaW1hcnlCdXR0b24pPFJlcXVpcmVkQmFzZUJ1dHRvblByb3BzPigpXG5cbmV4cG9ydCBjb25zdCBTdHlsZWRTZWNvbmRhcnlGb3JtU3VibWl0QnV0dG9uID0gc3R5bGVkKFxuICBTdHlsZWRTZWNvbmRhcnlCdXR0b25cbik8UmVxdWlyZWRCYXNlQnV0dG9uUHJvcHM+KClcblxuZXhwb3J0IGNvbnN0IFN0eWxlZEljb25CdXR0b24gPSBzdHlsZWQoXG4gIFN0eWxlZEJhc2VCdXR0b25cbik8UmVxdWlyZWRCYXNlQnV0dG9uUHJvcHM+KCh7IHNpemUsIHRoZW1lIH0pID0+IHtcbiAgY29uc3QgaWNvblBhZGRpbmc6IFJlY29yZDxCYXNlQnV0dG9uU2l6ZSwgc3RyaW5nPiA9IHtcbiAgICBbQmFzZUJ1dHRvblNpemUuWFNNQUxMXTogdGhlbWUuc3BhY2luZy50aHJlZVhTLFxuICAgIFtCYXNlQnV0dG9uU2l6ZS5TTUFMTF06IHRoZW1lLnNwYWNpbmcudHdvWFMsXG4gICAgW0Jhc2VCdXR0b25TaXplLk1FRElVTV06IHRoZW1lLnNwYWNpbmcubWQsXG4gICAgW0Jhc2VCdXR0b25TaXplLkxBUkdFXTogdGhlbWUuc3BhY2luZy5sZyxcbiAgfVxuICByZXR1cm4ge1xuICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICAgIGJvcmRlcjogYDFweCBzb2xpZCAke3RoZW1lLmNvbG9ycy50cmFuc3BhcmVudH1gLFxuICAgIHBhZGRpbmc6IGljb25QYWRkaW5nW3NpemVdLFxuXG4gICAgXCImOmhvdmVyXCI6IHtcbiAgICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICB9LFxuICAgIFwiJjphY3RpdmVcIjoge1xuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMud2hpdGUsXG4gICAgfSxcbiAgICBcIiY6bm90KDphY3RpdmUpXCI6IHtcbiAgICAgIGJveFNoYWRvdzogXCJub25lXCIsXG4gICAgfSxcbiAgICBcIiY6ZGlzYWJsZWQsICY6ZGlzYWJsZWQ6aG92ZXIsICY6ZGlzYWJsZWQ6YWN0aXZlXCI6IHtcbiAgICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLmxpZ2h0R3JheSxcbiAgICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gICAgICBjb2xvcjogdGhlbWUuY29sb3JzLmdyYXksXG4gICAgfSxcbiAgfVxufSlcblxuZXhwb3J0IGNvbnN0IFN0eWxlZEhlYWRlckJ1dHRvbiA9IHN0eWxlZChcbiAgU3R5bGVkQmFzZUJ1dHRvblxuKTxSZXF1aXJlZEJhc2VCdXR0b25Qcm9wcz4oKHsgdGhlbWUgfSkgPT4ge1xuICByZXR1cm4ge1xuICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICAgIGJvcmRlcjogXCJub25lXCIsXG4gICAgcGFkZGluZzogdGhlbWUuc3BhY2luZy5zbSxcbiAgICBmb250U2l6ZTogdGhlbWUuZm9udFNpemVzLnNtLFxuICAgIG1hcmdpbkxlZnQ6IHRoZW1lLnNwYWNpbmcudGhyZWVYUyxcbiAgICBtYXJnaW5SaWdodDogdGhlbWUuc3BhY2luZy50aHJlZVhTLFxuICAgIGxpbmVIZWlnaHQ6IDEsXG5cbiAgICAvLyBPdmVycmlkZSBidXR0b25zIG1pbiB3aWR0aCBhbmQgaGVpZ2h0LCB0byBlbnN1cmUgdGhlIGhvdmVyIHN0YXRlIGZvciBpY29uIGJ1dHRvbnMgb24gdGhlIGhlYWRlciBpcyBzcXVhcmVcbiAgICBtaW5XaWR0aDogdGhlbWUuc3BhY2luZy50aHJlZVhMLFxuICAgIG1pbkhlaWdodDogdGhlbWUuc3BhY2luZy50aHJlZVhMLFxuXG4gICAgXCImOmZvY3VzXCI6IHtcbiAgICAgIG91dGxpbmU6IFwibm9uZVwiLFxuICAgIH0sXG4gICAgXCImOmZvY3VzLXZpc2libGVcIjoge1xuICAgICAgYm94U2hhZG93OiBgMCAwIDAgMC4ycmVtICR7dHJhbnNwYXJlbnRpemUodGhlbWUuY29sb3JzLmdyYXk5MCwgMC44KX1gLFxuICAgIH0sXG4gICAgXCImOmhvdmVyXCI6IHtcbiAgICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLmRhcmtlbmVkQmdNaXgyNSxcbiAgICB9LFxuICAgIFwiJjpkaXNhYmxlZCwgJjpkaXNhYmxlZDpob3ZlciwgJjpkaXNhYmxlZDphY3RpdmVcIjoge1xuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMubGlnaHRHcmF5LFxuICAgICAgYm9yZGVyQ29sb3I6IHRoZW1lLmNvbG9ycy50cmFuc3BhcmVudCxcbiAgICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMuZ3JheSxcbiAgICB9LFxuICB9XG59KVxuXG4vLyBUYWtlIG91dCBwYWRkaW5nIGZvciB0aGlzIHNwZWNpZmljIGJ1dHRvbiwgc28gd2UgY2FuIGVuc3VyZSBpdCdzIDMyeDMycHggbGlrZSBvdGhlciBidXR0b25zIGluIENvbW11bml0eSBDbG91ZFxuZXhwb3J0IGNvbnN0IFN0eWxlZEhlYWRlck5vUGFkZGluZ0J1dHRvbiA9IHN0eWxlZChcbiAgU3R5bGVkSGVhZGVyQnV0dG9uXG4pPFJlcXVpcmVkQmFzZUJ1dHRvblByb3BzPigoKSA9PiB7XG4gIHJldHVybiB7XG4gICAgcGFkZGluZzogMCxcbiAgfVxufSlcblxuZXhwb3J0IGNvbnN0IFN0eWxlZEJvcmRlcmxlc3NJY29uQnV0dG9uID0gc3R5bGVkKFxuICBTdHlsZWRCYXNlQnV0dG9uXG4pPFJlcXVpcmVkQmFzZUJ1dHRvblByb3BzPigoeyBzaXplLCB0aGVtZSB9KSA9PiB7XG4gIGNvbnN0IGljb25QYWRkaW5nOiBSZWNvcmQ8QmFzZUJ1dHRvblNpemUsIHN0cmluZz4gPSB7XG4gICAgW0Jhc2VCdXR0b25TaXplLlhTTUFMTF06IHRoZW1lLnNwYWNpbmcudGhyZWVYUyxcbiAgICBbQmFzZUJ1dHRvblNpemUuU01BTExdOiB0aGVtZS5zcGFjaW5nLnR3b1hTLFxuICAgIFtCYXNlQnV0dG9uU2l6ZS5NRURJVU1dOiB0aGVtZS5zcGFjaW5nLm1kLFxuICAgIFtCYXNlQnV0dG9uU2l6ZS5MQVJHRV06IHRoZW1lLnNwYWNpbmcubGcsXG4gIH1cblxuICByZXR1cm4ge1xuICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICAgIGJvcmRlcjogYDFweCBzb2xpZCAke3RoZW1lLmNvbG9ycy50cmFuc3BhcmVudH1gLFxuICAgIHBhZGRpbmc6IGljb25QYWRkaW5nW3NpemVdLFxuXG4gICAgXCImOmZvY3VzXCI6IHtcbiAgICAgIGJveFNoYWRvdzogXCJub25lXCIsXG4gICAgICBvdXRsaW5lOiBcIm5vbmVcIixcbiAgICB9LFxuICAgIFwiJjpkaXNhYmxlZCwgJjpkaXNhYmxlZDpob3ZlciwgJjpkaXNhYmxlZDphY3RpdmVcIjoge1xuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMubGlnaHRHcmF5LFxuICAgICAgYm9yZGVyQ29sb3I6IHRoZW1lLmNvbG9ycy50cmFuc3BhcmVudCxcbiAgICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMuZ3JheSxcbiAgICB9LFxuICB9XG59KVxuXG5leHBvcnQgY29uc3QgU3R5bGVkVG9vbHRpcE5vcm1hbCA9IHN0eWxlZC5kaXYoKHsgdGhlbWUgfSkgPT4gKHtcbiAgZGlzcGxheTogXCJibG9ja1wiLFxuICBbYEBtZWRpYSAobWF4LXdpZHRoOiAke3RoZW1lLmJyZWFrcG9pbnRzLnNtfSlgXToge1xuICAgIGRpc3BsYXk6IFwibm9uZVwiLFxuICB9LFxufSkpXG5cbmV4cG9ydCBjb25zdCBTdHlsZWRUb29sdGlwTW9iaWxlID0gc3R5bGVkLmRpdigoeyB0aGVtZSB9KSA9PiAoe1xuICBkaXNwbGF5OiBcIm5vbmVcIixcbiAgW2BAbWVkaWEgKG1heC13aWR0aDogJHt0aGVtZS5icmVha3BvaW50cy5zbX0pYF06IHtcbiAgICBkaXNwbGF5OiBcImJsb2NrXCIsXG4gIH0sXG59KSlcbiJdfQ== */ + .css-2v1jym-StyledBaseButton-StyledTertiaryButton{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;font-weight:400;padding:0.375rem 0.75rem;border-radius:0.5rem;min-height:38.4px;margin:0;line-height:1.6;color:inherit;width:auto;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;}/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0eWxlZC1jb21wb25lbnRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQXlKb0MiLCJmaWxlIjoic3R5bGVkLWNvbXBvbmVudHMudHMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENvcHlyaWdodCAoYykgU3RyZWFtbGl0IEluYy4gKDIwMTgtMjAyMikgU25vd2ZsYWtlIEluYy4gKDIwMjIpXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IE1vdXNlRXZlbnQsIFJlYWN0Tm9kZSB9IGZyb20gXCJyZWFjdFwiXG5pbXBvcnQgc3R5bGVkLCB7IENTU09iamVjdCB9IGZyb20gXCJAZW1vdGlvbi9zdHlsZWRcIlxuaW1wb3J0IHsgZGFya2VuLCB0cmFuc3BhcmVudGl6ZSB9IGZyb20gXCJjb2xvcjJrXCJcbmltcG9ydCB7IEVtb3Rpb25UaGVtZSB9IGZyb20gXCJAc3RyZWFtbGl0L2xpYi9zcmMvdGhlbWVcIlxuXG5leHBvcnQgZW51bSBCYXNlQnV0dG9uS2luZCB7XG4gIFBSSU1BUlkgPSBcInByaW1hcnlcIixcbiAgU0VDT05EQVJZID0gXCJzZWNvbmRhcnlcIixcbiAgVEVSVElBUlkgPSBcInRlcnRpYXJ5XCIsXG4gIExJTksgPSBcImxpbmtcIixcbiAgSUNPTiA9IFwiaWNvblwiLFxuICBCT1JERVJMRVNTX0lDT04gPSBcImJvcmRlcmxlc3NJY29uXCIsXG4gIE1JTklNQUwgPSBcIm1pbmltYWxcIixcbiAgUFJJTUFSWV9GT1JNX1NVQk1JVCA9IFwicHJpbWFyeUZvcm1TdWJtaXRcIixcbiAgU0VDT05EQVJZX0ZPUk1fU1VCTUlUID0gXCJzZWNvbmRhcnlGb3JtU3VibWl0XCIsXG4gIEhFQURFUl9CVVRUT04gPSBcImhlYWRlclwiLFxuICBIRUFERVJfTk9fUEFERElORyA9IFwiaGVhZGVyTm9QYWRkaW5nXCIsXG59XG5cbmV4cG9ydCBlbnVtIEJhc2VCdXR0b25TaXplIHtcbiAgWFNNQUxMID0gXCJ4c21hbGxcIixcbiAgU01BTEwgPSBcInNtYWxsXCIsXG4gIE1FRElVTSA9IFwibWVkaXVtXCIsXG4gIExBUkdFID0gXCJsYXJnZVwiLFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJhc2VCdXR0b25Qcm9wcyB7XG4gIGtpbmQ6IEJhc2VCdXR0b25LaW5kXG4gIHNpemU/OiBCYXNlQnV0dG9uU2l6ZVxuICBvbkNsaWNrPzogKGV2ZW50OiBNb3VzZUV2ZW50PEhUTUxCdXR0b25FbGVtZW50PikgPT4gYW55XG4gIGRpc2FibGVkPzogYm9vbGVhblxuICAvLyBJZiB0cnVlIG9yIG51bWJlciwgdGhlIGJ1dHRvbiBzaG91bGQgdGFrZSB1cCBjb250YWluZXIncyBmdWxsIHdpZHRoXG4gIGZsdWlkV2lkdGg/OiBib29sZWFuIHwgbnVtYmVyXG4gIGNoaWxkcmVuOiBSZWFjdE5vZGVcbiAgYXV0b0ZvY3VzPzogYm9vbGVhblxufVxuXG50eXBlIFJlcXVpcmVkQmFzZUJ1dHRvblByb3BzID0gUmVxdWlyZWQ8QmFzZUJ1dHRvblByb3BzPlxuXG5mdW5jdGlvbiBnZXRTaXplU3R5bGUoc2l6ZTogQmFzZUJ1dHRvblNpemUsIHRoZW1lOiBFbW90aW9uVGhlbWUpOiBDU1NPYmplY3Qge1xuICBzd2l0Y2ggKHNpemUpIHtcbiAgICBjYXNlIEJhc2VCdXR0b25TaXplLlhTTUFMTDpcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHBhZGRpbmc6IGAke3RoZW1lLnNwYWNpbmcudHdvWFN9ICR7dGhlbWUuc3BhY2luZy5zbX1gLFxuICAgICAgICBmb250U2l6ZTogdGhlbWUuZm9udFNpemVzLnNtLFxuICAgICAgfVxuICAgIGNhc2UgQmFzZUJ1dHRvblNpemUuU01BTEw6XG4gICAgICByZXR1cm4ge1xuICAgICAgICBwYWRkaW5nOiBgJHt0aGVtZS5zcGFjaW5nLnR3b1hTfSAke3RoZW1lLnNwYWNpbmcubWR9YCxcbiAgICAgIH1cbiAgICBjYXNlIEJhc2VCdXR0b25TaXplLkxBUkdFOlxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcGFkZGluZzogYCR7dGhlbWUuc3BhY2luZy5tZH0gJHt0aGVtZS5zcGFjaW5nLm1kfWAsXG4gICAgICB9XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHBhZGRpbmc6IGAke3RoZW1lLnNwYWNpbmcueHN9ICR7dGhlbWUuc3BhY2luZy5tZH1gLFxuICAgICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBTdHlsZWRCYXNlQnV0dG9uID0gc3R5bGVkLmJ1dHRvbjxSZXF1aXJlZEJhc2VCdXR0b25Qcm9wcz4oXG4gICh7IGZsdWlkV2lkdGgsIHNpemUsIHRoZW1lIH0pID0+IHtcbiAgICBjb25zdCBidXR0b25XaWR0aCA9XG4gICAgICB0eXBlb2YgZmx1aWRXaWR0aCA9PSBcIm51bWJlclwiID8gYCR7Zmx1aWRXaWR0aH1weGAgOiBcIjEwMCVcIlxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGRpc3BsYXk6IFwiaW5saW5lLWZsZXhcIixcbiAgICAgIGFsaWduSXRlbXM6IFwiY2VudGVyXCIsXG4gICAgICBqdXN0aWZ5Q29udGVudDogXCJjZW50ZXJcIixcbiAgICAgIGZvbnRXZWlnaHQ6IHRoZW1lLmZvbnRXZWlnaHRzLm5vcm1hbCxcbiAgICAgIHBhZGRpbmc6IGAke3RoZW1lLnNwYWNpbmcueHN9ICR7dGhlbWUuc3BhY2luZy5tZH1gLFxuICAgICAgYm9yZGVyUmFkaXVzOiB0aGVtZS5yYWRpaS5sZyxcbiAgICAgIG1pbkhlaWdodDogXCIzOC40cHhcIixcbiAgICAgIG1hcmdpbjogMCxcbiAgICAgIGxpbmVIZWlnaHQ6IHRoZW1lLmxpbmVIZWlnaHRzLmJhc2UsXG4gICAgICBjb2xvcjogXCJpbmhlcml0XCIsXG4gICAgICB3aWR0aDogZmx1aWRXaWR0aCA/IGJ1dHRvbldpZHRoIDogXCJhdXRvXCIsXG4gICAgICB1c2VyU2VsZWN0OiBcIm5vbmVcIixcbiAgICAgIFwiJjpmb2N1c1wiOiB7XG4gICAgICAgIG91dGxpbmU6IFwibm9uZVwiLFxuICAgICAgfSxcbiAgICAgIFwiJjpmb2N1cy12aXNpYmxlXCI6IHtcbiAgICAgICAgYm94U2hhZG93OiBgMCAwIDAgMC4ycmVtICR7dHJhbnNwYXJlbnRpemUodGhlbWUuY29sb3JzLnByaW1hcnksIDAuNSl9YCxcbiAgICAgIH0sXG4gICAgICAuLi5nZXRTaXplU3R5bGUoc2l6ZSwgdGhlbWUpLFxuICAgIH1cbiAgfVxuKVxuXG5leHBvcnQgY29uc3QgU3R5bGVkUHJpbWFyeUJ1dHRvbiA9IHN0eWxlZChcbiAgU3R5bGVkQmFzZUJ1dHRvblxuKTxSZXF1aXJlZEJhc2VCdXR0b25Qcm9wcz4oKHsgdGhlbWUgfSkgPT4gKHtcbiAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgY29sb3I6IHRoZW1lLmNvbG9ycy53aGl0ZSxcbiAgYm9yZGVyOiBgMXB4IHNvbGlkICR7dGhlbWUuY29sb3JzLnByaW1hcnl9YCxcbiAgXCImOmhvdmVyXCI6IHtcbiAgICBiYWNrZ3JvdW5kQ29sb3I6IGRhcmtlbih0aGVtZS5jb2xvcnMucHJpbWFyeSwgMC4wNSksXG4gIH0sXG4gIFwiJjphY3RpdmVcIjoge1xuICAgIGJhY2tncm91bmRDb2xvcjogXCJ0cmFuc3BhcmVudFwiLFxuICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgfSxcbiAgXCImOmRpc2FibGVkLCAmOmRpc2FibGVkOmhvdmVyLCAmOmRpc2FibGVkOmFjdGl2ZVwiOiB7XG4gICAgYm9yZGVyQ29sb3I6IHRoZW1lLmNvbG9ycy5mYWRlZFRleHQxMCxcbiAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoZW1lLmNvbG9ycy50cmFuc3BhcmVudCxcbiAgICBjb2xvcjogdGhlbWUuY29sb3JzLmZhZGVkVGV4dDQwLFxuICAgIGN1cnNvcjogXCJub3QtYWxsb3dlZFwiLFxuICB9LFxufSkpXG5cbmV4cG9ydCBjb25zdCBTdHlsZWRTZWNvbmRhcnlCdXR0b24gPSBzdHlsZWQoXG4gIFN0eWxlZEJhc2VCdXR0b25cbik8UmVxdWlyZWRCYXNlQnV0dG9uUHJvcHM+KCh7IHRoZW1lIH0pID0+ICh7XG4gIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLmxpZ2h0ZW5lZEJnMDUsXG4gIGJvcmRlcjogYDFweCBzb2xpZCAke3RoZW1lLmNvbG9ycy5mYWRlZFRleHQxMH1gLFxuICBcIiY6aG92ZXJcIjoge1xuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICBjb2xvcjogdGhlbWUuY29sb3JzLnByaW1hcnksXG4gIH0sXG4gIFwiJjphY3RpdmVcIjoge1xuICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMud2hpdGUsXG4gICAgYm9yZGVyQ29sb3I6IHRoZW1lLmNvbG9ycy5wcmltYXJ5LFxuICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnByaW1hcnksXG4gIH0sXG4gIFwiJjpmb2N1czpub3QoOmFjdGl2ZSlcIjoge1xuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICBjb2xvcjogdGhlbWUuY29sb3JzLnByaW1hcnksXG4gIH0sXG4gIFwiJjpkaXNhYmxlZCwgJjpkaXNhYmxlZDpob3ZlciwgJjpkaXNhYmxlZDphY3RpdmVcIjoge1xuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMuZmFkZWRUZXh0MTAsXG4gICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gICAgY29sb3I6IHRoZW1lLmNvbG9ycy5mYWRlZFRleHQ0MCxcbiAgICBjdXJzb3I6IFwibm90LWFsbG93ZWRcIixcbiAgfSxcbn0pKVxuXG5leHBvcnQgY29uc3QgU3R5bGVkVGVydGlhcnlCdXR0b24gPSBzdHlsZWQoXG4gIFN0eWxlZEJhc2VCdXR0b25cbik8UmVxdWlyZWRCYXNlQnV0dG9uUHJvcHM+KCh7IHRoZW1lIH0pID0+ICh7XG4gIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICBib3JkZXI6IGAxcHggc29saWQgJHt0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnR9YCxcbiAgXCImOmhvdmVyXCI6IHtcbiAgICBib3JkZXJDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgfSxcbiAgXCImOmFjdGl2ZVwiOiB7XG4gICAgY29sb3I6IHRoZW1lLmNvbG9ycy5wcmltYXJ5LFxuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gIH0sXG4gIFwiJjpmb2N1czpub3QoOmFjdGl2ZSlcIjoge1xuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gICAgY29sb3I6IHRoZW1lLmNvbG9ycy5wcmltYXJ5LFxuICB9LFxuICBcIiY6ZGlzYWJsZWQsICY6ZGlzYWJsZWQ6aG92ZXIsICY6ZGlzYWJsZWQ6YWN0aXZlXCI6IHtcbiAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoZW1lLmNvbG9ycy5saWdodEdyYXksXG4gICAgYm9yZGVyQ29sb3I6IHRoZW1lLmNvbG9ycy50cmFuc3BhcmVudCxcbiAgICBjb2xvcjogdGhlbWUuY29sb3JzLmdyYXksXG4gIH0sXG59KSlcblxuZXhwb3J0IGNvbnN0IFN0eWxlZExpbmtCdXR0b24gPSBzdHlsZWQoXG4gIFN0eWxlZEJhc2VCdXR0b25cbik8UmVxdWlyZWRCYXNlQnV0dG9uUHJvcHM+KCh7IHRoZW1lIH0pID0+ICh7XG4gIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICBwYWRkaW5nOiAwLFxuICBib3JkZXI6IFwibm9uZVwiLFxuICBjb2xvcjogdGhlbWUuY29sb3JzLnByaW1hcnksXG4gIFwiJjpob3ZlclwiOiB7XG4gICAgdGV4dERlY29yYXRpb246IFwidW5kZXJsaW5lXCIsXG4gIH0sXG4gIFwiJjphY3RpdmVcIjoge1xuICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICB0ZXh0RGVjb3JhdGlvbjogXCJ1bmRlcmxpbmVcIixcbiAgfSxcbiAgXCImOmRpc2FibGVkLCAmOmRpc2FibGVkOmhvdmVyLCAmOmRpc2FibGVkOmFjdGl2ZVwiOiB7XG4gICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMubGlnaHRHcmF5LFxuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gICAgY29sb3I6IHRoZW1lLmNvbG9ycy5ncmF5LFxuICB9LFxufSkpXG5cbmV4cG9ydCBjb25zdCBTdHlsZWRNaW5pbWFsQnV0dG9uID0gc3R5bGVkKFxuICBTdHlsZWRCYXNlQnV0dG9uXG4pPFJlcXVpcmVkQmFzZUJ1dHRvblByb3BzPigoeyB0aGVtZSB9KSA9PiAoe1xuICBiYWNrZ3JvdW5kQ29sb3I6IHRoZW1lLmNvbG9ycy50cmFuc3BhcmVudCxcbiAgYm9yZGVyOiBcIm5vbmVcIixcbiAgYm94U2hhZG93OiBcIm5vbmVcIixcbiAgcGFkZGluZzogMCxcbiAgXCImOmhvdmVyLCAmOmFjdGl2ZSwgJjpmb2N1cy12aXNpYmxlXCI6IHtcbiAgICBjb2xvcjogdGhlbWUuY29sb3JzLnByaW1hcnksXG4gIH0sXG59KSlcblxuZXhwb3J0IGNvbnN0IFN0eWxlZFByaW1hcnlGb3JtU3VibWl0QnV0dG9uID1cbiAgc3R5bGVkKFN0eWxlZFByaW1hcnlCdXR0b24pPFJlcXVpcmVkQmFzZUJ1dHRvblByb3BzPigpXG5cbmV4cG9ydCBjb25zdCBTdHlsZWRTZWNvbmRhcnlGb3JtU3VibWl0QnV0dG9uID0gc3R5bGVkKFxuICBTdHlsZWRTZWNvbmRhcnlCdXR0b25cbik8UmVxdWlyZWRCYXNlQnV0dG9uUHJvcHM+KClcblxuZXhwb3J0IGNvbnN0IFN0eWxlZEljb25CdXR0b24gPSBzdHlsZWQoXG4gIFN0eWxlZEJhc2VCdXR0b25cbik8UmVxdWlyZWRCYXNlQnV0dG9uUHJvcHM+KCh7IHNpemUsIHRoZW1lIH0pID0+IHtcbiAgY29uc3QgaWNvblBhZGRpbmc6IFJlY29yZDxCYXNlQnV0dG9uU2l6ZSwgc3RyaW5nPiA9IHtcbiAgICBbQmFzZUJ1dHRvblNpemUuWFNNQUxMXTogdGhlbWUuc3BhY2luZy50aHJlZVhTLFxuICAgIFtCYXNlQnV0dG9uU2l6ZS5TTUFMTF06IHRoZW1lLnNwYWNpbmcudHdvWFMsXG4gICAgW0Jhc2VCdXR0b25TaXplLk1FRElVTV06IHRoZW1lLnNwYWNpbmcubWQsXG4gICAgW0Jhc2VCdXR0b25TaXplLkxBUkdFXTogdGhlbWUuc3BhY2luZy5sZyxcbiAgfVxuICByZXR1cm4ge1xuICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICAgIGJvcmRlcjogYDFweCBzb2xpZCAke3RoZW1lLmNvbG9ycy50cmFuc3BhcmVudH1gLFxuICAgIHBhZGRpbmc6IGljb25QYWRkaW5nW3NpemVdLFxuXG4gICAgXCImOmhvdmVyXCI6IHtcbiAgICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICB9LFxuICAgIFwiJjphY3RpdmVcIjoge1xuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMud2hpdGUsXG4gICAgfSxcbiAgICBcIiY6bm90KDphY3RpdmUpXCI6IHtcbiAgICAgIGJveFNoYWRvdzogXCJub25lXCIsXG4gICAgfSxcbiAgICBcIiY6ZGlzYWJsZWQsICY6ZGlzYWJsZWQ6aG92ZXIsICY6ZGlzYWJsZWQ6YWN0aXZlXCI6IHtcbiAgICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLmxpZ2h0R3JheSxcbiAgICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gICAgICBjb2xvcjogdGhlbWUuY29sb3JzLmdyYXksXG4gICAgfSxcbiAgfVxufSlcblxuZXhwb3J0IGNvbnN0IFN0eWxlZEhlYWRlckJ1dHRvbiA9IHN0eWxlZChcbiAgU3R5bGVkQmFzZUJ1dHRvblxuKTxSZXF1aXJlZEJhc2VCdXR0b25Qcm9wcz4oKHsgdGhlbWUgfSkgPT4ge1xuICByZXR1cm4ge1xuICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICAgIGJvcmRlcjogXCJub25lXCIsXG4gICAgcGFkZGluZzogdGhlbWUuc3BhY2luZy5zbSxcbiAgICBmb250U2l6ZTogdGhlbWUuZm9udFNpemVzLnNtLFxuICAgIG1hcmdpbkxlZnQ6IHRoZW1lLnNwYWNpbmcudGhyZWVYUyxcbiAgICBtYXJnaW5SaWdodDogdGhlbWUuc3BhY2luZy50aHJlZVhTLFxuICAgIGxpbmVIZWlnaHQ6IDEsXG5cbiAgICAvLyBPdmVycmlkZSBidXR0b25zIG1pbiB3aWR0aCBhbmQgaGVpZ2h0LCB0byBlbnN1cmUgdGhlIGhvdmVyIHN0YXRlIGZvciBpY29uIGJ1dHRvbnMgb24gdGhlIGhlYWRlciBpcyBzcXVhcmVcbiAgICBtaW5XaWR0aDogdGhlbWUuc3BhY2luZy50aHJlZVhMLFxuICAgIG1pbkhlaWdodDogdGhlbWUuc3BhY2luZy50aHJlZVhMLFxuXG4gICAgXCImOmZvY3VzXCI6IHtcbiAgICAgIG91dGxpbmU6IFwibm9uZVwiLFxuICAgIH0sXG4gICAgXCImOmZvY3VzLXZpc2libGVcIjoge1xuICAgICAgYm94U2hhZG93OiBgMCAwIDAgMC4ycmVtICR7dHJhbnNwYXJlbnRpemUodGhlbWUuY29sb3JzLmdyYXk5MCwgMC44KX1gLFxuICAgIH0sXG4gICAgXCImOmhvdmVyXCI6IHtcbiAgICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLmRhcmtlbmVkQmdNaXgyNSxcbiAgICB9LFxuICAgIFwiJjpkaXNhYmxlZCwgJjpkaXNhYmxlZDpob3ZlciwgJjpkaXNhYmxlZDphY3RpdmVcIjoge1xuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMubGlnaHRHcmF5LFxuICAgICAgYm9yZGVyQ29sb3I6IHRoZW1lLmNvbG9ycy50cmFuc3BhcmVudCxcbiAgICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMuZ3JheSxcbiAgICB9LFxuICB9XG59KVxuXG4vLyBUYWtlIG91dCBwYWRkaW5nIGZvciB0aGlzIHNwZWNpZmljIGJ1dHRvbiwgc28gd2UgY2FuIGVuc3VyZSBpdCdzIDMyeDMycHggbGlrZSBvdGhlciBidXR0b25zIGluIENvbW11bml0eSBDbG91ZFxuZXhwb3J0IGNvbnN0IFN0eWxlZEhlYWRlck5vUGFkZGluZ0J1dHRvbiA9IHN0eWxlZChcbiAgU3R5bGVkSGVhZGVyQnV0dG9uXG4pPFJlcXVpcmVkQmFzZUJ1dHRvblByb3BzPigoKSA9PiB7XG4gIHJldHVybiB7XG4gICAgcGFkZGluZzogMCxcbiAgfVxufSlcblxuZXhwb3J0IGNvbnN0IFN0eWxlZEJvcmRlcmxlc3NJY29uQnV0dG9uID0gc3R5bGVkKFxuICBTdHlsZWRCYXNlQnV0dG9uXG4pPFJlcXVpcmVkQmFzZUJ1dHRvblByb3BzPigoeyBzaXplLCB0aGVtZSB9KSA9PiB7XG4gIGNvbnN0IGljb25QYWRkaW5nOiBSZWNvcmQ8QmFzZUJ1dHRvblNpemUsIHN0cmluZz4gPSB7XG4gICAgW0Jhc2VCdXR0b25TaXplLlhTTUFMTF06IHRoZW1lLnNwYWNpbmcudGhyZWVYUyxcbiAgICBbQmFzZUJ1dHRvblNpemUuU01BTExdOiB0aGVtZS5zcGFjaW5nLnR3b1hTLFxuICAgIFtCYXNlQnV0dG9uU2l6ZS5NRURJVU1dOiB0aGVtZS5zcGFjaW5nLm1kLFxuICAgIFtCYXNlQnV0dG9uU2l6ZS5MQVJHRV06IHRoZW1lLnNwYWNpbmcubGcsXG4gIH1cblxuICByZXR1cm4ge1xuICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICAgIGJvcmRlcjogYDFweCBzb2xpZCAke3RoZW1lLmNvbG9ycy50cmFuc3BhcmVudH1gLFxuICAgIHBhZGRpbmc6IGljb25QYWRkaW5nW3NpemVdLFxuXG4gICAgXCImOmZvY3VzXCI6IHtcbiAgICAgIGJveFNoYWRvdzogXCJub25lXCIsXG4gICAgICBvdXRsaW5lOiBcIm5vbmVcIixcbiAgICB9LFxuICAgIFwiJjpkaXNhYmxlZCwgJjpkaXNhYmxlZDpob3ZlciwgJjpkaXNhYmxlZDphY3RpdmVcIjoge1xuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMubGlnaHRHcmF5LFxuICAgICAgYm9yZGVyQ29sb3I6IHRoZW1lLmNvbG9ycy50cmFuc3BhcmVudCxcbiAgICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMuZ3JheSxcbiAgICB9LFxuICB9XG59KVxuXG5leHBvcnQgY29uc3QgU3R5bGVkVG9vbHRpcE5vcm1hbCA9IHN0eWxlZC5kaXYoKHsgdGhlbWUgfSkgPT4gKHtcbiAgZGlzcGxheTogXCJibG9ja1wiLFxuICBbYEBtZWRpYSAobWF4LXdpZHRoOiAke3RoZW1lLmJyZWFrcG9pbnRzLnNtfSlgXToge1xuICAgIGRpc3BsYXk6IFwibm9uZVwiLFxuICB9LFxufSkpXG5cbmV4cG9ydCBjb25zdCBTdHlsZWRUb29sdGlwTW9iaWxlID0gc3R5bGVkLmRpdigoeyB0aGVtZSB9KSA9PiAoe1xuICBkaXNwbGF5OiBcIm5vbmVcIixcbiAgW2BAbWVkaWEgKG1heC13aWR0aDogJHt0aGVtZS5icmVha3BvaW50cy5zbX0pYF06IHtcbiAgICBkaXNwbGF5OiBcImJsb2NrXCIsXG4gIH0sXG59KSlcbiJdfQ== */ , , , , , , , , , , , , , , ], }, @@ -251,7 +252,7 @@ exports[`StreamlitDialog renders secondary dialog buttons properly 1`] = ` isStringTag={true} serialized={ Object { - "map": "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0eWxlZC1jb21wb25lbnRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQXlIcUMiLCJmaWxlIjoic3R5bGVkLWNvbXBvbmVudHMudHMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENvcHlyaWdodCAoYykgU3RyZWFtbGl0IEluYy4gKDIwMTgtMjAyMikgU25vd2ZsYWtlIEluYy4gKDIwMjIpXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IE1vdXNlRXZlbnQsIFJlYWN0Tm9kZSB9IGZyb20gXCJyZWFjdFwiXG5pbXBvcnQgc3R5bGVkLCB7IENTU09iamVjdCB9IGZyb20gXCJAZW1vdGlvbi9zdHlsZWRcIlxuaW1wb3J0IHsgZGFya2VuLCB0cmFuc3BhcmVudGl6ZSB9IGZyb20gXCJjb2xvcjJrXCJcbmltcG9ydCB7IEVtb3Rpb25UaGVtZSB9IGZyb20gXCJAc3RyZWFtbGl0L2xpYi9zcmMvdGhlbWVcIlxuXG5leHBvcnQgZW51bSBCYXNlQnV0dG9uS2luZCB7XG4gIFBSSU1BUlkgPSBcInByaW1hcnlcIixcbiAgU0VDT05EQVJZID0gXCJzZWNvbmRhcnlcIixcbiAgVEVSVElBUlkgPSBcInRlcnRpYXJ5XCIsXG4gIExJTksgPSBcImxpbmtcIixcbiAgSUNPTiA9IFwiaWNvblwiLFxuICBCT1JERVJMRVNTX0lDT04gPSBcImJvcmRlcmxlc3NJY29uXCIsXG4gIE1JTklNQUwgPSBcIm1pbmltYWxcIixcbiAgUFJJTUFSWV9GT1JNX1NVQk1JVCA9IFwicHJpbWFyeUZvcm1TdWJtaXRcIixcbiAgU0VDT05EQVJZX0ZPUk1fU1VCTUlUID0gXCJzZWNvbmRhcnlGb3JtU3VibWl0XCIsXG4gIEhFQURFUl9CVVRUT04gPSBcImhlYWRlclwiLFxuICBIRUFERVJfTk9fUEFERElORyA9IFwiaGVhZGVyTm9QYWRkaW5nXCIsXG59XG5cbmV4cG9ydCBlbnVtIEJhc2VCdXR0b25TaXplIHtcbiAgWFNNQUxMID0gXCJ4c21hbGxcIixcbiAgU01BTEwgPSBcInNtYWxsXCIsXG4gIE1FRElVTSA9IFwibWVkaXVtXCIsXG4gIExBUkdFID0gXCJsYXJnZVwiLFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJhc2VCdXR0b25Qcm9wcyB7XG4gIGtpbmQ6IEJhc2VCdXR0b25LaW5kXG4gIHNpemU/OiBCYXNlQnV0dG9uU2l6ZVxuICBvbkNsaWNrPzogKGV2ZW50OiBNb3VzZUV2ZW50PEhUTUxCdXR0b25FbGVtZW50PikgPT4gYW55XG4gIGRpc2FibGVkPzogYm9vbGVhblxuICBmbHVpZFdpZHRoPzogYm9vbGVhblxuICBjaGlsZHJlbjogUmVhY3ROb2RlXG4gIGF1dG9Gb2N1cz86IGJvb2xlYW5cbn1cblxudHlwZSBSZXF1aXJlZEJhc2VCdXR0b25Qcm9wcyA9IFJlcXVpcmVkPEJhc2VCdXR0b25Qcm9wcz5cblxuZnVuY3Rpb24gZ2V0U2l6ZVN0eWxlKHNpemU6IEJhc2VCdXR0b25TaXplLCB0aGVtZTogRW1vdGlvblRoZW1lKTogQ1NTT2JqZWN0IHtcbiAgc3dpdGNoIChzaXplKSB7XG4gICAgY2FzZSBCYXNlQnV0dG9uU2l6ZS5YU01BTEw6XG4gICAgICByZXR1cm4ge1xuICAgICAgICBwYWRkaW5nOiBgJHt0aGVtZS5zcGFjaW5nLnR3b1hTfSAke3RoZW1lLnNwYWNpbmcuc219YCxcbiAgICAgICAgZm9udFNpemU6IHRoZW1lLmZvbnRTaXplcy5zbSxcbiAgICAgIH1cbiAgICBjYXNlIEJhc2VCdXR0b25TaXplLlNNQUxMOlxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcGFkZGluZzogYCR7dGhlbWUuc3BhY2luZy50d29YU30gJHt0aGVtZS5zcGFjaW5nLm1kfWAsXG4gICAgICB9XG4gICAgY2FzZSBCYXNlQnV0dG9uU2l6ZS5MQVJHRTpcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHBhZGRpbmc6IGAke3RoZW1lLnNwYWNpbmcubWR9ICR7dGhlbWUuc3BhY2luZy5tZH1gLFxuICAgICAgfVxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4ge1xuICAgICAgICBwYWRkaW5nOiBgJHt0aGVtZS5zcGFjaW5nLnhzfSAke3RoZW1lLnNwYWNpbmcubWR9YCxcbiAgICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3QgU3R5bGVkQmFzZUJ1dHRvbiA9IHN0eWxlZC5idXR0b248UmVxdWlyZWRCYXNlQnV0dG9uUHJvcHM+KFxuICAoeyBmbHVpZFdpZHRoLCBzaXplLCB0aGVtZSB9KSA9PiAoe1xuICAgIGRpc3BsYXk6IFwiaW5saW5lLWZsZXhcIixcbiAgICBhbGlnbkl0ZW1zOiBcImNlbnRlclwiLFxuICAgIGp1c3RpZnlDb250ZW50OiBcImNlbnRlclwiLFxuICAgIGZvbnRXZWlnaHQ6IHRoZW1lLmZvbnRXZWlnaHRzLm5vcm1hbCxcbiAgICBwYWRkaW5nOiBgJHt0aGVtZS5zcGFjaW5nLnhzfSAke3RoZW1lLnNwYWNpbmcubWR9YCxcbiAgICBib3JkZXJSYWRpdXM6IHRoZW1lLnJhZGlpLmxnLFxuICAgIG1pbkhlaWdodDogXCIzOC40cHhcIixcbiAgICBtYXJnaW46IDAsXG4gICAgbGluZUhlaWdodDogdGhlbWUubGluZUhlaWdodHMuYmFzZSxcbiAgICBjb2xvcjogXCJpbmhlcml0XCIsXG4gICAgd2lkdGg6IGZsdWlkV2lkdGggPyBcIjEwMCVcIiA6IFwiYXV0b1wiLFxuICAgIHVzZXJTZWxlY3Q6IFwibm9uZVwiLFxuICAgIFwiJjpmb2N1c1wiOiB7XG4gICAgICBvdXRsaW5lOiBcIm5vbmVcIixcbiAgICB9LFxuICAgIFwiJjpmb2N1cy12aXNpYmxlXCI6IHtcbiAgICAgIGJveFNoYWRvdzogYDAgMCAwIDAuMnJlbSAke3RyYW5zcGFyZW50aXplKHRoZW1lLmNvbG9ycy5wcmltYXJ5LCAwLjUpfWAsXG4gICAgfSxcbiAgICAuLi5nZXRTaXplU3R5bGUoc2l6ZSwgdGhlbWUpLFxuICB9KVxuKVxuXG5leHBvcnQgY29uc3QgU3R5bGVkUHJpbWFyeUJ1dHRvbiA9IHN0eWxlZChcbiAgU3R5bGVkQmFzZUJ1dHRvblxuKTxSZXF1aXJlZEJhc2VCdXR0b25Qcm9wcz4oKHsgdGhlbWUgfSkgPT4gKHtcbiAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgY29sb3I6IHRoZW1lLmNvbG9ycy53aGl0ZSxcbiAgYm9yZGVyOiBgMXB4IHNvbGlkICR7dGhlbWUuY29sb3JzLnByaW1hcnl9YCxcbiAgXCImOmhvdmVyXCI6IHtcbiAgICBiYWNrZ3JvdW5kQ29sb3I6IGRhcmtlbih0aGVtZS5jb2xvcnMucHJpbWFyeSwgMC4wNSksXG4gIH0sXG4gIFwiJjphY3RpdmVcIjoge1xuICAgIGJhY2tncm91bmRDb2xvcjogXCJ0cmFuc3BhcmVudFwiLFxuICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgfSxcbiAgXCImOmRpc2FibGVkLCAmOmRpc2FibGVkOmhvdmVyLCAmOmRpc2FibGVkOmFjdGl2ZVwiOiB7XG4gICAgYm9yZGVyQ29sb3I6IHRoZW1lLmNvbG9ycy5mYWRlZFRleHQxMCxcbiAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoZW1lLmNvbG9ycy50cmFuc3BhcmVudCxcbiAgICBjb2xvcjogdGhlbWUuY29sb3JzLmZhZGVkVGV4dDQwLFxuICAgIGN1cnNvcjogXCJub3QtYWxsb3dlZFwiLFxuICB9LFxufSkpXG5cbmV4cG9ydCBjb25zdCBTdHlsZWRTZWNvbmRhcnlCdXR0b24gPSBzdHlsZWQoXG4gIFN0eWxlZEJhc2VCdXR0b25cbik8UmVxdWlyZWRCYXNlQnV0dG9uUHJvcHM+KCh7IHRoZW1lIH0pID0+ICh7XG4gIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLmxpZ2h0ZW5lZEJnMDUsXG4gIGJvcmRlcjogYDFweCBzb2xpZCAke3RoZW1lLmNvbG9ycy5mYWRlZFRleHQxMH1gLFxuICBcIiY6aG92ZXJcIjoge1xuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICBjb2xvcjogdGhlbWUuY29sb3JzLnByaW1hcnksXG4gIH0sXG4gIFwiJjphY3RpdmVcIjoge1xuICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMud2hpdGUsXG4gICAgYm9yZGVyQ29sb3I6IHRoZW1lLmNvbG9ycy5wcmltYXJ5LFxuICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnByaW1hcnksXG4gIH0sXG4gIFwiJjpmb2N1czpub3QoOmFjdGl2ZSlcIjoge1xuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICBjb2xvcjogdGhlbWUuY29sb3JzLnByaW1hcnksXG4gIH0sXG4gIFwiJjpkaXNhYmxlZCwgJjpkaXNhYmxlZDpob3ZlciwgJjpkaXNhYmxlZDphY3RpdmVcIjoge1xuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMuZmFkZWRUZXh0MTAsXG4gICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gICAgY29sb3I6IHRoZW1lLmNvbG9ycy5mYWRlZFRleHQ0MCxcbiAgICBjdXJzb3I6IFwibm90LWFsbG93ZWRcIixcbiAgfSxcbn0pKVxuXG5leHBvcnQgY29uc3QgU3R5bGVkVGVydGlhcnlCdXR0b24gPSBzdHlsZWQoXG4gIFN0eWxlZEJhc2VCdXR0b25cbik8UmVxdWlyZWRCYXNlQnV0dG9uUHJvcHM+KCh7IHRoZW1lIH0pID0+ICh7XG4gIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICBib3JkZXI6IGAxcHggc29saWQgJHt0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnR9YCxcbiAgXCImOmhvdmVyXCI6IHtcbiAgICBib3JkZXJDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgfSxcbiAgXCImOmFjdGl2ZVwiOiB7XG4gICAgY29sb3I6IHRoZW1lLmNvbG9ycy5wcmltYXJ5LFxuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gIH0sXG4gIFwiJjpmb2N1czpub3QoOmFjdGl2ZSlcIjoge1xuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gICAgY29sb3I6IHRoZW1lLmNvbG9ycy5wcmltYXJ5LFxuICB9LFxuICBcIiY6ZGlzYWJsZWQsICY6ZGlzYWJsZWQ6aG92ZXIsICY6ZGlzYWJsZWQ6YWN0aXZlXCI6IHtcbiAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoZW1lLmNvbG9ycy5saWdodEdyYXksXG4gICAgYm9yZGVyQ29sb3I6IHRoZW1lLmNvbG9ycy50cmFuc3BhcmVudCxcbiAgICBjb2xvcjogdGhlbWUuY29sb3JzLmdyYXksXG4gIH0sXG59KSlcblxuZXhwb3J0IGNvbnN0IFN0eWxlZExpbmtCdXR0b24gPSBzdHlsZWQoXG4gIFN0eWxlZEJhc2VCdXR0b25cbik8UmVxdWlyZWRCYXNlQnV0dG9uUHJvcHM+KCh7IHRoZW1lIH0pID0+ICh7XG4gIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICBwYWRkaW5nOiAwLFxuICBib3JkZXI6IFwibm9uZVwiLFxuICBjb2xvcjogdGhlbWUuY29sb3JzLnByaW1hcnksXG4gIFwiJjpob3ZlclwiOiB7XG4gICAgdGV4dERlY29yYXRpb246IFwidW5kZXJsaW5lXCIsXG4gIH0sXG4gIFwiJjphY3RpdmVcIjoge1xuICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICB0ZXh0RGVjb3JhdGlvbjogXCJ1bmRlcmxpbmVcIixcbiAgfSxcbiAgXCImOmRpc2FibGVkLCAmOmRpc2FibGVkOmhvdmVyLCAmOmRpc2FibGVkOmFjdGl2ZVwiOiB7XG4gICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMubGlnaHRHcmF5LFxuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gICAgY29sb3I6IHRoZW1lLmNvbG9ycy5ncmF5LFxuICB9LFxufSkpXG5cbmV4cG9ydCBjb25zdCBTdHlsZWRNaW5pbWFsQnV0dG9uID0gc3R5bGVkKFxuICBTdHlsZWRCYXNlQnV0dG9uXG4pPFJlcXVpcmVkQmFzZUJ1dHRvblByb3BzPigoeyB0aGVtZSB9KSA9PiAoe1xuICBiYWNrZ3JvdW5kQ29sb3I6IHRoZW1lLmNvbG9ycy50cmFuc3BhcmVudCxcbiAgYm9yZGVyOiBcIm5vbmVcIixcbiAgYm94U2hhZG93OiBcIm5vbmVcIixcbiAgcGFkZGluZzogMCxcbiAgXCImOmhvdmVyLCAmOmFjdGl2ZSwgJjpmb2N1cy12aXNpYmxlXCI6IHtcbiAgICBjb2xvcjogdGhlbWUuY29sb3JzLnByaW1hcnksXG4gIH0sXG59KSlcblxuZXhwb3J0IGNvbnN0IFN0eWxlZFByaW1hcnlGb3JtU3VibWl0QnV0dG9uID1cbiAgc3R5bGVkKFN0eWxlZFByaW1hcnlCdXR0b24pPFJlcXVpcmVkQmFzZUJ1dHRvblByb3BzPigpXG5cbmV4cG9ydCBjb25zdCBTdHlsZWRTZWNvbmRhcnlGb3JtU3VibWl0QnV0dG9uID0gc3R5bGVkKFxuICBTdHlsZWRTZWNvbmRhcnlCdXR0b25cbik8UmVxdWlyZWRCYXNlQnV0dG9uUHJvcHM+KClcblxuZXhwb3J0IGNvbnN0IFN0eWxlZEljb25CdXR0b24gPSBzdHlsZWQoXG4gIFN0eWxlZEJhc2VCdXR0b25cbik8UmVxdWlyZWRCYXNlQnV0dG9uUHJvcHM+KCh7IHNpemUsIHRoZW1lIH0pID0+IHtcbiAgY29uc3QgaWNvblBhZGRpbmc6IFJlY29yZDxCYXNlQnV0dG9uU2l6ZSwgc3RyaW5nPiA9IHtcbiAgICBbQmFzZUJ1dHRvblNpemUuWFNNQUxMXTogdGhlbWUuc3BhY2luZy50aHJlZVhTLFxuICAgIFtCYXNlQnV0dG9uU2l6ZS5TTUFMTF06IHRoZW1lLnNwYWNpbmcudHdvWFMsXG4gICAgW0Jhc2VCdXR0b25TaXplLk1FRElVTV06IHRoZW1lLnNwYWNpbmcubWQsXG4gICAgW0Jhc2VCdXR0b25TaXplLkxBUkdFXTogdGhlbWUuc3BhY2luZy5sZyxcbiAgfVxuICByZXR1cm4ge1xuICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICAgIGJvcmRlcjogYDFweCBzb2xpZCAke3RoZW1lLmNvbG9ycy50cmFuc3BhcmVudH1gLFxuICAgIHBhZGRpbmc6IGljb25QYWRkaW5nW3NpemVdLFxuXG4gICAgXCImOmhvdmVyXCI6IHtcbiAgICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICB9LFxuICAgIFwiJjphY3RpdmVcIjoge1xuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMud2hpdGUsXG4gICAgfSxcbiAgICBcIiY6bm90KDphY3RpdmUpXCI6IHtcbiAgICAgIGJveFNoYWRvdzogXCJub25lXCIsXG4gICAgfSxcbiAgICBcIiY6ZGlzYWJsZWQsICY6ZGlzYWJsZWQ6aG92ZXIsICY6ZGlzYWJsZWQ6YWN0aXZlXCI6IHtcbiAgICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLmxpZ2h0R3JheSxcbiAgICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gICAgICBjb2xvcjogdGhlbWUuY29sb3JzLmdyYXksXG4gICAgfSxcbiAgfVxufSlcblxuZXhwb3J0IGNvbnN0IFN0eWxlZEhlYWRlckJ1dHRvbiA9IHN0eWxlZChcbiAgU3R5bGVkQmFzZUJ1dHRvblxuKTxSZXF1aXJlZEJhc2VCdXR0b25Qcm9wcz4oKHsgdGhlbWUgfSkgPT4ge1xuICByZXR1cm4ge1xuICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICAgIGJvcmRlcjogXCJub25lXCIsXG4gICAgcGFkZGluZzogdGhlbWUuc3BhY2luZy5zbSxcbiAgICBmb250U2l6ZTogdGhlbWUuZm9udFNpemVzLnNtLFxuICAgIG1hcmdpbkxlZnQ6IHRoZW1lLnNwYWNpbmcudGhyZWVYUyxcbiAgICBtYXJnaW5SaWdodDogdGhlbWUuc3BhY2luZy50aHJlZVhTLFxuICAgIGxpbmVIZWlnaHQ6IDEsXG5cbiAgICAvLyBPdmVycmlkZSBidXR0b25zIG1pbiB3aWR0aCBhbmQgaGVpZ2h0LCB0byBlbnN1cmUgdGhlIGhvdmVyIHN0YXRlIGZvciBpY29uIGJ1dHRvbnMgb24gdGhlIGhlYWRlciBpcyBzcXVhcmVcbiAgICBtaW5XaWR0aDogdGhlbWUuc3BhY2luZy50aHJlZVhMLFxuICAgIG1pbkhlaWdodDogdGhlbWUuc3BhY2luZy50aHJlZVhMLFxuXG4gICAgXCImOmZvY3VzXCI6IHtcbiAgICAgIG91dGxpbmU6IFwibm9uZVwiLFxuICAgIH0sXG4gICAgXCImOmZvY3VzLXZpc2libGVcIjoge1xuICAgICAgYm94U2hhZG93OiBgMCAwIDAgMC4ycmVtICR7dHJhbnNwYXJlbnRpemUodGhlbWUuY29sb3JzLmdyYXk5MCwgMC44KX1gLFxuICAgIH0sXG4gICAgXCImOmhvdmVyXCI6IHtcbiAgICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLmRhcmtlbmVkQmdNaXgyNSxcbiAgICB9LFxuICAgIFwiJjpkaXNhYmxlZCwgJjpkaXNhYmxlZDpob3ZlciwgJjpkaXNhYmxlZDphY3RpdmVcIjoge1xuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMubGlnaHRHcmF5LFxuICAgICAgYm9yZGVyQ29sb3I6IHRoZW1lLmNvbG9ycy50cmFuc3BhcmVudCxcbiAgICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMuZ3JheSxcbiAgICB9LFxuICB9XG59KVxuXG4vLyBUYWtlIG91dCBwYWRkaW5nIGZvciB0aGlzIHNwZWNpZmljIGJ1dHRvbiwgc28gd2UgY2FuIGVuc3VyZSBpdCdzIDMyeDMycHggbGlrZSBvdGhlciBidXR0b25zIGluIENvbW11bml0eSBDbG91ZFxuZXhwb3J0IGNvbnN0IFN0eWxlZEhlYWRlck5vUGFkZGluZ0J1dHRvbiA9IHN0eWxlZChcbiAgU3R5bGVkSGVhZGVyQnV0dG9uXG4pPFJlcXVpcmVkQmFzZUJ1dHRvblByb3BzPigoKSA9PiB7XG4gIHJldHVybiB7XG4gICAgcGFkZGluZzogMCxcbiAgfVxufSlcblxuZXhwb3J0IGNvbnN0IFN0eWxlZEJvcmRlcmxlc3NJY29uQnV0dG9uID0gc3R5bGVkKFxuICBTdHlsZWRCYXNlQnV0dG9uXG4pPFJlcXVpcmVkQmFzZUJ1dHRvblByb3BzPigoeyBzaXplLCB0aGVtZSB9KSA9PiB7XG4gIGNvbnN0IGljb25QYWRkaW5nOiBSZWNvcmQ8QmFzZUJ1dHRvblNpemUsIHN0cmluZz4gPSB7XG4gICAgW0Jhc2VCdXR0b25TaXplLlhTTUFMTF06IHRoZW1lLnNwYWNpbmcudGhyZWVYUyxcbiAgICBbQmFzZUJ1dHRvblNpemUuU01BTExdOiB0aGVtZS5zcGFjaW5nLnR3b1hTLFxuICAgIFtCYXNlQnV0dG9uU2l6ZS5NRURJVU1dOiB0aGVtZS5zcGFjaW5nLm1kLFxuICAgIFtCYXNlQnV0dG9uU2l6ZS5MQVJHRV06IHRoZW1lLnNwYWNpbmcubGcsXG4gIH1cblxuICByZXR1cm4ge1xuICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICAgIGJvcmRlcjogYDFweCBzb2xpZCAke3RoZW1lLmNvbG9ycy50cmFuc3BhcmVudH1gLFxuICAgIHBhZGRpbmc6IGljb25QYWRkaW5nW3NpemVdLFxuXG4gICAgXCImOmZvY3VzXCI6IHtcbiAgICAgIGJveFNoYWRvdzogXCJub25lXCIsXG4gICAgICBvdXRsaW5lOiBcIm5vbmVcIixcbiAgICB9LFxuICAgIFwiJjpkaXNhYmxlZCwgJjpkaXNhYmxlZDpob3ZlciwgJjpkaXNhYmxlZDphY3RpdmVcIjoge1xuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMubGlnaHRHcmF5LFxuICAgICAgYm9yZGVyQ29sb3I6IHRoZW1lLmNvbG9ycy50cmFuc3BhcmVudCxcbiAgICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMuZ3JheSxcbiAgICB9LFxuICB9XG59KVxuXG5leHBvcnQgY29uc3QgU3R5bGVkVG9vbHRpcE5vcm1hbCA9IHN0eWxlZC5kaXYoKHsgdGhlbWUgfSkgPT4gKHtcbiAgZGlzcGxheTogXCJibG9ja1wiLFxuICBbYEBtZWRpYSAobWF4LXdpZHRoOiAke3RoZW1lLmJyZWFrcG9pbnRzLnNtfSlgXToge1xuICAgIGRpc3BsYXk6IFwibm9uZVwiLFxuICB9LFxufSkpXG5cbmV4cG9ydCBjb25zdCBTdHlsZWRUb29sdGlwTW9iaWxlID0gc3R5bGVkLmRpdigoeyB0aGVtZSB9KSA9PiAoe1xuICBkaXNwbGF5OiBcIm5vbmVcIixcbiAgW2BAbWVkaWEgKG1heC13aWR0aDogJHt0aGVtZS5icmVha3BvaW50cy5zbX0pYF06IHtcbiAgICBkaXNwbGF5OiBcImJsb2NrXCIsXG4gIH0sXG59KSlcbiJdfQ== */", + "map": "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0eWxlZC1jb21wb25lbnRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQStIcUMiLCJmaWxlIjoic3R5bGVkLWNvbXBvbmVudHMudHMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENvcHlyaWdodCAoYykgU3RyZWFtbGl0IEluYy4gKDIwMTgtMjAyMikgU25vd2ZsYWtlIEluYy4gKDIwMjIpXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IE1vdXNlRXZlbnQsIFJlYWN0Tm9kZSB9IGZyb20gXCJyZWFjdFwiXG5pbXBvcnQgc3R5bGVkLCB7IENTU09iamVjdCB9IGZyb20gXCJAZW1vdGlvbi9zdHlsZWRcIlxuaW1wb3J0IHsgZGFya2VuLCB0cmFuc3BhcmVudGl6ZSB9IGZyb20gXCJjb2xvcjJrXCJcbmltcG9ydCB7IEVtb3Rpb25UaGVtZSB9IGZyb20gXCJAc3RyZWFtbGl0L2xpYi9zcmMvdGhlbWVcIlxuXG5leHBvcnQgZW51bSBCYXNlQnV0dG9uS2luZCB7XG4gIFBSSU1BUlkgPSBcInByaW1hcnlcIixcbiAgU0VDT05EQVJZID0gXCJzZWNvbmRhcnlcIixcbiAgVEVSVElBUlkgPSBcInRlcnRpYXJ5XCIsXG4gIExJTksgPSBcImxpbmtcIixcbiAgSUNPTiA9IFwiaWNvblwiLFxuICBCT1JERVJMRVNTX0lDT04gPSBcImJvcmRlcmxlc3NJY29uXCIsXG4gIE1JTklNQUwgPSBcIm1pbmltYWxcIixcbiAgUFJJTUFSWV9GT1JNX1NVQk1JVCA9IFwicHJpbWFyeUZvcm1TdWJtaXRcIixcbiAgU0VDT05EQVJZX0ZPUk1fU1VCTUlUID0gXCJzZWNvbmRhcnlGb3JtU3VibWl0XCIsXG4gIEhFQURFUl9CVVRUT04gPSBcImhlYWRlclwiLFxuICBIRUFERVJfTk9fUEFERElORyA9IFwiaGVhZGVyTm9QYWRkaW5nXCIsXG59XG5cbmV4cG9ydCBlbnVtIEJhc2VCdXR0b25TaXplIHtcbiAgWFNNQUxMID0gXCJ4c21hbGxcIixcbiAgU01BTEwgPSBcInNtYWxsXCIsXG4gIE1FRElVTSA9IFwibWVkaXVtXCIsXG4gIExBUkdFID0gXCJsYXJnZVwiLFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJhc2VCdXR0b25Qcm9wcyB7XG4gIGtpbmQ6IEJhc2VCdXR0b25LaW5kXG4gIHNpemU/OiBCYXNlQnV0dG9uU2l6ZVxuICBvbkNsaWNrPzogKGV2ZW50OiBNb3VzZUV2ZW50PEhUTUxCdXR0b25FbGVtZW50PikgPT4gYW55XG4gIGRpc2FibGVkPzogYm9vbGVhblxuICAvLyBJZiB0cnVlIG9yIG51bWJlciwgdGhlIGJ1dHRvbiBzaG91bGQgdGFrZSB1cCBjb250YWluZXIncyBmdWxsIHdpZHRoXG4gIGZsdWlkV2lkdGg/OiBib29sZWFuIHwgbnVtYmVyXG4gIGNoaWxkcmVuOiBSZWFjdE5vZGVcbiAgYXV0b0ZvY3VzPzogYm9vbGVhblxufVxuXG50eXBlIFJlcXVpcmVkQmFzZUJ1dHRvblByb3BzID0gUmVxdWlyZWQ8QmFzZUJ1dHRvblByb3BzPlxuXG5mdW5jdGlvbiBnZXRTaXplU3R5bGUoc2l6ZTogQmFzZUJ1dHRvblNpemUsIHRoZW1lOiBFbW90aW9uVGhlbWUpOiBDU1NPYmplY3Qge1xuICBzd2l0Y2ggKHNpemUpIHtcbiAgICBjYXNlIEJhc2VCdXR0b25TaXplLlhTTUFMTDpcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHBhZGRpbmc6IGAke3RoZW1lLnNwYWNpbmcudHdvWFN9ICR7dGhlbWUuc3BhY2luZy5zbX1gLFxuICAgICAgICBmb250U2l6ZTogdGhlbWUuZm9udFNpemVzLnNtLFxuICAgICAgfVxuICAgIGNhc2UgQmFzZUJ1dHRvblNpemUuU01BTEw6XG4gICAgICByZXR1cm4ge1xuICAgICAgICBwYWRkaW5nOiBgJHt0aGVtZS5zcGFjaW5nLnR3b1hTfSAke3RoZW1lLnNwYWNpbmcubWR9YCxcbiAgICAgIH1cbiAgICBjYXNlIEJhc2VCdXR0b25TaXplLkxBUkdFOlxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcGFkZGluZzogYCR7dGhlbWUuc3BhY2luZy5tZH0gJHt0aGVtZS5zcGFjaW5nLm1kfWAsXG4gICAgICB9XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHBhZGRpbmc6IGAke3RoZW1lLnNwYWNpbmcueHN9ICR7dGhlbWUuc3BhY2luZy5tZH1gLFxuICAgICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBTdHlsZWRCYXNlQnV0dG9uID0gc3R5bGVkLmJ1dHRvbjxSZXF1aXJlZEJhc2VCdXR0b25Qcm9wcz4oXG4gICh7IGZsdWlkV2lkdGgsIHNpemUsIHRoZW1lIH0pID0+IHtcbiAgICBjb25zdCBidXR0b25XaWR0aCA9XG4gICAgICB0eXBlb2YgZmx1aWRXaWR0aCA9PSBcIm51bWJlclwiID8gYCR7Zmx1aWRXaWR0aH1weGAgOiBcIjEwMCVcIlxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGRpc3BsYXk6IFwiaW5saW5lLWZsZXhcIixcbiAgICAgIGFsaWduSXRlbXM6IFwiY2VudGVyXCIsXG4gICAgICBqdXN0aWZ5Q29udGVudDogXCJjZW50ZXJcIixcbiAgICAgIGZvbnRXZWlnaHQ6IHRoZW1lLmZvbnRXZWlnaHRzLm5vcm1hbCxcbiAgICAgIHBhZGRpbmc6IGAke3RoZW1lLnNwYWNpbmcueHN9ICR7dGhlbWUuc3BhY2luZy5tZH1gLFxuICAgICAgYm9yZGVyUmFkaXVzOiB0aGVtZS5yYWRpaS5sZyxcbiAgICAgIG1pbkhlaWdodDogXCIzOC40cHhcIixcbiAgICAgIG1hcmdpbjogMCxcbiAgICAgIGxpbmVIZWlnaHQ6IHRoZW1lLmxpbmVIZWlnaHRzLmJhc2UsXG4gICAgICBjb2xvcjogXCJpbmhlcml0XCIsXG4gICAgICB3aWR0aDogZmx1aWRXaWR0aCA/IGJ1dHRvbldpZHRoIDogXCJhdXRvXCIsXG4gICAgICB1c2VyU2VsZWN0OiBcIm5vbmVcIixcbiAgICAgIFwiJjpmb2N1c1wiOiB7XG4gICAgICAgIG91dGxpbmU6IFwibm9uZVwiLFxuICAgICAgfSxcbiAgICAgIFwiJjpmb2N1cy12aXNpYmxlXCI6IHtcbiAgICAgICAgYm94U2hhZG93OiBgMCAwIDAgMC4ycmVtICR7dHJhbnNwYXJlbnRpemUodGhlbWUuY29sb3JzLnByaW1hcnksIDAuNSl9YCxcbiAgICAgIH0sXG4gICAgICAuLi5nZXRTaXplU3R5bGUoc2l6ZSwgdGhlbWUpLFxuICAgIH1cbiAgfVxuKVxuXG5leHBvcnQgY29uc3QgU3R5bGVkUHJpbWFyeUJ1dHRvbiA9IHN0eWxlZChcbiAgU3R5bGVkQmFzZUJ1dHRvblxuKTxSZXF1aXJlZEJhc2VCdXR0b25Qcm9wcz4oKHsgdGhlbWUgfSkgPT4gKHtcbiAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgY29sb3I6IHRoZW1lLmNvbG9ycy53aGl0ZSxcbiAgYm9yZGVyOiBgMXB4IHNvbGlkICR7dGhlbWUuY29sb3JzLnByaW1hcnl9YCxcbiAgXCImOmhvdmVyXCI6IHtcbiAgICBiYWNrZ3JvdW5kQ29sb3I6IGRhcmtlbih0aGVtZS5jb2xvcnMucHJpbWFyeSwgMC4wNSksXG4gIH0sXG4gIFwiJjphY3RpdmVcIjoge1xuICAgIGJhY2tncm91bmRDb2xvcjogXCJ0cmFuc3BhcmVudFwiLFxuICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgfSxcbiAgXCImOmRpc2FibGVkLCAmOmRpc2FibGVkOmhvdmVyLCAmOmRpc2FibGVkOmFjdGl2ZVwiOiB7XG4gICAgYm9yZGVyQ29sb3I6IHRoZW1lLmNvbG9ycy5mYWRlZFRleHQxMCxcbiAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoZW1lLmNvbG9ycy50cmFuc3BhcmVudCxcbiAgICBjb2xvcjogdGhlbWUuY29sb3JzLmZhZGVkVGV4dDQwLFxuICAgIGN1cnNvcjogXCJub3QtYWxsb3dlZFwiLFxuICB9LFxufSkpXG5cbmV4cG9ydCBjb25zdCBTdHlsZWRTZWNvbmRhcnlCdXR0b24gPSBzdHlsZWQoXG4gIFN0eWxlZEJhc2VCdXR0b25cbik8UmVxdWlyZWRCYXNlQnV0dG9uUHJvcHM+KCh7IHRoZW1lIH0pID0+ICh7XG4gIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLmxpZ2h0ZW5lZEJnMDUsXG4gIGJvcmRlcjogYDFweCBzb2xpZCAke3RoZW1lLmNvbG9ycy5mYWRlZFRleHQxMH1gLFxuICBcIiY6aG92ZXJcIjoge1xuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICBjb2xvcjogdGhlbWUuY29sb3JzLnByaW1hcnksXG4gIH0sXG4gIFwiJjphY3RpdmVcIjoge1xuICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMud2hpdGUsXG4gICAgYm9yZGVyQ29sb3I6IHRoZW1lLmNvbG9ycy5wcmltYXJ5LFxuICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnByaW1hcnksXG4gIH0sXG4gIFwiJjpmb2N1czpub3QoOmFjdGl2ZSlcIjoge1xuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICBjb2xvcjogdGhlbWUuY29sb3JzLnByaW1hcnksXG4gIH0sXG4gIFwiJjpkaXNhYmxlZCwgJjpkaXNhYmxlZDpob3ZlciwgJjpkaXNhYmxlZDphY3RpdmVcIjoge1xuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMuZmFkZWRUZXh0MTAsXG4gICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gICAgY29sb3I6IHRoZW1lLmNvbG9ycy5mYWRlZFRleHQ0MCxcbiAgICBjdXJzb3I6IFwibm90LWFsbG93ZWRcIixcbiAgfSxcbn0pKVxuXG5leHBvcnQgY29uc3QgU3R5bGVkVGVydGlhcnlCdXR0b24gPSBzdHlsZWQoXG4gIFN0eWxlZEJhc2VCdXR0b25cbik8UmVxdWlyZWRCYXNlQnV0dG9uUHJvcHM+KCh7IHRoZW1lIH0pID0+ICh7XG4gIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICBib3JkZXI6IGAxcHggc29saWQgJHt0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnR9YCxcbiAgXCImOmhvdmVyXCI6IHtcbiAgICBib3JkZXJDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgfSxcbiAgXCImOmFjdGl2ZVwiOiB7XG4gICAgY29sb3I6IHRoZW1lLmNvbG9ycy5wcmltYXJ5LFxuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gIH0sXG4gIFwiJjpmb2N1czpub3QoOmFjdGl2ZSlcIjoge1xuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gICAgY29sb3I6IHRoZW1lLmNvbG9ycy5wcmltYXJ5LFxuICB9LFxuICBcIiY6ZGlzYWJsZWQsICY6ZGlzYWJsZWQ6aG92ZXIsICY6ZGlzYWJsZWQ6YWN0aXZlXCI6IHtcbiAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoZW1lLmNvbG9ycy5saWdodEdyYXksXG4gICAgYm9yZGVyQ29sb3I6IHRoZW1lLmNvbG9ycy50cmFuc3BhcmVudCxcbiAgICBjb2xvcjogdGhlbWUuY29sb3JzLmdyYXksXG4gIH0sXG59KSlcblxuZXhwb3J0IGNvbnN0IFN0eWxlZExpbmtCdXR0b24gPSBzdHlsZWQoXG4gIFN0eWxlZEJhc2VCdXR0b25cbik8UmVxdWlyZWRCYXNlQnV0dG9uUHJvcHM+KCh7IHRoZW1lIH0pID0+ICh7XG4gIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICBwYWRkaW5nOiAwLFxuICBib3JkZXI6IFwibm9uZVwiLFxuICBjb2xvcjogdGhlbWUuY29sb3JzLnByaW1hcnksXG4gIFwiJjpob3ZlclwiOiB7XG4gICAgdGV4dERlY29yYXRpb246IFwidW5kZXJsaW5lXCIsXG4gIH0sXG4gIFwiJjphY3RpdmVcIjoge1xuICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICB0ZXh0RGVjb3JhdGlvbjogXCJ1bmRlcmxpbmVcIixcbiAgfSxcbiAgXCImOmRpc2FibGVkLCAmOmRpc2FibGVkOmhvdmVyLCAmOmRpc2FibGVkOmFjdGl2ZVwiOiB7XG4gICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMubGlnaHRHcmF5LFxuICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gICAgY29sb3I6IHRoZW1lLmNvbG9ycy5ncmF5LFxuICB9LFxufSkpXG5cbmV4cG9ydCBjb25zdCBTdHlsZWRNaW5pbWFsQnV0dG9uID0gc3R5bGVkKFxuICBTdHlsZWRCYXNlQnV0dG9uXG4pPFJlcXVpcmVkQmFzZUJ1dHRvblByb3BzPigoeyB0aGVtZSB9KSA9PiAoe1xuICBiYWNrZ3JvdW5kQ29sb3I6IHRoZW1lLmNvbG9ycy50cmFuc3BhcmVudCxcbiAgYm9yZGVyOiBcIm5vbmVcIixcbiAgYm94U2hhZG93OiBcIm5vbmVcIixcbiAgcGFkZGluZzogMCxcbiAgXCImOmhvdmVyLCAmOmFjdGl2ZSwgJjpmb2N1cy12aXNpYmxlXCI6IHtcbiAgICBjb2xvcjogdGhlbWUuY29sb3JzLnByaW1hcnksXG4gIH0sXG59KSlcblxuZXhwb3J0IGNvbnN0IFN0eWxlZFByaW1hcnlGb3JtU3VibWl0QnV0dG9uID1cbiAgc3R5bGVkKFN0eWxlZFByaW1hcnlCdXR0b24pPFJlcXVpcmVkQmFzZUJ1dHRvblByb3BzPigpXG5cbmV4cG9ydCBjb25zdCBTdHlsZWRTZWNvbmRhcnlGb3JtU3VibWl0QnV0dG9uID0gc3R5bGVkKFxuICBTdHlsZWRTZWNvbmRhcnlCdXR0b25cbik8UmVxdWlyZWRCYXNlQnV0dG9uUHJvcHM+KClcblxuZXhwb3J0IGNvbnN0IFN0eWxlZEljb25CdXR0b24gPSBzdHlsZWQoXG4gIFN0eWxlZEJhc2VCdXR0b25cbik8UmVxdWlyZWRCYXNlQnV0dG9uUHJvcHM+KCh7IHNpemUsIHRoZW1lIH0pID0+IHtcbiAgY29uc3QgaWNvblBhZGRpbmc6IFJlY29yZDxCYXNlQnV0dG9uU2l6ZSwgc3RyaW5nPiA9IHtcbiAgICBbQmFzZUJ1dHRvblNpemUuWFNNQUxMXTogdGhlbWUuc3BhY2luZy50aHJlZVhTLFxuICAgIFtCYXNlQnV0dG9uU2l6ZS5TTUFMTF06IHRoZW1lLnNwYWNpbmcudHdvWFMsXG4gICAgW0Jhc2VCdXR0b25TaXplLk1FRElVTV06IHRoZW1lLnNwYWNpbmcubWQsXG4gICAgW0Jhc2VCdXR0b25TaXplLkxBUkdFXTogdGhlbWUuc3BhY2luZy5sZyxcbiAgfVxuICByZXR1cm4ge1xuICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICAgIGJvcmRlcjogYDFweCBzb2xpZCAke3RoZW1lLmNvbG9ycy50cmFuc3BhcmVudH1gLFxuICAgIHBhZGRpbmc6IGljb25QYWRkaW5nW3NpemVdLFxuXG4gICAgXCImOmhvdmVyXCI6IHtcbiAgICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICB9LFxuICAgIFwiJjphY3RpdmVcIjoge1xuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMucHJpbWFyeSxcbiAgICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMud2hpdGUsXG4gICAgfSxcbiAgICBcIiY6bm90KDphY3RpdmUpXCI6IHtcbiAgICAgIGJveFNoYWRvdzogXCJub25lXCIsXG4gICAgfSxcbiAgICBcIiY6ZGlzYWJsZWQsICY6ZGlzYWJsZWQ6aG92ZXIsICY6ZGlzYWJsZWQ6YWN0aXZlXCI6IHtcbiAgICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLmxpZ2h0R3JheSxcbiAgICAgIGJvcmRlckNvbG9yOiB0aGVtZS5jb2xvcnMudHJhbnNwYXJlbnQsXG4gICAgICBjb2xvcjogdGhlbWUuY29sb3JzLmdyYXksXG4gICAgfSxcbiAgfVxufSlcblxuZXhwb3J0IGNvbnN0IFN0eWxlZEhlYWRlckJ1dHRvbiA9IHN0eWxlZChcbiAgU3R5bGVkQmFzZUJ1dHRvblxuKTxSZXF1aXJlZEJhc2VCdXR0b25Qcm9wcz4oKHsgdGhlbWUgfSkgPT4ge1xuICByZXR1cm4ge1xuICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICAgIGJvcmRlcjogXCJub25lXCIsXG4gICAgcGFkZGluZzogdGhlbWUuc3BhY2luZy5zbSxcbiAgICBmb250U2l6ZTogdGhlbWUuZm9udFNpemVzLnNtLFxuICAgIG1hcmdpbkxlZnQ6IHRoZW1lLnNwYWNpbmcudGhyZWVYUyxcbiAgICBtYXJnaW5SaWdodDogdGhlbWUuc3BhY2luZy50aHJlZVhTLFxuICAgIGxpbmVIZWlnaHQ6IDEsXG5cbiAgICAvLyBPdmVycmlkZSBidXR0b25zIG1pbiB3aWR0aCBhbmQgaGVpZ2h0LCB0byBlbnN1cmUgdGhlIGhvdmVyIHN0YXRlIGZvciBpY29uIGJ1dHRvbnMgb24gdGhlIGhlYWRlciBpcyBzcXVhcmVcbiAgICBtaW5XaWR0aDogdGhlbWUuc3BhY2luZy50aHJlZVhMLFxuICAgIG1pbkhlaWdodDogdGhlbWUuc3BhY2luZy50aHJlZVhMLFxuXG4gICAgXCImOmZvY3VzXCI6IHtcbiAgICAgIG91dGxpbmU6IFwibm9uZVwiLFxuICAgIH0sXG4gICAgXCImOmZvY3VzLXZpc2libGVcIjoge1xuICAgICAgYm94U2hhZG93OiBgMCAwIDAgMC4ycmVtICR7dHJhbnNwYXJlbnRpemUodGhlbWUuY29sb3JzLmdyYXk5MCwgMC44KX1gLFxuICAgIH0sXG4gICAgXCImOmhvdmVyXCI6IHtcbiAgICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLmRhcmtlbmVkQmdNaXgyNSxcbiAgICB9LFxuICAgIFwiJjpkaXNhYmxlZCwgJjpkaXNhYmxlZDpob3ZlciwgJjpkaXNhYmxlZDphY3RpdmVcIjoge1xuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMubGlnaHRHcmF5LFxuICAgICAgYm9yZGVyQ29sb3I6IHRoZW1lLmNvbG9ycy50cmFuc3BhcmVudCxcbiAgICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMuZ3JheSxcbiAgICB9LFxuICB9XG59KVxuXG4vLyBUYWtlIG91dCBwYWRkaW5nIGZvciB0aGlzIHNwZWNpZmljIGJ1dHRvbiwgc28gd2UgY2FuIGVuc3VyZSBpdCdzIDMyeDMycHggbGlrZSBvdGhlciBidXR0b25zIGluIENvbW11bml0eSBDbG91ZFxuZXhwb3J0IGNvbnN0IFN0eWxlZEhlYWRlck5vUGFkZGluZ0J1dHRvbiA9IHN0eWxlZChcbiAgU3R5bGVkSGVhZGVyQnV0dG9uXG4pPFJlcXVpcmVkQmFzZUJ1dHRvblByb3BzPigoKSA9PiB7XG4gIHJldHVybiB7XG4gICAgcGFkZGluZzogMCxcbiAgfVxufSlcblxuZXhwb3J0IGNvbnN0IFN0eWxlZEJvcmRlcmxlc3NJY29uQnV0dG9uID0gc3R5bGVkKFxuICBTdHlsZWRCYXNlQnV0dG9uXG4pPFJlcXVpcmVkQmFzZUJ1dHRvblByb3BzPigoeyBzaXplLCB0aGVtZSB9KSA9PiB7XG4gIGNvbnN0IGljb25QYWRkaW5nOiBSZWNvcmQ8QmFzZUJ1dHRvblNpemUsIHN0cmluZz4gPSB7XG4gICAgW0Jhc2VCdXR0b25TaXplLlhTTUFMTF06IHRoZW1lLnNwYWNpbmcudGhyZWVYUyxcbiAgICBbQmFzZUJ1dHRvblNpemUuU01BTExdOiB0aGVtZS5zcGFjaW5nLnR3b1hTLFxuICAgIFtCYXNlQnV0dG9uU2l6ZS5NRURJVU1dOiB0aGVtZS5zcGFjaW5nLm1kLFxuICAgIFtCYXNlQnV0dG9uU2l6ZS5MQVJHRV06IHRoZW1lLnNwYWNpbmcubGcsXG4gIH1cblxuICByZXR1cm4ge1xuICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUuY29sb3JzLnRyYW5zcGFyZW50LFxuICAgIGJvcmRlcjogYDFweCBzb2xpZCAke3RoZW1lLmNvbG9ycy50cmFuc3BhcmVudH1gLFxuICAgIHBhZGRpbmc6IGljb25QYWRkaW5nW3NpemVdLFxuXG4gICAgXCImOmZvY3VzXCI6IHtcbiAgICAgIGJveFNoYWRvdzogXCJub25lXCIsXG4gICAgICBvdXRsaW5lOiBcIm5vbmVcIixcbiAgICB9LFxuICAgIFwiJjpkaXNhYmxlZCwgJjpkaXNhYmxlZDpob3ZlciwgJjpkaXNhYmxlZDphY3RpdmVcIjoge1xuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5jb2xvcnMubGlnaHRHcmF5LFxuICAgICAgYm9yZGVyQ29sb3I6IHRoZW1lLmNvbG9ycy50cmFuc3BhcmVudCxcbiAgICAgIGNvbG9yOiB0aGVtZS5jb2xvcnMuZ3JheSxcbiAgICB9LFxuICB9XG59KVxuXG5leHBvcnQgY29uc3QgU3R5bGVkVG9vbHRpcE5vcm1hbCA9IHN0eWxlZC5kaXYoKHsgdGhlbWUgfSkgPT4gKHtcbiAgZGlzcGxheTogXCJibG9ja1wiLFxuICBbYEBtZWRpYSAobWF4LXdpZHRoOiAke3RoZW1lLmJyZWFrcG9pbnRzLnNtfSlgXToge1xuICAgIGRpc3BsYXk6IFwibm9uZVwiLFxuICB9LFxufSkpXG5cbmV4cG9ydCBjb25zdCBTdHlsZWRUb29sdGlwTW9iaWxlID0gc3R5bGVkLmRpdigoeyB0aGVtZSB9KSA9PiAoe1xuICBkaXNwbGF5OiBcIm5vbmVcIixcbiAgW2BAbWVkaWEgKG1heC13aWR0aDogJHt0aGVtZS5icmVha3BvaW50cy5zbX0pYF06IHtcbiAgICBkaXNwbGF5OiBcImJsb2NrXCIsXG4gIH0sXG59KSlcbiJdfQ== */", "name": "1v0fdp-StyledBaseButton-StyledSecondaryButton", "next": undefined, "styles": "label:StyledBaseButton;display:inline-flex;align-items:center;justify-content:center;font-weight:400;padding:0.375rem 0.75rem;border-radius:0.5rem;min-height:38.4px;margin:0;line-height:1.6;color:inherit;width:auto;user-select:none;&:focus{outline:none;}&:focus-visible{box-shadow:0 0 0 0.2rem rgba(255, 75, 75, 0.5);}label:StyledSecondaryButton;background-color:hsla(0, 0%, 100%, 1);border:1px solid rgba(49, 51, 63, 0.2);&:hover{border-color:#ff4b4b;color:#ff4b4b;}&:active{color:#ffffff;border-color:#ff4b4b;background-color:#ff4b4b;}&:focus:not(:active){border-color:#ff4b4b;color:#ff4b4b;}&:disabled, &:disabled:hover, &:disabled:active{border-color:rgba(49, 51, 63, 0.2);background-color:transparent;color:rgba(49, 51, 63, 0.4);cursor:not-allowed;}", @@ -262,6 +263,7 @@ exports[`StreamlitDialog renders secondary dialog buttons properly 1`] = `