From 5dbbd14aa666bbaadc314dadb07e87e0fa879abe Mon Sep 17 00:00:00 2001 From: mitmproxy release bot Date: Sun, 12 Apr 2026 21:43:57 +0000 Subject: [PATCH 01/30] reopen main for development --- mitmproxy/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mitmproxy/version.py b/mitmproxy/version.py index 758fc02c73..e4842b025c 100644 --- a/mitmproxy/version.py +++ b/mitmproxy/version.py @@ -2,7 +2,7 @@ import subprocess import sys -VERSION = "12.2.2" +VERSION = "13.0.0.dev" MITMPROXY = "mitmproxy " + VERSION # Serialization format version. This is displayed nowhere, it just needs to be incremented by one From 58370ffb84f8fa0d048b1543d17e9c8e84cb5f6d Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Mon, 13 Apr 2026 19:36:34 +0200 Subject: [PATCH 02/30] Remove cooldown from pyOpenSSL and our own packages --- .github/dependabot.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index dd71ff578d..93e57441b1 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -14,6 +14,10 @@ updates: directory: "/" cooldown: default-days: 42 + exclude: + - "pyopenssl" + - "cryptography" + - "mitmproxy*" schedule: interval: "monthly" open-pull-requests-limit: 10 From 00ee4e97791d92493bd778791f2e852a3f1e7a1b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2026 19:58:32 +0200 Subject: [PATCH 03/30] Update pyopenssl requirement from <=25.3.0,>=24.3 to >=24.3,<=26.0.0 in the openssl group (#8180) * Update pyopenssl requirement in the openssl group Updates the requirements on [pyopenssl](https://github.com/pyca/pyopenssl) to permit the latest version. Updates `pyopenssl` to 26.0.0 - [Changelog](https://github.com/pyca/pyopenssl/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/pyopenssl/compare/24.3.0...26.0.0) --- updated-dependencies: - dependency-name: pyopenssl dependency-version: 26.0.0 dependency-type: direct:production dependency-group: openssl ... Signed-off-by: dependabot[bot] * [autofix.ci] apply automated fixes --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- uv.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 7ddc3b8346..9638a9b782 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,7 +47,7 @@ dependencies = [ "mitmproxy_rs>=0.12.6,<0.13", # relaxed upper bound here: we control this "msgpack>=1.0.0,<=1.1.2", "pydivert>=2.0.3,<=2.1.0; sys_platform == 'win32'", - "pyOpenSSL>=24.3,<=25.3.0", + "pyOpenSSL>=24.3,<=26.0.0", "pyparsing>=2.4.2,<=3.3.2", "pyperclip>=1.9.0,<=1.11.0", "ruamel.yaml>=0.18.10,<=0.19.1", diff --git a/uv.lock b/uv.lock index bce99ecaf4..685c5ba896 100644 --- a/uv.lock +++ b/uv.lock @@ -1046,7 +1046,7 @@ requires-dist = [ { name = "msgpack", specifier = ">=1.0.0,<=1.1.2" }, { name = "publicsuffix2", specifier = ">=2.20190812,<=2.20191221" }, { name = "pydivert", marker = "sys_platform == 'win32'", specifier = ">=2.0.3,<=2.1.0" }, - { name = "pyopenssl", specifier = ">=24.3,<=25.3.0" }, + { name = "pyopenssl", specifier = ">=24.3,<=26.0.0" }, { name = "pyparsing", specifier = ">=2.4.2,<=3.3.2" }, { name = "pyperclip", specifier = ">=1.9.0,<=1.11.0" }, { name = "ruamel-yaml", specifier = ">=0.18.10,<=0.19.1" }, From d332cbf19b1b7710cd53daf3bf1e8b1e97424734 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2026 19:58:51 +0200 Subject: [PATCH 04/30] Update asgiref requirement from <=3.11.0,>=3.2.10 to >=3.2.10,<=3.11.1 (#8181) * Update asgiref requirement from <=3.11.0,>=3.2.10 to >=3.2.10,<=3.11.1 Updates the requirements on [asgiref](https://github.com/django/asgiref) to permit the latest version. - [Changelog](https://github.com/django/asgiref/blob/main/CHANGELOG.txt) - [Commits](https://github.com/django/asgiref/compare/3.2.10...3.11.1) --- updated-dependencies: - dependency-name: asgiref dependency-version: 3.11.1 dependency-type: direct:production ... Signed-off-by: dependabot[bot] * [autofix.ci] apply automated fixes --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- uv.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 9638a9b782..36148c9766 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,7 +33,7 @@ classifiers = [ dependencies = [ "aioquic>=1.2.0,<=1.2.0", "argon2-cffi>=23.1.0,<=25.1.0", - "asgiref>=3.2.10,<=3.11.0", + "asgiref>=3.2.10,<=3.11.1", "bcrypt>=5.0.0,<=5.0.0", "Brotli>=1.0,<=1.2.0", "certifi>=2019.9.11", # no upper bound here to get latest CA bundle diff --git a/uv.lock b/uv.lock index 685c5ba896..4966bfd674 100644 --- a/uv.lock +++ b/uv.lock @@ -1031,7 +1031,7 @@ tox = [ requires-dist = [ { name = "aioquic", specifier = "<=1.2.0,>=1.2.0" }, { name = "argon2-cffi", specifier = ">=23.1.0,<=25.1.0" }, - { name = "asgiref", specifier = ">=3.2.10,<=3.11.0" }, + { name = "asgiref", specifier = ">=3.2.10,<=3.11.1" }, { name = "bcrypt", specifier = "<=5.0.0,>=5.0.0" }, { name = "brotli", specifier = ">=1.0,<=1.2.0" }, { name = "certifi", specifier = ">=2019.9.11" }, From c9b063bc6565840714a3008f264fc4e76112836e Mon Sep 17 00:00:00 2001 From: Vitaly Date: Sun, 19 Apr 2026 17:50:02 +0500 Subject: [PATCH 05/30] Use sys.executable instead of python3 in docs build script (#8183) * Use sys.executable instead of python3 in docs build script * [autofix.ci] apply automated fixes --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- docs/build.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/build.py b/docs/build.py index d8c3e944c2..2f0677f818 100755 --- a/docs/build.py +++ b/docs/build.py @@ -1,13 +1,16 @@ #!/usr/bin/env python3 import shutil import subprocess +import sys from pathlib import Path here = Path(__file__).parent for script in sorted((here / "scripts").glob("*.py")): print(f"Generating output for {script.name}...") - out = subprocess.check_output(["python3", script.absolute()], cwd=here, text=True) + out = subprocess.check_output( + [sys.executable, script.absolute()], cwd=here, text=True + ) if out: (here / "src" / "generated" / f"{script.stem}.html").write_text( out, encoding="utf8" From a8fbfc73fae5334868ca8a4238952572c3863083 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julio=20C=C3=A9sar=20Su=C3=A1stegui?= Date: Sat, 25 Apr 2026 03:24:59 -0600 Subject: [PATCH 06/30] fix: avoid IndexError in is_mostly_bin for short tails (#8196) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: avoid IndexError in is_mostly_bin for short tails `is_mostly_bin` looks up to 4 bytes past the 100-byte cutoff to find a clean UTF-8 character boundary. when the input is just over 100 bytes and starts with a continuation byte at index 100, the lookahead reads past the end of the buffer. cap the loop end at `len(s)`. existing fallback to `s[:100]` still covers the case where every byte in the lookahead window is a continuation byte. fixes #8188 * [autofix.ci] apply automated fixes --------- Co-authored-by: Julio César Suástegui Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- CHANGELOG.md | 3 +++ mitmproxy/utils/strutils.py | 2 +- test/mitmproxy/utils/test_strutils.py | 5 +++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 109f8e799c..713ea6c217 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ ## Unreleased: mitmproxy next +- Fix `IndexError` in `is_mostly_bin` when exporting flows to HAR with payloads + that have a UTF-8 continuation byte at the 100-byte cutoff. + ([#8196](https://github.com/mitmproxy/mitmproxy/pull/8196), @juliosuas) ## 12 April 2026: mitmproxy 12.2.2 diff --git a/mitmproxy/utils/strutils.py b/mitmproxy/utils/strutils.py index d7ab4a8e1a..9c5cb72731 100644 --- a/mitmproxy/utils/strutils.py +++ b/mitmproxy/utils/strutils.py @@ -132,7 +132,7 @@ def is_mostly_bin(s: bytes) -> bool: # Cut off at ~100 chars, but do it smartly so that if the input is UTF-8, we don't # chop a multibyte code point in half. if len(s) > 100: - for cut in range(100, 104): + for cut in range(100, min(104, len(s))): is_continuation_byte = (s[cut] >> 6) == 0b10 if not is_continuation_byte: # A new character starts here, so we cut off just before that. diff --git a/test/mitmproxy/utils/test_strutils.py b/test/mitmproxy/utils/test_strutils.py index 644e4ea0a1..0a3c9f95da 100644 --- a/test/mitmproxy/utils/test_strutils.py +++ b/test/mitmproxy/utils/test_strutils.py @@ -94,6 +94,11 @@ def test_is_mostly_bin(): assert not strutils.is_mostly_bin(b"aaaaa" + 50 * "𐍅".encode()) # only utf8 continuation chars assert strutils.is_mostly_bin(150 * b"\x80") + # regression #8188: payloads with len 101-103 and a continuation byte at + # the 100-byte cutoff used to raise IndexError because the lookahead loop + # ran past the end of the string. Should not raise. + for tail in (1, 2, 3): + strutils.is_mostly_bin(b"a" * 100 + b"\x80" * tail) def test_is_xml(): From ab470e5397d8cb73b3c44b9ee75834e6cda83ae7 Mon Sep 17 00:00:00 2001 From: Olexandr88 Date: Tue, 28 Apr 2026 21:25:50 +0300 Subject: [PATCH 07/30] Fix IP blocking and merge additional DoH blocklists (#8197) --- examples/contrib/block_dns_over_https.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/contrib/block_dns_over_https.py b/examples/contrib/block_dns_over_https.py index 63f0c723db..7178aa41e3 100644 --- a/examples/contrib/block_dns_over_https.py +++ b/examples/contrib/block_dns_over_https.py @@ -257,8 +257,8 @@ doh_hostnames, doh_ips = default_blocklist["hostnames"], default_blocklist["ips"] # convert to sets for faster lookups -doh_hostnames = set(doh_hostnames) -doh_ips = set(doh_ips) +doh_hostnames = set(doh_hostnames) | set(additional_doh_names) +doh_ips = set(doh_ips) | set(additional_doh_ips) def _has_dns_message_content_type(flow): @@ -335,7 +335,7 @@ def _requested_hostname_is_in_doh_blocklist(flow): :return: True if server's hostname is in DoH blocklist, otherwise False """ hostname = flow.request.host - ip = flow.server_conn.address + ip = flow.server_conn.address[0] return hostname in doh_hostnames or hostname in doh_ips or ip in doh_ips From 3dd268a9beb6349fdc11be7bf613fb0cf9a25859 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 9 May 2026 14:54:12 -0500 Subject: [PATCH 08/30] Bump upper bounds for cryptography and pyOpenSSL (#8219) * Bump upper bounds for cryptography and pyOpenSSL * [autofix.ci] apply automated fixes --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- pyproject.toml | 4 ++-- uv.lock | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 36148c9766..b538e11ce9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,7 +37,7 @@ dependencies = [ "bcrypt>=5.0.0,<=5.0.0", "Brotli>=1.0,<=1.2.0", "certifi>=2019.9.11", # no upper bound here to get latest CA bundle - "cryptography>=42.0,<=46.1", # relaxed upper bound here to get security fixes + "cryptography>=42.0,<=48.1", # relaxed upper bound here to get security fixes "flask>=3.0,<=3.1.3", "h11>=0.16.0,<=0.16.0", "h2>=4.3.0,<=4.3.0", @@ -47,7 +47,7 @@ dependencies = [ "mitmproxy_rs>=0.12.6,<0.13", # relaxed upper bound here: we control this "msgpack>=1.0.0,<=1.1.2", "pydivert>=2.0.3,<=2.1.0; sys_platform == 'win32'", - "pyOpenSSL>=24.3,<=26.0.0", + "pyOpenSSL>=24.3,<=27.0.0", "pyparsing>=2.4.2,<=3.3.2", "pyperclip>=1.9.0,<=1.11.0", "ruamel.yaml>=0.18.10,<=0.19.1", diff --git a/uv.lock b/uv.lock index 4966bfd674..ee51fcfd5c 100644 --- a/uv.lock +++ b/uv.lock @@ -1035,7 +1035,7 @@ requires-dist = [ { name = "bcrypt", specifier = "<=5.0.0,>=5.0.0" }, { name = "brotli", specifier = ">=1.0,<=1.2.0" }, { name = "certifi", specifier = ">=2019.9.11" }, - { name = "cryptography", specifier = ">=42.0,<=46.1" }, + { name = "cryptography", specifier = ">=42.0,<=48.1" }, { name = "flask", specifier = ">=3.0,<=3.1.3" }, { name = "h11", specifier = "<=0.16.0,>=0.16.0" }, { name = "h2", specifier = "<=4.3.0,>=4.3.0" }, @@ -1046,7 +1046,7 @@ requires-dist = [ { name = "msgpack", specifier = ">=1.0.0,<=1.1.2" }, { name = "publicsuffix2", specifier = ">=2.20190812,<=2.20191221" }, { name = "pydivert", marker = "sys_platform == 'win32'", specifier = ">=2.0.3,<=2.1.0" }, - { name = "pyopenssl", specifier = ">=24.3,<=26.0.0" }, + { name = "pyopenssl", specifier = ">=24.3,<=27.0.0" }, { name = "pyparsing", specifier = ">=2.4.2,<=3.3.2" }, { name = "pyperclip", specifier = ">=1.9.0,<=1.11.0" }, { name = "ruamel-yaml", specifier = ">=0.18.10,<=0.19.1" }, From 373d0b801fa2ee221804414e7873f9308a85305e Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 11 May 2026 08:17:08 -0400 Subject: [PATCH 09/30] upgrade the version of pyopenssl in the lockfile (#8223) follow up to #8219 --- uv.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/uv.lock b/uv.lock index ee51fcfd5c..fdfa96fa46 100644 --- a/uv.lock +++ b/uv.lock @@ -1440,15 +1440,15 @@ wheels = [ [[package]] name = "pyopenssl" -version = "25.3.0" +version = "26.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cryptography" }, { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/80/be/97b83a464498a79103036bc74d1038df4a7ef0e402cfaf4d5e113fb14759/pyopenssl-25.3.0.tar.gz", hash = "sha256:c981cb0a3fd84e8602d7afc209522773b94c1c2446a3c710a75b06fe1beae329", size = 184073, upload-time = "2025-09-17T00:32:21.037Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1a/51/27a5ad5f939d08f690a326ef9582cda7140555180db71695f6fb747d6a36/pyopenssl-26.2.0.tar.gz", hash = "sha256:8c6fcecd1183a7fc897548dfe388b0cdb7f37e018200d8409cf33959dbe35387", size = 182195, upload-time = "2026-05-04T23:06:09.72Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/81/ef2b1dfd1862567d573a4fdbc9f969067621764fbb74338496840a1d2977/pyopenssl-25.3.0-py3-none-any.whl", hash = "sha256:1fda6fc034d5e3d179d39e59c1895c9faeaf40a79de5fc4cbbfbe0d36f4a77b6", size = 57268, upload-time = "2025-09-17T00:32:19.474Z" }, + { url = "https://files.pythonhosted.org/packages/73/b8/a0e2790ae249d6f38c9f66de7a211621a7ab2650217bcd04e1262f578a56/pyopenssl-26.2.0-py3-none-any.whl", hash = "sha256:4f9d971bc5298b8bc1fab282803da04bf000c755d4ad9d99b52de2569ca19a70", size = 55823, upload-time = "2026-05-04T23:06:08.395Z" }, ] [[package]] From 680d2199e8fb5dd84509df6df4b1e5fa8396676c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 May 2026 15:43:00 +0200 Subject: [PATCH 10/30] Bump the github-actions group with 8 updates (#8209) Bumps the github-actions group with 8 updates: | Package | From | To | | --- | --- | --- | | [actions/setup-node](https://github.com/actions/setup-node) | `6` | `6.3.0` | | [apple-actions/import-codesign-certs](https://github.com/apple-actions/import-codesign-certs) | `6.0.0` | `6.1.0` | | [actions/cache](https://github.com/actions/cache) | `5` | `5.0.4` | | [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) | `3.7.0` | `4.0.0` | | [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) | `3.12.0` | `4.0.0` | | [docker/login-action](https://github.com/docker/login-action) | `3.7.0` | `4.0.0` | | [docker/metadata-action](https://github.com/docker/metadata-action) | `5.10.0` | `6.0.0` | | [docker/build-push-action](https://github.com/docker/build-push-action) | `6.19.2` | `7.0.0` | Updates `actions/setup-node` from 6 to 6.3.0 - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v6...v6.3.0) Updates `apple-actions/import-codesign-certs` from 6.0.0 to 6.1.0 - [Release notes](https://github.com/apple-actions/import-codesign-certs/releases) - [Commits](https://github.com/apple-actions/import-codesign-certs/compare/b610f78488812c1e56b20e6df63ec42d833f2d14...fe74d46e82474f87e1ba79832ad28a4013d0e33a) Updates `actions/cache` from 5 to 5.0.4 - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v5...v5.0.4) Updates `docker/setup-qemu-action` from 3.7.0 to 4.0.0 - [Release notes](https://github.com/docker/setup-qemu-action/releases) - [Commits](https://github.com/docker/setup-qemu-action/compare/c7c53464625b32c7a7e944ae62b3e17d2b600130...ce360397dd3f832beb865e1373c09c0e9f86d70a) Updates `docker/setup-buildx-action` from 3.12.0 to 4.0.0 - [Release notes](https://github.com/docker/setup-buildx-action/releases) - [Commits](https://github.com/docker/setup-buildx-action/compare/8d2750c68a42422c14e847fe6c8ac0403b4cbd6f...4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd) Updates `docker/login-action` from 3.7.0 to 4.0.0 - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/c94ce9fb468520275223c153574b00df6fe4bcc9...b45d80f862d83dbcd57f89517bcf500b2ab88fb2) Updates `docker/metadata-action` from 5.10.0 to 6.0.0 - [Release notes](https://github.com/docker/metadata-action/releases) - [Commits](https://github.com/docker/metadata-action/compare/c299e40c65443455700f0fdfc63efafe5b349051...030e881283bb7a6894de51c315a6bfe6a94e05cf) Updates `docker/build-push-action` from 6.19.2 to 7.0.0 - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/10e90e3645eae34f1e60eeb005ba3a3d33f178e8...d08e5c354a6adb9ed34480a06d141179aa583294) --- updated-dependencies: - dependency-name: actions/setup-node dependency-version: 6.3.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions - dependency-name: apple-actions/import-codesign-certs dependency-version: 6.1.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions - dependency-name: actions/cache dependency-version: 5.0.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions - dependency-name: docker/setup-qemu-action dependency-version: 4.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: github-actions - dependency-name: docker/setup-buildx-action dependency-version: 4.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: github-actions - dependency-name: docker/login-action dependency-version: 4.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: github-actions - dependency-name: docker/metadata-action dependency-version: 6.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: github-actions - dependency-name: docker/build-push-action dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: github-actions ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/autofix.yml | 2 +- .github/workflows/main.yml | 18 +++++++++--------- .github/workflows/release.yml | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/autofix.yml b/.github/workflows/autofix.yml index 8c30c96914..c46bcf6a2b 100644 --- a/.github/workflows/autofix.yml +++ b/.github/workflows/autofix.yml @@ -25,7 +25,7 @@ jobs: - run: web/gen/all - - uses: actions/setup-node@v6 + - uses: actions/setup-node@v6.3.0 with: node-version-file: .github/node-version.txt - run: npm ci diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 81963bd475..53ac689270 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -96,7 +96,7 @@ jobs: - if: runner.os == 'macOS' && github.repository == 'mitmproxy/mitmproxy' && (startsWith(github.ref, 'refs/heads/') || startsWith(github.ref, 'refs/tags/')) id: keychain - uses: apple-actions/import-codesign-certs@b610f78488812c1e56b20e6df63ec42d833f2d14 + uses: apple-actions/import-codesign-certs@fe74d46e82474f87e1ba79832ad28a4013d0e33a with: keychain: ${{ runner.temp }}/temp p12-file-base64: ${{ secrets.APPLE_CERTIFICATE }} @@ -153,11 +153,11 @@ jobs: runs-on: ubuntu-latest steps: - uses: mhils/workflows/checkout@8fe88b311a66c441e01edfebe4cd90d8a47fa335 - - uses: actions/setup-node@v6 + - uses: actions/setup-node@v6.3.0 with: node-version-file: .github/node-version.txt - name: Cache Node.js modules - uses: actions/cache@v5 + uses: actions/cache@v5.0.4 with: # npm cache files are stored in `~/.npm` on Linux/macOS path: ~/.npm @@ -250,16 +250,16 @@ jobs: with: name: binaries.wheel path: release/docker - - uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0 - - uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v1.6.0 + - uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0 + - uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v1.6.0 - name: Login to Docker Hub - uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 + uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0 with: username: mitmbot password: ${{ secrets.DOCKER_PASSWORD }} - name: Login to GitHub Container Registry - uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 + uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0 with: registry: ghcr.io username: ${{ github.repository_owner }} @@ -267,7 +267,7 @@ jobs: - name: Docker meta id: meta - uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 + uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf env: DOCKER_METADATA_ANNOTATIONS_LEVELS: index with: @@ -283,7 +283,7 @@ jobs: - name: Build and push id: push - uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2 + uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0 with: context: release/docker platforms: linux/amd64,linux/arm64 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 475b67a36c..2f7802447f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,7 +25,7 @@ jobs: - uses: actions/checkout@v6 with: token: ${{ secrets.GH_PUSH_TOKEN }} # this token works to push to the protected main branch. - - uses: actions/setup-node@v6 + - uses: actions/setup-node@v6.3.0 with: node-version-file: .github/node-version.txt - uses: mhils/workflows/setup-python@8fe88b311a66c441e01edfebe4cd90d8a47fa335 From 96ec8f72b40f52c2b8446b6918e5bf1606189e5e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 May 2026 15:43:09 +0200 Subject: [PATCH 11/30] Bump awscli from 1.44.53 to 1.44.63 in the deploy group (#8208) * Bump awscli from 1.44.53 to 1.44.63 in the deploy group Bumps the deploy group with 1 update: [awscli](https://github.com/aws/aws-cli). Updates `awscli` from 1.44.53 to 1.44.63 - [Release notes](https://github.com/aws/aws-cli/releases) - [Commits](https://github.com/aws/aws-cli/compare/1.44.53...1.44.63) --- updated-dependencies: - dependency-name: awscli dependency-version: 1.44.63 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: deploy ... Signed-off-by: dependabot[bot] * [autofix.ci] apply automated fixes --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- uv.lock | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index b538e11ce9..fb778680a7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -89,7 +89,7 @@ ruff = [ "ruff==0.15.8", ] deploy = [ - "awscli==1.44.53", + "awscli==1.44.63", "twine==6.2.0", ] diff --git a/uv.lock b/uv.lock index fdfa96fa46..7cf7ed9b8c 100644 --- a/uv.lock +++ b/uv.lock @@ -100,7 +100,7 @@ wheels = [ [[package]] name = "awscli" -version = "1.44.53" +version = "1.44.63" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore" }, @@ -110,9 +110,9 @@ dependencies = [ { name = "rsa" }, { name = "s3transfer" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ef/9b/2c7071d975a975af0766fd133a15aa912aaf4963eab46946c3ea15bb1026/awscli-1.44.53.tar.gz", hash = "sha256:5e32503102efea10e59fee986dc568c7ed21e43d1acf7a1717a277a76a3a3673", size = 1883790, upload-time = "2026-03-06T22:47:51.276Z" } +sdist = { url = "https://files.pythonhosted.org/packages/83/39/0dddc7b57818f3bc5f7401481881a6eba867634af768458eaab46fbbf93c/awscli-1.44.63.tar.gz", hash = "sha256:81e0fb0028f48d0387782bc272a8e6df69a644520e0ce2a1bcf025ec157fe454", size = 1886381, upload-time = "2026-03-20T19:39:48.003Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/82/0e/87b79ad45c0c31344d7d2e6c1ef5a72e6c26857e9c541fb741e60a344c1e/awscli-1.44.53-py3-none-any.whl", hash = "sha256:3a19606fae23ce9d611a55c3fe027bf47396ad9e2d47083310f179166cceaa90", size = 4621982, upload-time = "2026-03-06T22:47:48.246Z" }, + { url = "https://files.pythonhosted.org/packages/11/4f/5d16ee94872b2077ad202f91d6fdc1d38be1ac27906b2a61395f00759bdf/awscli-1.44.63-py3-none-any.whl", hash = "sha256:290298451e46aaf94018cbbf653ca1d7ab890e137888330191152d56f1c827ef", size = 4623761, upload-time = "2026-03-20T19:39:44.236Z" }, ] [[package]] @@ -192,16 +192,16 @@ wheels = [ [[package]] name = "botocore" -version = "1.42.63" +version = "1.42.73" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jmespath" }, { name = "python-dateutil" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/af/eb/a1c042f6638ada552399a9977335a6de2668a85bf80bece193c953531236/botocore-1.42.63.tar.gz", hash = "sha256:1fdfc33cff58d21e8622cf620ba2bba3cff324557932aaf935b5374e4610f059", size = 14965362, upload-time = "2026-03-06T22:47:44.158Z" } +sdist = { url = "https://files.pythonhosted.org/packages/28/23/0c88ca116ef63b1ae77c901cd5d2095d22a8dbde9e80df74545db4a061b4/botocore-1.42.73.tar.gz", hash = "sha256:575858641e4949aaf2af1ced145b8524529edf006d075877af6b82ff96ad854c", size = 15008008, upload-time = "2026-03-20T19:39:40.082Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/60/17a2d3b94658bb999c6aee7bba6c76b271905debf0c8c8e6ac63ca8491bc/botocore-1.42.63-py3-none-any.whl", hash = "sha256:83f39d04f2b316bdfc59a3cac2d12238bde7126ac99d9a57d910dbd86d58c528", size = 14639889, upload-time = "2026-03-06T22:47:39.347Z" }, + { url = "https://files.pythonhosted.org/packages/8e/65/971f3d55015f4d133a6ff3ad74cd39f4b8dd8f53f7775a3c2ad378ea5145/botocore-1.42.73-py3-none-any.whl", hash = "sha256:7b62e2a12f7a1b08eb7360eecd23bb16fe3b7ab7f5617cf91b25476c6f86a0fe", size = 14681861, upload-time = "2026-03-20T19:39:35.341Z" }, ] [[package]] @@ -1060,7 +1060,7 @@ requires-dist = [ [package.metadata.requires-dev] deploy = [ - { name = "awscli", specifier = "==1.44.53" }, + { name = "awscli", specifier = "==1.44.63" }, { name = "twine", specifier = "==6.2.0" }, ] dev = [ From a5f8716bfbaf3290936a8f8c53e2c87f7c04df8f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 May 2026 15:43:20 +0200 Subject: [PATCH 12/30] Bump the tox group with 2 updates (#8207) * Bump the tox group with 2 updates Bumps the tox group with 2 updates: [tox](https://github.com/tox-dev/tox) and [tox-uv](https://github.com/tox-dev/tox-uv). Updates `tox` from 4.49.0 to 4.50.3 - [Release notes](https://github.com/tox-dev/tox/releases) - [Changelog](https://github.com/tox-dev/tox/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/tox/compare/4.49.0...4.50.3) Updates `tox-uv` from 1.33.1 to 1.33.4 - [Release notes](https://github.com/tox-dev/tox-uv/releases) - [Commits](https://github.com/tox-dev/tox-uv/compare/1.33.1...1.33.4) --- updated-dependencies: - dependency-name: tox dependency-version: 4.50.3 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: tox - dependency-name: tox-uv dependency-version: 1.33.4 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: tox ... Signed-off-by: dependabot[bot] * [autofix.ci] apply automated fixes --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- pyproject.toml | 4 ++-- uv.lock | 24 ++++++++++++------------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index fb778680a7..a7f7c7020f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -82,8 +82,8 @@ dev = [ {include-group = "ruff"}, ] tox = [ - "tox==4.49.0", - "tox-uv==1.33.1", + "tox==4.50.3", + "tox-uv==1.33.4", ] ruff = [ "ruff==0.15.8", diff --git a/uv.lock b/uv.lock index 7cf7ed9b8c..d65d7c82e9 100644 --- a/uv.lock +++ b/uv.lock @@ -1079,15 +1079,15 @@ dev = [ { name = "pytest-xdist", specifier = "==3.8.0" }, { name = "requests", specifier = "==2.32.5" }, { name = "ruff", specifier = "==0.15.8" }, - { name = "tox", specifier = "==4.49.0" }, - { name = "tox-uv", specifier = "==1.33.1" }, + { name = "tox", specifier = "==4.50.3" }, + { name = "tox-uv", specifier = "==1.33.4" }, { name = "types-requests", specifier = "==2.32.4.20260107" }, { name = "wheel", specifier = "==0.46.3" }, ] ruff = [{ name = "ruff", specifier = "==0.15.8" }] tox = [ - { name = "tox", specifier = "==4.49.0" }, - { name = "tox-uv", specifier = "==1.33.1" }, + { name = "tox", specifier = "==4.50.3" }, + { name = "tox-uv", specifier = "==1.33.4" }, ] [[package]] @@ -1844,7 +1844,7 @@ wheels = [ [[package]] name = "tox" -version = "4.49.0" +version = "4.50.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cachetools" }, @@ -1857,34 +1857,34 @@ dependencies = [ { name = "tomli-w" }, { name = "virtualenv" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c5/5a/56146cae67d337426a98cf95f1a9f3ae8b557879df9a03332ef7d6654496/tox-4.49.0.tar.gz", hash = "sha256:2e01f09ae1226749466cbcd8c514fe988ffc8c76b5d523c7f9b745d1711a6e71", size = 259917, upload-time = "2026-03-06T19:57:10.723Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ae/45/e4c0ac54af794f992790abe350770bb1fa6d5a85b25d47b6182c83ec7915/tox-4.50.3.tar.gz", hash = "sha256:c745641de6cc4f19d066bd9f98c1c25f7affb005b381b7f3694a1f142ea0946b", size = 266455, upload-time = "2026-03-20T01:17:59.351Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/97/db/c13e849355a7833b319785bafbc947104f9161b964884b159ca94984965a/tox-4.49.0-py3-none-any.whl", hash = "sha256:97cf3cea10c12442569a31bfa411600fbbfc8cb972ad4e48039599935c94a584", size = 206768, upload-time = "2026-03-06T19:57:09.369Z" }, + { url = "https://files.pythonhosted.org/packages/fe/ab/369d60db70d9031341082842071541f2497741b04140816c7df82734faf6/tox-4.50.3-py3-none-any.whl", hash = "sha256:5e788a512bfe6f7447e0c8d7c1b666eb2e56e5e676c65717490423bec37d1a07", size = 207667, upload-time = "2026-03-20T01:17:57.553Z" }, ] [[package]] name = "tox-uv" -version = "1.33.1" +version = "1.33.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "tox-uv-bare" }, { name = "uv" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/19/51/9a6dd32e34a3ee200c7890497093875e2c0a0b08737bb897e5916c6575bc/tox_uv-1.33.1-py3-none-any.whl", hash = "sha256:0617caa6444097434cdef24477307ff3242021a44088df673ae08771d3657f79", size = 5364, upload-time = "2026-03-02T17:06:18.32Z" }, + { url = "https://files.pythonhosted.org/packages/33/60/f3419045763389b7c1645753ccab1917c8758b0a95b6bad01fed479a9d5b/tox_uv-1.33.4-py3-none-any.whl", hash = "sha256:fe63d7597a0aac6116e06c0f1366b0925bc94b0b92b62a9ec5a9f3e4c17ad5b2", size = 5482, upload-time = "2026-03-12T21:20:54.221Z" }, ] [[package]] name = "tox-uv-bare" -version = "1.33.1" +version = "1.33.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "packaging" }, { name = "tox" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b0/7b/5ce3aa477400c7791968037b3bf27a50a4e19160a111d9956d20e5ce6b06/tox_uv_bare-1.33.1.tar.gz", hash = "sha256:169185feb3cc8f321eb2a33c575c61dc6efd9bf6044b97636a7381261d29e85c", size = 27203, upload-time = "2026-03-02T17:06:21.118Z" } +sdist = { url = "https://files.pythonhosted.org/packages/86/56/12f8602a3207b87825564939a4956941c6ddac2f1ac714967926ebb5c9b0/tox_uv_bare-1.33.4.tar.gz", hash = "sha256:310726bd445557f411e7b3096075378c5aac39bb9aa984651a40836f8c988703", size = 27452, upload-time = "2026-03-12T21:20:57.007Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d2/8e/ae95104165f4e2da5d9d25d8c71c7c935227c3eeb88e0376dab48b787a1c/tox_uv_bare-1.33.1-py3-none-any.whl", hash = "sha256:e64fdcd607a0f66212ef9edb36a5a672f10b461fce2a8216dda3e93c45d4a3f9", size = 19718, upload-time = "2026-03-02T17:06:19.657Z" }, + { url = "https://files.pythonhosted.org/packages/b7/0d/9d47b320eec0013f7cedb3f340f965e11b8071350b01d5d6e3b301a3e558/tox_uv_bare-1.33.4-py3-none-any.whl", hash = "sha256:fab00d5b0097cdee6607ce0f79326e6c1a8828097b63ab8cb4f327cb132e5fbf", size = 19669, upload-time = "2026-03-12T21:20:55.638Z" }, ] [[package]] From f478061882670cb612296d43d85ff98848fb4302 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 May 2026 15:43:34 +0200 Subject: [PATCH 13/30] Bump pyinstaller-hooks-contrib from 2026.2 to 2026.3 in the pyinstaller group (#8205) * Bump pyinstaller-hooks-contrib in the pyinstaller group Bumps the pyinstaller group with 1 update: [pyinstaller-hooks-contrib](https://github.com/pyinstaller/pyinstaller-hooks-contrib). Updates `pyinstaller-hooks-contrib` from 2026.2 to 2026.3 - [Release notes](https://github.com/pyinstaller/pyinstaller-hooks-contrib/releases) - [Changelog](https://github.com/pyinstaller/pyinstaller-hooks-contrib/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pyinstaller/pyinstaller-hooks-contrib/compare/v2026.2...v2026.3) --- updated-dependencies: - dependency-name: pyinstaller-hooks-contrib dependency-version: '2026.3' dependency-type: direct:development update-type: version-update:semver-minor dependency-group: pyinstaller ... Signed-off-by: dependabot[bot] * [autofix.ci] apply automated fixes --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- uv.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a7f7c7020f..1c1fa7aed3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -67,7 +67,7 @@ dev = [ "maturin==1.12.6", "pdoc==16.0.0", "pyinstaller==6.19.0", - "pyinstaller-hooks-contrib==2026.2", + "pyinstaller-hooks-contrib==2026.3", "pytest-asyncio==1.2.0", "pytest-cov==7.0.0", "pytest-timeout==2.4.0", diff --git a/uv.lock b/uv.lock index d65d7c82e9..0d4ac4bce5 100644 --- a/uv.lock +++ b/uv.lock @@ -1071,7 +1071,7 @@ dev = [ { name = "mypy", specifier = "==1.19.1" }, { name = "pdoc", specifier = "==16.0.0" }, { name = "pyinstaller", specifier = "==6.19.0" }, - { name = "pyinstaller-hooks-contrib", specifier = "==2026.2" }, + { name = "pyinstaller-hooks-contrib", specifier = "==2026.3" }, { name = "pytest", specifier = "==8.4.2" }, { name = "pytest-asyncio", specifier = "==1.2.0" }, { name = "pytest-cov", specifier = "==7.0.0" }, @@ -1408,15 +1408,15 @@ wheels = [ [[package]] name = "pyinstaller-hooks-contrib" -version = "2026.2" +version = "2026.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "packaging" }, { name = "setuptools" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6b/90/f3b30d72b89ab5b8f3ef714db94d09c7c263cce6562b4c7c636d99630695/pyinstaller_hooks_contrib-2026.2.tar.gz", hash = "sha256:cbd1eb00b5d13301b1cce602e1fffb17f0c531c0391f0a87a383d376be68a186", size = 171884, upload-time = "2026-03-02T23:07:01.221Z" } +sdist = { url = "https://files.pythonhosted.org/packages/80/17/716326f6ba18d0663f7995ae369c23e50efebc22fbb054e9710a45688f61/pyinstaller_hooks_contrib-2026.3.tar.gz", hash = "sha256:800d3a198a49a6cd0de2d7fb795005fdca7a0222ed9cb47c0691abd1c27b9310", size = 172323, upload-time = "2026-03-09T22:44:06.345Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/34/3b/1efef5ff4d4d150f646b873e963437c0b800cb375a37df01fefab149f4d9/pyinstaller_hooks_contrib-2026.2-py3-none-any.whl", hash = "sha256:fc29f0481b58adf78ce9c1d9cf135fe96f38c708f74b2aa0670ef93e59578ab9", size = 453939, upload-time = "2026-03-02T23:06:59.469Z" }, + { url = "https://files.pythonhosted.org/packages/ed/19/781352446af28755f16ce52b2d97f7a6f2d7974ac34c00ca5cd8c40c9098/pyinstaller_hooks_contrib-2026.3-py3-none-any.whl", hash = "sha256:5ecd1068ad262afecadf07556279d2be52ca93a88b049fae17f1a2eb2969254a", size = 454625, upload-time = "2026-03-09T22:44:04.717Z" }, ] [[package]] From b464cbf82308547f461a916b18db96d05c399944 Mon Sep 17 00:00:00 2001 From: unique-jakub Date: Mon, 11 May 2026 15:45:24 +0200 Subject: [PATCH 14/30] =?UTF-8?q?Copy=20issuer's=20SubjectKeyIdentifier=20?= =?UTF-8?q?into=20leaf=20AuthorityKeyIdentifier=20(RFC=205280=20=C2=A74.2.?= =?UTF-8?q?1.2)=20(#8214)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Copy issuer's SubjectKeyIdentifier into leaf AuthorityKeyIdentifier mitmproxy.certs.dummy_cert previously built the leaf's AuthorityKeyIdentifier with `from_issuer_public_key()`, which always derives the keyIdentifier as the SHA-1 of the issuer's BIT STRING public key. This violates RFC 5280 §4.2.1.2: The value of the subject key identifier MUST be the value placed in the key identifier field of the authority key identifier extension of certificates issued by the subject of this certificate. Whenever the issuer's stored SKI was generated by any other method (RFC 7093 truncated SHA-256/384/512, hardware-rooted CAs, or any custom value), the recomputed AKI mismatches the issuer's SKI and strict TLS chain builders (`X509_V_FLAG_X509_STRICT`, Python `ssl`, Go `crypto/x509`) reject the chain with "authority and subject key identifier mismatch". The most common modern trigger: cert-manager >=1.18 and Go >=1.25 default to truncated SHA-256 SKIs for FIPS 140-3 compliance, so any mitmproxy deployment fed a CA from those toolchains breaks. Fix: prefer the issuer's stored SKI extension verbatim (AuthorityKeyIdentifier.from_issuer_subject_key_identifier), and only fall back to the previous behavior when the issuer cert has no SKI extension at all. Adds two regression tests: - test_aki_copies_issuer_ski_non_sha1 verifies that a CA with a truncated SHA-256 SKI (as produced by cert-manager / Go 1.25+) yields a leaf whose AKI is byte-equal to the issuer's stored SKI. - test_aki_falls_back_when_issuer_has_no_ski verifies the SKI-absent fallback still produces the previous AKI value. * [autofix.ci] apply automated fixes * shorten changelog --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Maximilian Hils --- CHANGELOG.md | 4 ++ mitmproxy/certs.py | 24 ++++++++-- test/mitmproxy/test_certs.py | 85 ++++++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 713ea6c217..0f3c355d3b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ ## Unreleased: mitmproxy next +- Fix `authority and subject key identifier mismatch` errors when mitmproxy + is configured with a custom CA whose SubjectKeyIdentifier was not derived + as SHA-1 of the public key. + ([#8214](https://github.com/mitmproxy/mitmproxy/pull/8214), @unique-jakub) - Fix `IndexError` in `is_mostly_bin` when exporting flows to HAR with payloads that have a UTF-8 continuation byte at the 100-byte cutoff. ([#8196](https://github.com/mitmproxy/mitmproxy/pull/8196), @juliosuas) diff --git a/mitmproxy/certs.py b/mitmproxy/certs.py index 2f421e25e1..329630f77b 100644 --- a/mitmproxy/certs.py +++ b/mitmproxy/certs.py @@ -356,10 +356,26 @@ def dummy_cert( ) # https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.1 - builder = builder.add_extension( - x509.AuthorityKeyIdentifier.from_issuer_public_key(cacert.public_key()), # type: ignore - critical=False, - ) + # Per RFC 5280 §4.2.1.2, the AKI's keyIdentifier in a child certificate + # MUST be byte-equal to the issuer's stored SubjectKeyIdentifier. If we + # recompute it from the public key with `from_issuer_public_key()`, we + # always derive a SHA-1 digest, which mismatches whenever the issuer's + # SKI was generated by a different method (RFC 7093 truncated + # SHA-256/384/512, hardware-rooted CAs, or any custom value). This + # mismatch is rejected by strict TLS chain builders (`X509_V_FLAG_X509_STRICT`, + # Python `ssl`, Go `crypto/x509`) with "authority and subject key + # identifier mismatch". Most notably, cert-manager >=1.18 / Go >=1.25 + # default to truncated SHA-256 SKIs for FIPS 140-3 compliance. + try: + issuer_ski = cacert.extensions.get_extension_for_class( + x509.SubjectKeyIdentifier + ).value + aki = x509.AuthorityKeyIdentifier.from_issuer_subject_key_identifier(issuer_ski) + except x509.ExtensionNotFound: + # Fall back when the issuer cert has no SKI extension at all (legacy + # CAs predating RFC 5280 conformance). + aki = x509.AuthorityKeyIdentifier.from_issuer_public_key(cacert.public_key()) # type: ignore + builder = builder.add_extension(aki, critical=False) # If CA and leaf cert have the same Subject Key Identifier, SChannel breaks in funny ways, # see https://github.com/mitmproxy/mitmproxy/issues/6494. # https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.2 states diff --git a/test/mitmproxy/test_certs.py b/test/mitmproxy/test_certs.py index aba66a7337..6fe5ee84fe 100644 --- a/test/mitmproxy/test_certs.py +++ b/test/mitmproxy/test_certs.py @@ -1,11 +1,16 @@ +import hashlib import ipaddress import os from datetime import datetime +from datetime import timedelta from datetime import timezone from pathlib import Path import pytest from cryptography import x509 +from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives import serialization +from cryptography.hazmat.primitives.asymmetric import rsa from cryptography.x509 import NameOID from ..conftest import skip_windows @@ -176,6 +181,86 @@ def test_with_ca(self, tstore): assert r.altnames == x509.GeneralNames([]) assert r.crl_distribution_points == [] + @staticmethod + def _build_ca_with_ski( + ski_digest: bytes, + ) -> tuple[rsa.RSAPrivateKey, x509.Certificate]: + """Build a self-signed CA whose SubjectKeyIdentifier is `ski_digest`.""" + key = rsa.generate_private_key(public_exponent=65537, key_size=2048) + name = x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "test ca")]) + now = datetime.now(timezone.utc) + cert = ( + x509.CertificateBuilder() + .subject_name(name) + .issuer_name(name) + .public_key(key.public_key()) + .serial_number(x509.random_serial_number()) + .not_valid_before(now - timedelta(days=1)) + .not_valid_after(now + timedelta(days=365)) + .add_extension( + x509.BasicConstraints(ca=True, path_length=None), critical=True + ) + .add_extension(x509.SubjectKeyIdentifier(digest=ski_digest), critical=False) + .sign(private_key=key, algorithm=hashes.SHA256()) + ) + return key, cert + + def test_aki_copies_issuer_ski_non_sha1(self): + # RFC 5280 §4.2.1.2: a child cert's AKI keyIdentifier MUST be byte-equal + # to the issuer's stored SubjectKeyIdentifier. mitmproxy must therefore + # copy the issuer's SKI verbatim, not recompute it from the public key + # (which always produces a SHA-1 digest and so mismatches whenever the + # CA used a different method, e.g. cert-manager >=1.18 / Go >=1.25 + # which default to truncated SHA-256 for FIPS 140-3 compliance). + pub_der = ( + rsa.generate_private_key(public_exponent=65537, key_size=2048) + .public_key() + .public_bytes( + encoding=serialization.Encoding.DER, + format=serialization.PublicFormat.SubjectPublicKeyInfo, + ) + ) + sha256_ski_digest = hashlib.sha256(pub_der).digest()[:20] + ca_key, ca_cert = self._build_ca_with_ski(sha256_ski_digest) + + leaf = certs.dummy_cert(ca_key, ca_cert, "example.com", []) + + leaf_aki = leaf._cert.extensions.get_extension_for_class( + x509.AuthorityKeyIdentifier + ).value + assert leaf_aki.key_identifier == sha256_ski_digest + + def test_aki_falls_back_when_issuer_has_no_ski(self): + # Legacy CAs may not have an SKI extension at all. Falling back to + # `from_issuer_public_key` keeps mitmproxy producing a usable AKI + # rather than raising. + key = rsa.generate_private_key(public_exponent=65537, key_size=2048) + name = x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "no-ski ca")]) + now = datetime.now(timezone.utc) + ca_cert = ( + x509.CertificateBuilder() + .subject_name(name) + .issuer_name(name) + .public_key(key.public_key()) + .serial_number(x509.random_serial_number()) + .not_valid_before(now - timedelta(days=1)) + .not_valid_after(now + timedelta(days=365)) + .add_extension( + x509.BasicConstraints(ca=True, path_length=None), critical=True + ) + .sign(private_key=key, algorithm=hashes.SHA256()) + ) + + leaf = certs.dummy_cert(key, ca_cert, "example.com", []) + + leaf_aki = leaf._cert.extensions.get_extension_for_class( + x509.AuthorityKeyIdentifier + ).value + expected = x509.AuthorityKeyIdentifier.from_issuer_public_key( + ca_cert.public_key() # type: ignore[arg-type] + ).key_identifier + assert leaf_aki.key_identifier == expected + class TestCert: def test_simple(self, tdata): From ed564afe9455fd9a18771a46316df4224d0d57b9 Mon Sep 17 00:00:00 2001 From: Emanuele Micheletti Date: Mon, 11 May 2026 16:08:05 +0200 Subject: [PATCH 15/30] Reduce generated certificate validity (#8203) * Reduce generated certificate validity * [autofix.ci] apply automated fixes * make cert backdating more clear --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Maximilian Hils Co-authored-by: Maximilian Hils --- CHANGELOG.md | 3 +++ mitmproxy/certs.py | 16 ++++++++++------ test/mitmproxy/test_certs.py | 11 +++++++++++ 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f3c355d3b..df9faf7a31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ ## Unreleased: mitmproxy next +- Reduce generated leaf certificate validity from 199 to 197 days so the 2-day + `notBefore` backdate remains below Chromium's 200-day limit. + ([#8203](https://github.com/mitmproxy/mitmproxy/pull/8203), @emanuele-em) - Fix `authority and subject key identifier mismatch` errors when mitmproxy is configured with a custom CA whose SubjectKeyIdentifier was not derived as SHA-1 of the public key. diff --git a/mitmproxy/certs.py b/mitmproxy/certs.py index 329630f77b..b67e064cee 100644 --- a/mitmproxy/certs.py +++ b/mitmproxy/certs.py @@ -35,10 +35,14 @@ logger = logging.getLogger(__name__) # Default expiry must not be too long: https://github.com/mitmproxy/mitmproxy/issues/815 +# Note that expiry will be offset by `CERT_VALIDITY_OFFSET`, i.e. the cert will be +# backdated a bit to account for clients with incorrect clocks. CA_EXPIRY = datetime.timedelta(days=10 * 365) CERT_EXPIRY = datetime.timedelta(days=199) CRL_EXPIRY = datetime.timedelta(days=7) +CERT_VALIDITY_OFFSET = datetime.timedelta(days=-2) + # Generated with "openssl dhparam". It's too slow to generate this on startup. DEFAULT_DHPARAM = b""" -----BEGIN DH PARAMETERS----- @@ -245,8 +249,8 @@ def create_ca( builder = x509.CertificateBuilder() builder = builder.serial_number(x509.random_serial_number()) builder = builder.subject_name(name) - builder = builder.not_valid_before(now - datetime.timedelta(days=2)) - builder = builder.not_valid_after(now + CA_EXPIRY) + builder = builder.not_valid_before(now + CERT_VALIDITY_OFFSET) + builder = builder.not_valid_after(now + CERT_VALIDITY_OFFSET + CA_EXPIRY) builder = builder.issuer_name(name) builder = builder.public_key(private_key.public_key()) builder = builder.add_extension( @@ -335,8 +339,8 @@ def dummy_cert( builder = builder.public_key(cacert.public_key()) now = datetime.datetime.now() - builder = builder.not_valid_before(now - datetime.timedelta(days=2)) - builder = builder.not_valid_after(now + CERT_EXPIRY) + builder = builder.not_valid_before(now + CERT_VALIDITY_OFFSET) + builder = builder.not_valid_after(now + CERT_VALIDITY_OFFSET + CERT_EXPIRY) subject = [] is_valid_commonname = commonname is not None and len(commonname) < 64 @@ -416,8 +420,8 @@ def dummy_crl( builder = builder.issuer_name(cacert.issuer) now = datetime.datetime.now() - builder = builder.last_update(now - datetime.timedelta(days=2)) - builder = builder.next_update(now + CRL_EXPIRY) + builder = builder.last_update(now + CERT_VALIDITY_OFFSET) + builder = builder.next_update(now + CERT_VALIDITY_OFFSET + CRL_EXPIRY) builder = builder.add_extension(x509.CRLNumber(1000), False) # meaningless number crl = builder.sign(private_key=privkey, algorithm=hashes.SHA256()) diff --git a/test/mitmproxy/test_certs.py b/test/mitmproxy/test_certs.py index 6fe5ee84fe..b365cbf2ae 100644 --- a/test/mitmproxy/test_certs.py +++ b/test/mitmproxy/test_certs.py @@ -145,6 +145,17 @@ def test_asterisk_forms(self, input, output): class TestDummyCert: + def test_validity_period(self, tstore): + r = certs.dummy_cert( + tstore.default_privatekey, + tstore.default_ca._cert, + "foo.com", + [], + ) + validity_period = r.notafter - r.notbefore + assert validity_period == certs.CERT_EXPIRY + assert validity_period < timedelta(days=200) + def test_with_ca(self, tstore): r = certs.dummy_cert( tstore.default_privatekey, From 0fb62c456ccc0839ed4ea9ac6e4d503a80d4e529 Mon Sep 17 00:00:00 2001 From: ChrisJr404 Date: Mon, 11 May 2026 10:18:51 -0400 Subject: [PATCH 16/30] docs: document addon live-reload + testing pattern (#8210) * docs: document addon live-reload + testing pattern Issue #6377 asked for addon development docs covering hot reload and testing. mitmproxy already watches scripts loaded with -s for changes and re-imports them on save (mitmproxy/addons/script.py: Script.watcher and the unconditional Script(s, True) at line 218), but that behavior was undocumented, and there was no canonical example of how to unit-test a custom addon with mitmproxy.test.taddons / mitmproxy.test.tflow. Add a "Developing Addons" section to docs/src/content/addons/overview.md with two subsections: - Live Reloading: explains the file-watcher behavior, including which errors leave the previous version unloaded and which don't. - Testing Addons: a small example that unit-tests the Counter addon from anatomy.py using taddons.context() and tflow.tflow(), plus a pointer to tctx.cycle() and the existing test/mitmproxy/addons/ tests for patterns that need the full event sequence. No code changes. * reduce testing section Testing helpers are currently a bit ugly and not part of the public API, so let's not put them front center in the docs. --------- Co-authored-by: Chris (ChrisJr404) <11917633+ChrisJr404@users.noreply.github.com> Co-authored-by: Maximilian Hils --- docs/src/content/addons/overview.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/docs/src/content/addons/overview.md b/docs/src/content/addons/overview.md index cecb2c6646..409ad69677 100644 --- a/docs/src/content/addons/overview.md +++ b/docs/src/content/addons/overview.md @@ -54,3 +54,28 @@ This lets us place event handler functions in the module scope. For instance, here is a complete script that adds a header to every request: {{< example src="examples/addons/anatomy2.py" lang="py" >}} + +# Developing Addons + +## Live Reloading + +Scripts loaded with `-s path/to/script.py` are watched for changes. +Whenever the file's modification time changes, mitmproxy unregisters the +old module, re-imports the file, and re-registers the new addon — without +restarting the proxy or losing the state of any other addons or in-flight +flows. This means you can edit your addon in your editor and the changes +take effect on the next save (within roughly one second). + +Errors raised at import time, in `configure`, or in `running` are logged +to the event log and the previous version of the addon is left +unregistered. Fix the error and save the file again to retry. Errors +raised inside event handlers (`request`, `response`, …) are logged but do +not unload the addon. + +## Testing Addons + +Because addons are regular Python files, the easiest way to unit-test +them is to import the module from your test, instantiate the addon, and +call the event handler directly. For more complex testing needs, +see [`test/mitmproxy/addons`](https://github.com/mitmproxy/mitmproxy/tree/main/test/mitmproxy/addons) +(but please note that internal testing helpers have no guaranteed stable API). From 6bc7f0a4f25e085f3eea3ae64e28b72c6f7662a3 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Tue, 12 May 2026 12:30:47 +0000 Subject: [PATCH 17/30] Rename mitmweb XSRF cookie to `_mitmproxy_xsrf` to recover broken Firefox sessions (#8224) Co-authored-by: Maximilian Hils --- mitmproxy/tools/web/app.py | 3 +++ web/src/js/utils.ts | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/mitmproxy/tools/web/app.py b/mitmproxy/tools/web/app.py index c207701ed3..1989bd2e9d 100644 --- a/mitmproxy/tools/web/app.py +++ b/mitmproxy/tools/web/app.py @@ -925,6 +925,9 @@ def __init__( template_path=os.path.join(os.path.dirname(__file__), "templates"), static_path=os.path.join(os.path.dirname(__file__), "static"), xsrf_cookies=True, + # https://github.com/mitmproxy/mitmproxy/issues/8194 + # 2026-05: We can move back to the default cookie name in a few years. + xsrf_cookie_name="_mitmproxy_xsrf", xsrf_cookie_kwargs=dict(samesite="Strict"), cookie_secret=secrets.token_bytes(32), debug=debug, diff --git a/web/src/js/utils.ts b/web/src/js/utils.ts index 7e76df609c..89969f55cf 100644 --- a/web/src/js/utils.ts +++ b/web/src/js/utils.ts @@ -78,7 +78,7 @@ function getCookie(name) { } let xsrf = () => { - const cached = getCookie("_xsrf"); + const cached = getCookie("_mitmproxy_xsrf"); xsrf = () => cached; return xsrf(); }; From f9c2b44acb8d09d4d23a2faf3def2b3c637f16b4 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Tue, 12 May 2026 14:57:34 +0200 Subject: [PATCH 18/30] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index df9faf7a31..d46708d9a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ - Reduce generated leaf certificate validity from 199 to 197 days so the 2-day `notBefore` backdate remains below Chromium's 200-day limit. ([#8203](https://github.com/mitmproxy/mitmproxy/pull/8203), @emanuele-em) +- Fixed a bug where mitmweb would not pick up its XSRF cookie. + ([#8224](https://github.com/mitmproxy/mitmproxy/pull/8224), @mhils) - Fix `authority and subject key identifier mismatch` errors when mitmproxy is configured with a custom CA whose SubjectKeyIdentifier was not derived as SHA-1 of the public key. From 6c09d56e4c29a92f5ad01b03199977584b8ea14f Mon Sep 17 00:00:00 2001 From: mitmproxy release bot Date: Tue, 12 May 2026 13:02:14 +0000 Subject: [PATCH 19/30] mitmproxy 12.2.3 --- CHANGELOG.md | 3 +++ mitmproxy/tools/web/index.html | 2 +- .../tools/web/static/{index-D7g-N5jK.js => index-Be7e-cwP.js} | 2 +- mitmproxy/version.py | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) rename mitmproxy/tools/web/static/{index-D7g-N5jK.js => index-Be7e-cwP.js} (80%) diff --git a/CHANGELOG.md b/CHANGELOG.md index d46708d9a8..352f935ed5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ ## Unreleased: mitmproxy next + +## 12 May 2026: mitmproxy 12.2.3 + - Reduce generated leaf certificate validity from 199 to 197 days so the 2-day `notBefore` backdate remains below Chromium's 200-day limit. ([#8203](https://github.com/mitmproxy/mitmproxy/pull/8203), @emanuele-em) diff --git a/mitmproxy/tools/web/index.html b/mitmproxy/tools/web/index.html index 0ec4aa2fa6..74288b6128 100644 --- a/mitmproxy/tools/web/index.html +++ b/mitmproxy/tools/web/index.html @@ -5,7 +5,7 @@ mitmproxy - + diff --git a/mitmproxy/tools/web/static/index-D7g-N5jK.js b/mitmproxy/tools/web/static/index-Be7e-cwP.js similarity index 80% rename from mitmproxy/tools/web/static/index-D7g-N5jK.js rename to mitmproxy/tools/web/static/index-Be7e-cwP.js index 7dc205c955..54b08644e2 100644 --- a/mitmproxy/tools/web/static/index-D7g-N5jK.js +++ b/mitmproxy/tools/web/static/index-Be7e-cwP.js @@ -1,4 +1,4 @@ -import{c as fe,R as Cl,a as _e,r as I,b as Te,d as je,j as o,e as k,f as ui,u as Nl,g as kl,h as fi,s as Kt,i as El,l as Ht,k as Tl,m as Rl,n as Al,y as Dl,o as Fl,p as Il,q as zt,Q as Ll,t as Pl,P as Ol}from"./vendor-BS4xPthR.js";(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))i(r);new MutationObserver(r=>{for(const n of r)if(n.type==="childList")for(const l of n.addedNodes)l.tagName==="LINK"&&l.rel==="modulepreload"&&i(l)}).observe(document,{childList:!0,subtree:!0});function s(r){const n={};return r.integrity&&(n.integrity=r.integrity),r.referrerPolicy&&(n.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?n.credentials="include":r.crossOrigin==="anonymous"?n.credentials="omit":n.credentials="same-origin",n}function i(r){if(r.ep)return;r.ep=!0;const n=s(r);fetch(r.href,n)}})();const Ml={tab:"request",contentViewFor:{}},ql=fe({name:"ui/flow",initialState:Ml,reducers:{selectTab(t,e){t.tab=e.payload},setContentViewFor(t,e){t.contentViewFor[e.payload.messageId]=e.payload.contentView}}}),{actions:Hl,reducer:Vl}=ql,{selectTab:Ut,setContentViewFor:pi}=Hl;window.React=Cl;const hi=function(t){if(t===0)return"0";const e=["b","kb","mb","gb","tb"];let s=0;for(;st);s++);let i;return t%Math.pow(1024,s)===0?i=0:i=1,(t/Math.pow(1024,s)).toFixed(i)+e[s]},mi=function(t){let e=t;const s=["ms","s","min","h"],i=[1e3,60,60];let r=0;for(;Math.abs(e)>=i[r]&&r{const t=Ul("_xsrf");return fs=()=>t,fs()};function ne(t,e={}){return e.method&&e.method!=="GET"&&(e.headers=e.headers||{},e.headers["X-XSRFToken"]=fs()),t.startsWith("/")&&(t="."+t),fetch(t,{credentials:"same-origin",...e})}ne.put=(t,e,s={})=>ne(t,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(e),...s});ne.post=(t,e,s={})=>ne(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e),...s});async function Bt(t,...e){return await(await ne(`/commands/${t}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({arguments:e})})).json()}async function gi(t){try{await navigator.clipboard.write([new ClipboardItem({"text/plain":t})]);return}catch(i){console.warn(i)}const e=await t;try{await navigator.clipboard.writeText(e);return}catch(i){console.warn(i)}const s=document.createElement("textarea");s.value=e,s.style.position="absolute",s.style.opacity="0",document.body.appendChild(s);try{if(s.focus(),s.select(),!document.execCommand("copy"))throw"failed to copy"}catch{alert(e)}finally{s.remove()}}async function Bl(t){await gi(Promise.resolve(t?.text||""))}function ps(t,e){const s=t.lastIndexOf(e);if(s===-1)return["",t];const i=t.slice(0,s),r=t.slice(s+e.length);return[i,r]}function vi(t,e){const s=t.indexOf(e);if(s===-1)return[t,""];const i=t.slice(0,s),r=t.slice(s+e.length);return[i,r]}function Ct(t){throw new Error(`Unreachable: ${JSON.stringify(t)}`)}const xi={http:80,https:443},Vn=new WeakMap;class we{static getContentType(e){const s=we.get_first_header(e,/^Content-Type$/i);if(s)return s.split(";")[0].trim()}static get_first_header(e,s){let i=Vn.get(e);i||(i=new Map,Vn.set(e,i));let r=i.get(s);if(r===void 0){const n=e.headers.find(([l,a])=>s.test(l));r=n?n[1]:!1,i.set(s,r)}return r!==!1?r:void 0}static match_header(e,s){const i=e.headers;if(!i)return!1;let r=i.length;for(;r--;)if(s.test(i[r].join(" ")))return i[r];return!1}static getContentURL(e,s,i,r){e.type==="http"&&s===e.request?s="request":e.type==="http"&&s===e.response&&(s="response");const n=r?`?lines=${r}`:"";return`./flows/${e.id}/${s}/`+(i?`content/${encodeURIComponent(i)}.json${n}`:"content.data")}}class ct extends we{static pretty_url(e){let s="";return xi[e.scheme]!==e.port&&(s=":"+e.port),e.scheme+"://"+e.pretty_host+s+e.path}}class mt extends we{}const Wl=/^(?:(https?):\/\/)?([^/:]+)?(?::(\d+))?(\/.*)?$/i,_i=function(t){const e=Wl.exec(t);if(!e)return;const s=e[1],i=e[2],r=parseInt(e[3]),n=e[4],l=s?r||xi[s]:r,a={};return s&&(a.scheme=s),i&&(a.host=i),l&&(a.port=l),n&&(a.path=n),a},Kl=/^HTTP\/\d+(\.\d+)*$/i,ji=function(t){return Kl.test(t)};function Wt(t){switch(t.type){case"http":return t.request.timestamp_start;case"tcp":case"udp":return t.client_conn.timestamp_start;case"dns":return t.request.timestamp}}function yi(t){switch(t.type){case"http":if(t.websocket){if(t.websocket.timestamp_end)return t.websocket.timestamp_end;if(t.websocket.messages_meta.timestamp_last)return t.websocket.messages_meta.timestamp_last}return t.response?t.response.timestamp_end:void 0;case"tcp":return t.server_conn?.timestamp_end;case"udp":return t.messages_meta.timestamp_last;case"dns":return t.response?.timestamp}}const wi=t=>{switch(t.type){case"http":{let e=t.request.contentLength||0;return t.response&&(e+=t.response.contentLength||0),t.websocket&&(e+=t.websocket.messages_meta.contentLength||0),e}case"tcp":case"udp":return t.messages_meta.contentLength||0;case"dns":return t.response?.size??0}},xs=t=>t.type==="http"&&!t.websocket,bi=t=>t.modified,_s=t=>t.intercepted,Si=t=>{if(t.type!=="http")return t.client_conn.tls_version==="QUICv1"?"resource-icon-quic":`resource-icon-${t.type}`;if(t.websocket)return"resource-icon-websocket";if(!t.response)return"resource-icon-plain";const e=mt.getContentType(t.response)||"";return t.response.status_code===304?"resource-icon-not-modified":300<=t.response.status_code&&t.response.status_code<400?"resource-icon-redirect":e.indexOf("image")>=0?"resource-icon-image":e.indexOf("javascript")>=0?"resource-icon-js":e.indexOf("css")>=0?"resource-icon-css":e.indexOf("html")>=0?"resource-icon-document":"resource-icon-plain"},$i=t=>{switch(t.type){case"http":return ct.pretty_url(t.request);case"tcp":case"udp":return`${t.client_conn.peername.join(":")} ↔ ${t.server_conn?.address?.join(":")}`;case"dns":return`${t.request.questions.map(e=>`${e.name} ${e.type}`).join(", ")} = ${(t.response?.answers.map(e=>e.data).join(", ")??"...")||"?"}`}},Ci=t=>{switch(t.type){case"http":return t.response?.status_code;case"dns":return t.response?.response_code;default:return}},Ni=t=>{switch(t.type){case"http":return t.websocket?t.client_conn.tls_established?"WSS":"WS":t.request.method;case"dns":return t.request.op_code;default:return t.type.toUpperCase()}},ki=t=>{switch(t.type){case"http":return t.request.http_version;default:return""}},Ei={tls:t=>t.type==="http"&&t.request.scheme,icon:Si,index:()=>0,path:$i,method:Ni,version:ki,status:Ci,size:wi,time:t=>{const e=Wt(t),s=yi(t);return e&&s&&s-e},timestamp:Wt,quickactions:()=>0,comment:t=>t.comment};function zl(t){return t in Ei}var ve=(t=>(t.Search="search",t.Highlight="highlight",t))(ve||{});const Ti={search:"",highlight:""},Gl=fe({name:"ui/filters",initialState:Ti,reducers:{setFilter(t,e){t.search=e.payload},setHighlight(t,e){t.highlight=e.payload}}}),{actions:Yl,reducer:Jl}=Gl,{setFilter:Ri,setHighlight:Ai}=Yl;function rs(t,e){return t.toSorted?t.toSorted(e):[...t].sort(e)}function js(t,...e){if(t.toSpliced)return t.toSpliced(...e);{const s=[...t];return s.splice(...e),s}}function jt(t){return new Map(t.map((e,s)=>[e.id,s]))}function os(t){return new Set(t.map(e=>e.id))}function Un(t,e){return t.has(e)&&(t=new Set(t),t.delete(e)),t}function Bn(t,e,s){const i=js(t,s,1),r=new Map(e);r.delete(t[s].id);for(let n=i.length-1;n>=s;n--)r.set(i[n].id,n);return{view:i,_viewIndex:r}}function Ql(t,e,s,i){const r=[...t],n=r.length;let l=e,a=l.get(s.id);if(a+10){l=new Map(l);do{const d=r[a+1];r[a]=d,l.set(d.id,a),a++}while(a+10);l.set(s.id,a)}else if(a>0&&i(s,r[a-1])<0){l=new Map(l);do{const d=r[a-1];r[a]=d,l.set(d.id,a),a--}while(a>0&&i(s,r[a-1])<0);l.set(s.id,a)}return r[a]=s,{view:r,_viewIndex:l}}function Wn(t,e,s,i){const r=Xl(t,s,i),n=js(t,r,0,s),l=new Map(e);for(let a=n.length-1;a>=r;a--)l.set(n[a].id,a);return{view:n,_viewIndex:l}}function Xl(t,e,s){let i=0,r=t.length;if(r===0||s(t[r-1],e)<=0)return r;for(;i>>1;s(e,t[n])>=0?i=n+1:r=n}return i}function ys(t){return t=t.filter(_s),()=>Promise.all(t.map(e=>ne(`/flows/${e.id}/resume`,{method:"POST"})))}function Di(){return()=>ne("/flows/resume",{method:"POST"})}function Fi(t){return t=t.filter(_s),()=>Promise.all(t.map(e=>ne(`/flows/${e.id}/kill`,{method:"POST"})))}function Zl(){return()=>ne("/flows/kill",{method:"POST"})}function Ii(t){return()=>Promise.all(t.map(e=>ne(`/flows/${e.id}`,{method:"DELETE"})))}function Li(t){return()=>Promise.all(t.map(e=>ne(`/flows/${e.id}/duplicate`,{method:"POST"})))}function ws(t){return t=t.filter(xs),()=>Promise.all(t.map(e=>ne(`/flows/${e.id}/replay`,{method:"POST"})))}function Pi(t){return t=t.filter(bi),()=>Promise.all(t.map(e=>ne(`/flows/${e.id}/revert`,{method:"POST"})))}function Kn(t,e){return()=>Promise.all(t.map(s=>Le(s,{marked:e})()))}function Le(t,e){return()=>ne.put(`/flows/${t.id}`,e)}function ec(t,e,s){const i=new FormData;return e=new window.Blob([e],{type:"plain/text"}),i.append("file",e),()=>ne(`/flows/${t.id}/${s}/content.data`,{method:"POST",body:i})}function Oi(){return()=>ne("/clear",{method:"POST"})}function tc(t){const e=new FormData;return e.append("file",t),()=>ne("/flows/dump",{method:"POST",body:e})}const Mi=_e("flows/add"),qi=_e("flows/update"),Hi=_e("flows/remove"),bs=_e("flows/receive"),Vi=_e("flows/filterUpdate"),Ui=_e("flows/sort"),Ve=_e("flows/select"),sc={list:[],_listIndex:new Map,byId:new Map,view:[],_viewIndex:new Map,sort:{column:void 0,desc:!1},selected:[],selectedIds:new Set,highlightedIds:new Set};function nc(t=sc,e){if(bs.match(e)){const{sort:s}=t,i=e.payload,r=jt(i),n=new Map(i.map(h=>[h.id,h])),l=rs(i,pt(s)),a=jt(l),d=t.selected.map(h=>n.get(h.id)).filter(h=>h!==void 0),f=os(d);return{list:i,_listIndex:r,byId:n,view:l,_viewIndex:a,sort:s,selected:d,selectedIds:f,highlightedIds:new Set}}else if(Mi.match(e)){const{flow:s,matching_filters:i}=e.payload;if(t._listIndex.has(s.id))return t;const{sort:r,selected:n,selectedIds:l}=t;let{view:a,_viewIndex:d,highlightedIds:f}=t;const p=new Map(t._listIndex);p.set(s.id,t.list.length);const h=[...t.list,s],g=new Map(t.byId);return g.set(s.id,s),(i[ve.Search]===!0||i[ve.Search]===void 0)&&({view:a,_viewIndex:d}=Wn(a,d,s,pt(r))),i[ve.Highlight]===!0&&(f=new Set(f),f.add(s.id)),{list:h,_listIndex:p,byId:g,view:a,_viewIndex:d,sort:r,selected:n,selectedIds:l,highlightedIds:f}}else if(qi.match(e)){const{flow:s,matching_filters:i}=e.payload,{_listIndex:r,sort:n,selectedIds:l}=t;let{view:a,_viewIndex:d,selected:f,highlightedIds:p}=t;const h=t._listIndex.get(s.id),g=[...t.list];h!==void 0?g[h]=s:g.push(s);const _=new Map(t.byId);_.set(s.id,s);const j=d.get(s.id),y=j!==void 0,w=i[ve.Search]===!0||i[ve.Search]===void 0;return w&&!y?{view:a,_viewIndex:d}=Wn(a,d,s,pt(n)):!w&&y?{view:a,_viewIndex:d}=Bn(a,d,j):w&&y&&({view:a,_viewIndex:d}=Ql(a,d,s,pt(n))),l.has(s.id)&&(f=f.map($=>$.id===s.id?s:$)),i[ve.Highlight]===!0?p.has(s.id)||(p=new Set(p),p.add(s.id)):p=Un(p,s.id),{list:g,_listIndex:r,byId:_,view:a,_viewIndex:d,sort:n,selected:f,selectedIds:l,highlightedIds:p}}else if(Hi.match(e)){const s=e.payload,{sort:i}=t;let{view:r,_viewIndex:n,selected:l,selectedIds:a}=t;const d=t._listIndex.get(s);if(d===void 0)return t;const f=js(t.list,d,1),p=jt(f),h=new Map(t.byId);h.delete(s);const g=n.get(s);if(g!==void 0&&({view:r,_viewIndex:n}=Bn(r,n,g)),a.has(s)){if(l.length===1&&g!==void 0){const j=r[g]??r[g-1];l=j?[j]:[]}else l=l.filter(j=>j.id!==s);a=os(l)}const _=Un(t.highlightedIds,s);return{list:f,_listIndex:p,byId:h,view:r,_viewIndex:n,sort:i,selected:l,selectedIds:a,highlightedIds:_}}else if(Vi.match(e)){const{name:s,matching_flow_ids:i}=e.payload;switch(s){case ve.Search:{const r=rs(i===null?t.list:i.map(l=>t.byId.get(l)).filter(l=>l!==void 0),pt(t.sort)),n=jt(r);return{...t,view:r,_viewIndex:n}}case ve.Highlight:return{...t,highlightedIds:new Set(i)};default:Ct(s)}}else if(Ui.match(e)){const s=e.payload;let i;s.column?i=rs(t.view,pt(s)):i=t.list.filter(n=>t._viewIndex.has(n.id));const r=jt(i);return{...t,sort:s,view:i,_viewIndex:r}}else return Ve.match(e)?{...t,selected:e.payload,selectedIds:os(e.payload)}:t}function pt({column:t,desc:e}){if(!t)return(i,r)=>0;const s=Ei[t];return(i,r)=>{const n=s(i),l=s(r);return n>l?e?-1:1:n{const{flows:i}=s();i.selectedIds.has(t.id)?e(Ve(i.selected.filter(r=>r!==t))):e(Ve([...i.selected,t]))}}function rc(t){return(e,s)=>{const{flows:i}=s(),r=i.selected[i.selected.length-1],n=i._viewIndex.get(t.id),l=i._viewIndex.get(r?.id);if(n===void 0||l===void 0)return e(Ve([t]));let a;return n<=l?a=i.view.slice(n,l+1):(a=i.view.slice(l+1,n+1),a.push(r)),e(Ve(a))}}const oc={activeModal:void 0},Bi=fe({name:"ui/modal",initialState:oc,reducers:{setActiveModal(t,e){t.activeModal=e.payload},hideModal(t){t.activeModal=void 0}}}),{actions:lc,reducer:cc}=Bi,ac=Bi.actions.hideModal.type,{setActiveModal:dc,hideModal:Wi}=lc,zn=(()=>{const t=document.createElement("div");return t.setAttribute("contenteditable","PLAINTEXT-ONLY"),t.contentEditable==="plaintext-only"?"plaintext-only":"true"})();class ce extends I.Component{input=Te.createRef();render(){const e=je("inline-input",this.props.className);return o.jsx("span",{ref:this.input,tabIndex:0,className:e,placeholder:this.props.placeholder,onFocus:this.onFocus,onBlur:this.onBlur,onKeyDown:this.onKeyDown,onInput:this.onInput,onPaste:this.onPaste,onMouseDown:this.onMouseDown,onClick:this.onClick,children:this.props.content})}componentDidUpdate(e){e.content!==this.props.content&&this.props.onInput?.(this.props.content)}isEditing=()=>this.input.current?.contentEditable===zn;startEditing=()=>{if(!this.input.current)return console.error("unreachable");this.isEditing()||(this.suppress_events=!0,this.input.current.blur(),this.input.current.contentEditable=zn,window.requestAnimationFrame(()=>{if(this.input.current){if(this.input.current.focus(),this.suppress_events=!1,this.props.selectAllOnClick){const e=document.createRange();e.selectNodeContents(this.input.current);const s=window.getSelection();s?.removeAllRanges(),s?.addRange(e)}this.props.onEditStart?.()}}))};resetValue=()=>{if(!this.input.current)return console.error("unreachable");this.input.current.textContent=this.props.content,this.props.onInput?.(this.props.content)};finishEditing=()=>{if(!this.input.current)return console.error("unreachable");this.props.onEditDone(this.input.current.textContent||""),this.input.current.blur(),this.input.current.contentEditable="inherit"};onPaste=e=>{e.preventDefault();const s=e.clipboardData.getData("text/plain");document.execCommand("insertHTML",!1,s)};suppress_events=!1;onMouseDown=e=>{this.suppress_events=!0,window.addEventListener("mouseup",this.onMouseUp,{once:!0})};onMouseUp=e=>{const s=e.target===this.input.current,i=!window.getSelection()?.toString();this.props.selectAllOnClick?s&&i&&this.startEditing():s&&this.startEditing(),this.suppress_events=!1};onClick=e=>{};onFocus=e=>{if(!this.input.current)throw"unreachable";this.suppress_events||this.startEditing()};onInput=e=>{this.props.onInput?.(this.input.current?.textContent||"")};onBlur=e=>{this.suppress_events||this.finishEditing()};onKeyDown=e=>{switch(e.stopPropagation(),e.key){case"Escape":e.preventDefault(),this.resetValue(),this.finishEditing();break;case"Enter":e.shiftKey||(e.preventDefault(),this.finishEditing());break}this.props.onKeyDown?.(e)}}function bt(t){const e=k.c(15);let s;e[0]!==t.content||e[1]!==t.isValid?(s=t.isValid(t.content),e[0]=t.content,e[1]=t.isValid,e[2]=s):s=e[2];const[i,r]=I.useState(s),n=I.useRef(null);let l;e[3]!==t?(l=_=>{t.isValid(_)?t.onEditDone(_):n.current?.resetValue()},e[3]=t,e[4]=l):l=e[4];const a=l,d=i?"has-success":"has-warning";let f;e[5]!==t.className||e[6]!==d?(f=je(t.className,d),e[5]=t.className,e[6]=d,e[7]=f):f=e[7];const p=f;let h;e[8]!==t?(h=_=>r(t.isValid(_)),e[8]=t,e[9]=h):h=e[9];let g;return e[10]!==p||e[11]!==a||e[12]!==t||e[13]!==h?(g=o.jsx(ce,{...t,className:p,onInput:h,onEditDone:a,ref:n}),e[10]=p,e[11]=a,e[12]=t,e[13]=h,e[14]=g):g=e[14],g}const G=()=>Nl(),D=kl,uc=ui.withTypes(),Ss=_e("EVENTS_ADD"),Ki=_e("EVENTS_RECEIVE"),Gt=_e("events/toggleVisibility"),zi=_e("events/toggleFilter");var Gi=(t=>(t.debug="debug",t.info="info",t.web="web",t.warn="warn",t.error="error",t))(Gi||{});const fc={visible:!1,filters:{debug:!1,info:!0,web:!0,warn:!0,error:!0},list:[],view:[]};function pc(t=fc,e){if(Ss.match(e)){const s=e.payload;return{...t,list:[...t.list,s],view:t.filters[s.level]?[...t.view,s]:t.view}}else{if(Ki.match(e))return{...t,list:e.payload,view:e.payload.filter(s=>t.filters[s.level])};if(Gt.match(e))return{...t,visible:!t.visible};if(zi.match(e)){const s={...t.filters,[e.payload]:!t.filters[e.payload]};return{...t,filters:s,view:t.list.filter(i=>s[i.level])}}else return t}}function hc(t,e="web"){return Ss({id:Math.random().toString(),message:t,level:e})}const Gn={},mc=fe({name:"ui/optionsEditor",initialState:Gn,reducers:{startUpdate(t,e){t[e.payload.option]={isUpdating:!0,value:e.payload.value,error:!1}},updateSuccess(t,e){t[e.payload.option]=void 0},updateError(t,e){let s=t[e.payload.option].value;typeof s=="boolean"&&(s=!s),t[e.payload.option]={value:s,isUpdating:!1,error:e.payload.error}}},extraReducers:t=>{t.addCase(ac,()=>Gn)}}),{actions:gc,reducer:vc}=mc,{startUpdate:xc,updateSuccess:_c,updateError:jc}=gc;var xe=(t=>(t[t.Capture=0]="Capture",t[t.FlowList=1]="FlowList",t[t.Options=2]="Options",t[t.Flow=3]="Flow",t))(xe||{});const yc=fe({name:"ui/tabs",initialState:{current:1},reducers:{setCurrent(t,e){t.current=e.payload}}}),{actions:wc,reducer:bc}=yc,{setCurrent:Vt}=wc,Sc=fi({flow:Vl,modal:cc,optionsEditor:vc,tabs:bc,filter:Jl});var wt=(t=>(t.INIT="CONNECTION_INIT",t.FETCHING="CONNECTION_FETCHING",t.ESTABLISHED="CONNECTION_ESTABLISHED",t.ERROR="CONNECTION_ERROR",t))(wt||{});const $c={state:"CONNECTION_INIT",message:void 0},Yi=fe({name:"connection",initialState:$c,reducers:{startFetching:t=>{t.state==="CONNECTION_INIT"&&(t.state="CONNECTION_FETCHING")},finishFetching:t=>{t.state==="CONNECTION_FETCHING"&&(t.state="CONNECTION_ESTABLISHED")},connectionError:(t,e)=>{t.state="CONNECTION_ERROR",t.message=e.payload}}}),{startFetching:Cc,finishFetching:Nc,connectionError:kc}=Yi.actions,Ec=Yi.reducer,Tc={add_upstream_certs_to_client_chain:!1,allow_hosts:[],anticache:!1,anticomp:!1,block_global:!0,block_list:[],block_private:!1,body_size_limit:void 0,cert_passphrase:void 0,certs:[],ciphers_client:void 0,ciphers_server:void 0,client_certs:void 0,client_replay:[],client_replay_concurrency:1,command_history:!0,confdir:"~/.mitmproxy",connect_addr:void 0,connection_strategy:"eager",console_focus_follow:!1,content_view_lines_cutoff:512,dns_name_servers:[],dns_use_hosts_file:!0,export_preserve_original_ip:!1,hardump:"",http2:!0,http2_ping_keepalive:58,http3:!0,http_connect_send_host_header:!0,ignore_hosts:[],intercept:void 0,intercept_active:!1,keep_alt_svc_header:!1,keep_host_header:!1,key_size:2048,listen_host:"",listen_port:void 0,map_local:[],map_remote:[],mode:["regular"],modify_body:[],modify_headers:[],normalize_outbound_headers:!0,onboarding:!0,onboarding_host:"mitm.it",protobuf_definitions:void 0,proxy_debug:!1,proxyauth:void 0,rawtcp:!0,readfile_filter:void 0,request_client_cert:!1,rfile:void 0,save_stream_file:void 0,save_stream_filter:void 0,scripts:[],server:!0,server_replay:[],server_replay_extra:"forward",server_replay_ignore_content:!1,server_replay_ignore_host:!1,server_replay_ignore_params:[],server_replay_ignore_payload_params:[],server_replay_ignore_port:!1,server_replay_kill_extra:!1,server_replay_nopop:!1,server_replay_refresh:!0,server_replay_reuse:!1,server_replay_use_headers:[],show_ignored_hosts:!1,showhost:!1,ssl_insecure:!1,ssl_verify_upstream_trusted_ca:void 0,ssl_verify_upstream_trusted_confdir:void 0,stickyauth:void 0,stickycookie:void 0,store_streamed_bodies:!1,stream_large_bodies:void 0,strip_ech:!0,tcp_hosts:[],tcp_timeout:600,termlog_verbosity:"info",tls_ecdh_curve_client:void 0,tls_ecdh_curve_server:void 0,tls_version_client_max:"UNBOUNDED",tls_version_client_min:"TLS1_2",tls_version_server_max:"UNBOUNDED",tls_version_server_min:"TLS1_2",udp_hosts:[],upstream_auth:void 0,upstream_cert:!0,validate_inbound_headers:!0,view_filter:void 0,view_order:"time",view_order_reversed:!1,web_columns:["tls","icon","path","method","status","size","time"],web_debug:!1,web_host:"127.0.0.1",web_open_browser:!0,web_password:"",web_port:8081,web_static_viewer:"",websocket:!0},Yt=_e("OPTIONS_RECEIVE"),$s=_e("OPTIONS_UPDATE"),Rc=fe({name:"options",initialState:Tc,reducers:{},extraReducers:t=>{t.addCase(Yt,(e,s)=>{const i={};for(const[r,{value:n}]of Object.entries(s.payload))i[r]=n;return i}).addCase($s,(e,s)=>{for(const[i,{value:r}]of Object.entries(s.payload))e[i]=r})}}),Ac=Rc.reducer;async function Dc(t,e,s){try{const i=await ne.put("/options",{[t]:e});if(i.status===200)s(_c({option:t}));else throw await i.text()}catch(i){s(jc({option:t,error:i.toString()}))}}const Fc=Dc;function Cs(t,e){return s=>{s(xc({option:t,value:e})),Fc(t,e,s)}}const Ic={visible:!1},Lc=fe({name:"commandBar",initialState:Ic,reducers:{toggleVisibility(t){t.visible=!t.visible}}}),{actions:Pc,reducer:Oc}=Lc,{toggleVisibility:Ji}=Pc,Ue=_e("STATE_RECEIVE"),Be=_e("STATE_UPDATE"),Mc={available:!1,version:"",contentViews:[],servers:{},platform:"",localModeUnavailable:null},qc=fe({name:"backendState",initialState:Mc,reducers:{},extraReducers:t=>{t.addCase(Ue,(e,s)=>({...e,available:!0,...s.payload})).addCase(Be,(e,s)=>({...e,...s.payload}))}}),Hc=qc.reducer,Vc={},Uc=fe({name:"optionsMeta",initialState:Vc,reducers:{},extraReducers:t=>{t.addCase(Yt,(e,s)=>s.payload).addCase($s,(e,s)=>({...e,...s.payload}))}}),Bc=Uc.reducer,dt=(t,e)=>e.listen_host&&e.listen_port?`${t}@${e.listen_host}:${e.listen_port}`:e.listen_port?`${t}@${e.listen_port}`:t,Qi=t=>{let[e,s]=ps(t,"@");e||(e=s,s="");const[i,r]=vi(e,":");let n,l;if(s){let a;if(s.includes(":")?[n,a]=ps(s,":"):(n="",a=s),a&&(l=parseInt(a,10),isNaN(l)||l<0||l>65535))throw new Error(`invalid port: ${a}`)}return{full_spec:t,name:i,data:r,listen_host:n,listen_port:l}},Xi=t=>dt("regular",t),Yn=({listen_host:t,listen_port:e})=>({ui_id:Math.random(),active:!0,listen_host:t,listen_port:e}),Zi=t=>t.selectedProcesses?`local:${t.selectedProcesses}`:"local",Jn=({data:t})=>({ui_id:Math.random(),active:!0,selectedProcesses:t}),er=t=>{const e=t.file_path?`wireguard:${t.file_path}`:"wireguard";return dt(e,t)},Qn=({data:t,listen_host:e,listen_port:s})=>({ui_id:Math.random(),active:!0,listen_host:e,listen_port:s,file_path:t});var Jt=(t=>(t.HTTP="http",t.HTTPS="https",t.HTTP3="http3",t.TLS="tls",t.DTLS="dtls",t.TCP="tcp",t.UDP="udp",t.DNS="dns",t.QUIC="quic",t))(Jt||{}),ot=(t=>(t.CSS="css",t.JAVASCRIPT="javascript",t.XML="xml",t.YAML="yaml",t.NONE="none",t.ERROR="error",t))(ot||{});const hs=()=>({active:!1,protocol:Jt.HTTPS,destination:"",ui_id:Math.random()}),Ns=t=>dt(`reverse:${t.protocol}://${t.destination}`,t),Wc=({data:t,listen_host:e,listen_port:s})=>{let[i,r]=vi(t,"://");return r||(r=i,i=Jt.HTTPS),{ui_id:Math.random(),active:!0,protocol:i,destination:r,listen_host:e,listen_port:s}},tr=t=>dt("transparent",t),Xn=({listen_host:t,listen_port:e})=>({ui_id:Math.random(),active:!0,listen_host:t,listen_port:e}),sr=t=>dt("socks5",t),Zn=({listen_host:t,listen_port:e})=>({ui_id:Math.random(),active:!0,listen_host:t,listen_port:e}),nr=t=>dt(`upstream:${t.destination}`,t),ei=({data:t,listen_host:e,listen_port:s})=>({ui_id:Math.random(),active:!0,destination:t||"",listen_host:e,listen_port:s}),ir=t=>dt("dns",t),ti=({listen_host:t,listen_port:e})=>({ui_id:Math.random(),active:!0,listen_host:t,listen_port:e}),Xe=t=>t.active&&!t.error;async function Kc(t,e){const s=e.getState().modes,i=[...s.regular.filter(Xe).map(Xi),...s.local.filter(Xe).map(Zi),...s.wireguard.filter(Xe).map(er),...s.reverse.filter(Xe).map(Ns),...s.transparent.filter(Xe).map(tr),...s.socks.filter(Xe).map(sr),...s.upstream.filter(Xe).map(nr),...s.dns.filter(Xe).map(ir)],r=await ne.put("/options",{mode:i});if(r.status!==200)throw new Error(await r.text())}function ie(t){return uc(t,Kc)}function se(t,e,s){t.addCase(s.pending,(i,r)=>{const{server:n,value:l}=r.meta.arg,a=i.findIndex(d=>d.ui_id===n.ui_id);a>=0&&(i[a][e]=l,i[a].error=void 0)}),t.addCase(s.rejected,(i,r)=>{const{server:n}=r.meta.arg,l=i.findIndex(a=>a.ui_id===n.ui_id);l>=0&&(i[l].error=r.error.message)})}function be(t,e){return function(i,r){if(r.payload.servers){const n=Object.values(r.payload.servers).filter(l=>l.type===t).map(l=>Qi(l.full_spec));if(n.length>0)return n.map(e);for(const l of i)l.active=!1}}}const rr=ie("modes/regular/setActive"),or=ie("modes/regular/setListenHost"),lr=ie("modes/regular/setListenPort"),zc=[{active:!0,ui_id:Math.random()}],Gc=fe({name:"modes/regular",initialState:zc,reducers:{},extraReducers:t=>{se(t,"active",rr),se(t,"listen_host",or),se(t,"listen_port",lr),t.addCase(Ue,be("regular",Yn)),t.addCase(Be,be("regular",Yn))}}),Yc=Gc.reducer,cr=ie("modes/local/setActive"),St=ie("modes/local/setSelectedProcesses"),Jc=[{active:!1,selectedProcesses:"",ui_id:Math.random()}],Qc=fe({name:"modes/local",initialState:Jc,reducers:{},extraReducers:t=>{se(t,"active",cr),se(t,"selectedProcesses",St),t.addCase(Ue,be("local",Jn)),t.addCase(Be,be("local",Jn))}}),Xc=Qc.reducer,ar=ie("modes/wireguard/setActive"),dr=ie("modes/wireguard/setListenHost"),ur=ie("modes/wireguard/setListenPort"),fr=ie("modes/wireguard/setFilePath"),Zc=[{active:!1,ui_id:Math.random()}],ea=fe({name:"modes/wireguard",initialState:Zc,reducers:{},extraReducers:t=>{se(t,"active",ar),se(t,"listen_host",dr),se(t,"listen_port",ur),se(t,"file_path",fr),t.addCase(Ue,be("wireguard",Qn)),t.addCase(Be,be("wireguard",Qn))}}),ta=ea.reducer,ms=ie("modes/reverse/setActive"),pr=ie("modes/reverse/setListenHost"),hr=ie("modes/reverse/setListenPort"),mr=ie("modes/reverse/setProtocol"),gr=ie("modes/reverse/setDestination"),sa=[hs()],vr=fe({name:"modes/reverse",initialState:sa,reducers:{addServer:t=>{t.push(hs())},removeServer:(t,e)=>{const s=t.findIndex(i=>i.ui_id===e.payload.ui_id);s!==-1&&(t[s].active&&console.error("servers should be deactivated before removal"),t.splice(s,1))}},extraReducers:t=>{se(t,"active",ms),se(t,"listen_host",pr),se(t,"listen_port",hr),se(t,"protocol",mr),se(t,"destination",gr),t.addCase(Ue,e),t.addCase(Be,e);function e(s,i){if(i.payload.servers){const r=Object.fromEntries(Object.entries(i.payload.servers).filter(([l,a])=>a.type==="reverse").map(([l,a])=>[l,Qi(l)])),n=[];for(const l of s){const a=Ns(l),d=a in r;delete r[a],n.push({...l,active:d})}for(const l of Object.values(r))n.push(Wc(l));return n.length>1&&Kt({...n[0],ui_id:void 0},{...hs(),ui_id:void 0})&&n.shift(),n}}}}),{addServer:na,removeServer:ia}=vr.actions,ra=vr.reducer,xr=ie("modes/transparent/setActive"),_r=ie("modes/transparent/setListenHost"),jr=ie("modes/transparent/setListenPort"),oa=[{active:!1,ui_id:Math.random()}],la=fe({name:"modes/transparent",initialState:oa,reducers:{},extraReducers:t=>{se(t,"active",xr),se(t,"listen_host",_r),se(t,"listen_port",jr),t.addCase(Ue,be("transparent",Xn)),t.addCase(Be,be("transparent",Xn))}}),ca=la.reducer,yr=ie("modes/socks5/setActive"),wr=ie("modes/socks5/setListenHost"),br=ie("modes/socks5/setListenPort"),aa=[{active:!1,ui_id:Math.random()}],da=fe({name:"modes/socks5",initialState:aa,reducers:{},extraReducers:t=>{se(t,"active",yr),se(t,"listen_host",wr),se(t,"listen_port",br),t.addCase(Ue,be("socks5",Zn)),t.addCase(Be,be("socks5",Zn))}}),ua=da.reducer,Sr=ie("modes/upstream/setActive"),$r=ie("modes/upstream/setListenHost"),Cr=ie("modes/upstream/setListenPort"),Nr=ie("modes/upstream/setDestination"),fa=[{active:!1,destination:"",ui_id:Math.random()}],pa=fe({name:"modes/upstream",initialState:fa,reducers:{},extraReducers:t=>{se(t,"active",Sr),se(t,"listen_host",$r),se(t,"listen_port",Cr),se(t,"destination",Nr),t.addCase(Ue,be("upstream",ei)),t.addCase(Be,be("upstream",ei))}}),ha=pa.reducer,kr=ie("modes/dns/setActive"),Er=ie("modes/dns/setListenHost"),Tr=ie("modes/dns/setListenPort"),ma=[{active:!0,ui_id:Math.random()}],ga=fe({name:"modes/dns",initialState:ma,reducers:{},extraReducers:t=>{se(t,"active",kr),se(t,"listen_host",Er),se(t,"listen_port",Tr),t.addCase(Ue,be("dns",ti)),t.addCase(Be,be("dns",ti))}}),va=ga.reducer,xa=fi({regular:Yc,local:Xc,wireguard:ta,reverse:ra,transparent:ca,socks:ua,upstream:ha,dns:va}),$t=ui("fetchProcesses",async(t,{rejectWithValue:e})=>{try{return(await ne("/processes")).json()}catch(s){return e(s.message)}}),_a={currentProcesses:[],isLoading:!1},ja=fe({name:"processes",initialState:_a,reducers:{},extraReducers:t=>{t.addCase($t.pending,e=>{e.isLoading=!0,e.error=void 0}),t.addCase($t.fulfilled,(e,s)=>{e.isLoading=!1,e.currentProcesses=s.payload}),t.addCase($t.rejected,(e,s)=>{e.isLoading=!1,e.error=s.payload})}}),ya=ja.reducer,wa={commandBar:Oc,eventLog:pc,flows:nc,connection:Ec,modes:xa,ui:Sc,options:Ac,options_meta:Bc,backendState:Hc,processes:ya},ba={immutableCheck:{warnAfter:5e5},serializableCheck:{warnAfter:5e5,ignoredPaths:["flows"]}},Nt=El({reducer:wa,middleware:t=>t(ba),devTools:!1});class Sa extends I.Component{container=Te.createRef();nameInput=Te.createRef();valueInput=Te.createRef();render=()=>{const[e,s]=this.props.item;return o.jsxs("div",{ref:this.container,className:"kv-row",onClick:this.onClick,onKeyDownCapture:this.onKeyDown,children:[o.jsx(ce,{ref:this.nameInput,className:"kv-key",content:e,onEditStart:this.props.onEditStart,onEditDone:i=>this.props.onEditDone([i,s]),selectAllOnClick:!0}),": ",o.jsx(ce,{ref:this.valueInput,className:"kv-value",content:s,onEditStart:this.props.onEditStart,onEditDone:i=>this.props.onEditDone([e,i]),placeholder:"empty",selectAllOnClick:!0})]})};onClick=e=>{e.target===this.container.current&&this.props.onClickEmptyArea()};onKeyDown=e=>{e.target===this.valueInput.current?.input.current&&e.key==="Tab"&&this.props.onTabNext()}}class Rr extends I.Component{rowRefs={};currentlyEditing;justFinishedEditing;state={currentList:this.props.data||[],initialList:this.props.data};static getDerivedStateFromProps(e,s){return e.data!==s.initialList?{currentList:e.data||[],initialList:e.data}:null}render=()=>{this.rowRefs={};const e=this.state.currentList.map((s,i)=>o.jsx(Sa,{item:s,onEditStart:()=>this.currentlyEditing=i,onEditDone:r=>this.onEditDone(i,r),onClickEmptyArea:()=>this.onClickEmptyArea(i),onTabNext:()=>this.onTabNext(i),ref:r=>{this.rowRefs[i]=r}},i));return o.jsxs("div",{className:je("kv-editor",this.props.className),onMouseDown:this.onMouseDown,children:[e,o.jsx("div",{onClick:s=>{s.preventDefault(),this.onClickEmptyArea(this.state.currentList.length-1)},className:"kv-add-row fa fa-plus-square-o",role:"button","aria-label":"Add"})]})};onEditDone=(e,s)=>{const i=[...this.state.currentList];s[0]?i[e]=s:i.splice(e,1),this.currentlyEditing=void 0,Ht.isEqual(this.state.currentList,i)||this.props.onChange(i),this.setState({currentList:i})};onClickEmptyArea=e=>{if(this.justFinishedEditing)return;const s=[...this.state.currentList];s.splice(e+1,0,["",""]),this.setState({currentList:s},()=>this.rowRefs[e+1]?.nameInput.current?.startEditing())};onTabNext=e=>{e==this.state.currentList.length-1&&this.onClickEmptyArea(e)};onMouseDown=e=>{this.justFinishedEditing=this.currentlyEditing}}function Ar(t,e){const s=k.c(6),[i,r]=I.useState(),[n,l]=I.useState();let a;s[0]!==n||s[1]!==t?(a=()=>{n&&n.abort();const f=new AbortController;return ne(t,{signal:f.signal}).then($a).then(p=>{r(p)}).catch(p=>{f.signal.aborted||r(`Error getting content: ${p}.`)}),l(f),()=>{f.signal.aborted||f.abort()}},s[0]=n,s[1]=t,s[2]=a):a=s[2];let d;return s[3]!==e||s[4]!==t?(d=[t,e],s[3]=e,s[4]=t,s[5]=d):d=s[5],I.useEffect(a,d),i}function $a(t){if(!t.ok)throw`${t.status} ${t.statusText}`.trim();return t.text()}function Dr(t,e,s,i,r){const n=k.c(11);let l;n[0]!==t||n[1]!==i||n[2]!==e||n[3]!==s?(l=we.getContentURL(t,e,s,i),n[0]=t,n[1]=i,n[2]=e,n[3]=s,n[4]=l):l=n[4];const d=Ar(l,r);let f;if(d)try{let p;n[5]!==d?(p=JSON.parse(d),n[5]=d,n[6]=p):p=n[6],f=p}catch{let p;n[7]!==d?(p={text:d,description:"Network Error",syntax_highlight:"error",view_name:"raw"},n[7]=d,n[8]=p):p=n[8];const h=p;if(e==="messages"){let g;n[9]!==h?(g=[h],n[9]=h,n[10]=g):g=n[10],f=g}else f=h}else f=void 0;return f}const Fr=Te.memo(function({icon:e,text:s,className:i,title:r,onOpenFile:n,onClick:l}){let a;return o.jsxs("a",{href:"#",onClick:d=>{a.click(),l&&l(d)},className:i,title:r,children:[o.jsx("i",{className:"fa fa-fw "+e}),s,o.jsx("input",{ref:d=>{a=d},className:"hidden",type:"file",onChange:d=>{d.preventDefault(),d.target.files&&d.target.files.length>0&&n(d.target.files[0]),a.value=""}})]})});function pe(t){const e=k.c(11),{onClick:s,children:i,icon:r,disabled:n,className:l,title:a}=t;let d;e[0]!==l?(d=je(l,"btn btn-default"),e[0]=l,e[1]=d):d=e[1];const f=n?void 0:s;let p;e[2]!==r?(p=r&&o.jsxs(o.Fragment,{children:[o.jsx("i",{className:"fa "+r})," "]}),e[2]=r,e[3]=p):p=e[3];let h;return e[4]!==i||e[5]!==n||e[6]!==d||e[7]!==f||e[8]!==p||e[9]!==a?(h=o.jsxs("button",{className:d,onClick:f,disabled:n,title:a,children:[p,i]}),e[4]=i,e[5]=n,e[6]=d,e[7]=f,e[8]=p,e[9]=a,e[10]=h):h=e[10],h}function Ca(t){const e=k.c(11),{initialContent:s,onChange:i,language:r,readonly:n}=t,l=n===void 0?!1:n,a=Na;let d;e:switch(r){case ot.YAML:{let h;e[0]===Symbol.for("react.memo_cache_sentinel")?(h=[Dl()],e[0]=h):h=e[0],d=h;break e}case ot.XML:{let h;e[1]===Symbol.for("react.memo_cache_sentinel")?(h=[Al()],e[1]=h):h=e[1],d=h;break e}case ot.JAVASCRIPT:{let h;e[2]===Symbol.for("react.memo_cache_sentinel")?(h=[Rl()],e[2]=h):h=e[2],d=h;break e}case ot.CSS:{let h;e[3]===Symbol.for("react.memo_cache_sentinel")?(h=[Tl()],e[3]=h):h=e[3],d=h;break e}case void 0:case null:case ot.NONE:case ot.ERROR:{let h;e[4]===Symbol.for("react.memo_cache_sentinel")?(h=[],e[4]=h):h=e[4],d=h;break e}default:{console.error("Unexpected syntax highlighting language: ",r);let g;e[5]===Symbol.for("react.memo_cache_sentinel")?(g=[],e[5]=g):g=e[5],d=g}}const f=d;let p;return e[6]!==f||e[7]!==s||e[8]!==i||e[9]!==l?(p=o.jsx("div",{className:"codeeditor",onKeyDown:a,children:o.jsx(Fl,{value:s,onChange:i,readOnly:l,extensions:f})}),e[6]=f,e[7]=s,e[8]=i,e[9]=l,e[10]=p):p=e[10],p}function Na(t){return t.stopPropagation()}const Ir=Te.memo(function(e){const s=k.c(9),{content:i,maxLines:r,showMore:n}=e;if(i.length===0)return null;let l;if(s[0]!==i||s[1]!==r||s[2]!==n){let d;s[4]!==r||s[5]!==n?(d=(f,p)=>p===r?o.jsxs("button",{onClick:n,className:"btn btn-xs btn-info",children:[o.jsx("i",{className:"fa fa-angle-double-down","aria-hidden":"true"})," ","Show more"]},"showmore"):o.jsx("div",{children:f},p),s[4]=r,s[5]=n,s[6]=d):d=s[6],l=i.split(` +import{c as fe,R as Cl,a as _e,r as I,b as Te,d as je,j as o,e as k,f as ui,u as Nl,g as kl,h as fi,s as Kt,i as El,l as Ht,k as Tl,m as Rl,n as Al,y as Dl,o as Fl,p as Il,q as zt,Q as Ll,t as Pl,P as Ol}from"./vendor-BS4xPthR.js";(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))i(r);new MutationObserver(r=>{for(const n of r)if(n.type==="childList")for(const l of n.addedNodes)l.tagName==="LINK"&&l.rel==="modulepreload"&&i(l)}).observe(document,{childList:!0,subtree:!0});function s(r){const n={};return r.integrity&&(n.integrity=r.integrity),r.referrerPolicy&&(n.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?n.credentials="include":r.crossOrigin==="anonymous"?n.credentials="omit":n.credentials="same-origin",n}function i(r){if(r.ep)return;r.ep=!0;const n=s(r);fetch(r.href,n)}})();const Ml={tab:"request",contentViewFor:{}},ql=fe({name:"ui/flow",initialState:Ml,reducers:{selectTab(t,e){t.tab=e.payload},setContentViewFor(t,e){t.contentViewFor[e.payload.messageId]=e.payload.contentView}}}),{actions:Hl,reducer:Vl}=ql,{selectTab:Ut,setContentViewFor:pi}=Hl;window.React=Cl;const hi=function(t){if(t===0)return"0";const e=["b","kb","mb","gb","tb"];let s=0;for(;st);s++);let i;return t%Math.pow(1024,s)===0?i=0:i=1,(t/Math.pow(1024,s)).toFixed(i)+e[s]},mi=function(t){let e=t;const s=["ms","s","min","h"],i=[1e3,60,60];let r=0;for(;Math.abs(e)>=i[r]&&r{const t=Ul("_mitmproxy_xsrf");return fs=()=>t,fs()};function ne(t,e={}){return e.method&&e.method!=="GET"&&(e.headers=e.headers||{},e.headers["X-XSRFToken"]=fs()),t.startsWith("/")&&(t="."+t),fetch(t,{credentials:"same-origin",...e})}ne.put=(t,e,s={})=>ne(t,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(e),...s});ne.post=(t,e,s={})=>ne(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e),...s});async function Bt(t,...e){return await(await ne(`/commands/${t}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({arguments:e})})).json()}async function gi(t){try{await navigator.clipboard.write([new ClipboardItem({"text/plain":t})]);return}catch(i){console.warn(i)}const e=await t;try{await navigator.clipboard.writeText(e);return}catch(i){console.warn(i)}const s=document.createElement("textarea");s.value=e,s.style.position="absolute",s.style.opacity="0",document.body.appendChild(s);try{if(s.focus(),s.select(),!document.execCommand("copy"))throw"failed to copy"}catch{alert(e)}finally{s.remove()}}async function Bl(t){await gi(Promise.resolve(t?.text||""))}function ps(t,e){const s=t.lastIndexOf(e);if(s===-1)return["",t];const i=t.slice(0,s),r=t.slice(s+e.length);return[i,r]}function vi(t,e){const s=t.indexOf(e);if(s===-1)return[t,""];const i=t.slice(0,s),r=t.slice(s+e.length);return[i,r]}function Ct(t){throw new Error(`Unreachable: ${JSON.stringify(t)}`)}const xi={http:80,https:443},Vn=new WeakMap;class we{static getContentType(e){const s=we.get_first_header(e,/^Content-Type$/i);if(s)return s.split(";")[0].trim()}static get_first_header(e,s){let i=Vn.get(e);i||(i=new Map,Vn.set(e,i));let r=i.get(s);if(r===void 0){const n=e.headers.find(([l,a])=>s.test(l));r=n?n[1]:!1,i.set(s,r)}return r!==!1?r:void 0}static match_header(e,s){const i=e.headers;if(!i)return!1;let r=i.length;for(;r--;)if(s.test(i[r].join(" ")))return i[r];return!1}static getContentURL(e,s,i,r){e.type==="http"&&s===e.request?s="request":e.type==="http"&&s===e.response&&(s="response");const n=r?`?lines=${r}`:"";return`./flows/${e.id}/${s}/`+(i?`content/${encodeURIComponent(i)}.json${n}`:"content.data")}}class ct extends we{static pretty_url(e){let s="";return xi[e.scheme]!==e.port&&(s=":"+e.port),e.scheme+"://"+e.pretty_host+s+e.path}}class mt extends we{}const Wl=/^(?:(https?):\/\/)?([^/:]+)?(?::(\d+))?(\/.*)?$/i,_i=function(t){const e=Wl.exec(t);if(!e)return;const s=e[1],i=e[2],r=parseInt(e[3]),n=e[4],l=s?r||xi[s]:r,a={};return s&&(a.scheme=s),i&&(a.host=i),l&&(a.port=l),n&&(a.path=n),a},Kl=/^HTTP\/\d+(\.\d+)*$/i,ji=function(t){return Kl.test(t)};function Wt(t){switch(t.type){case"http":return t.request.timestamp_start;case"tcp":case"udp":return t.client_conn.timestamp_start;case"dns":return t.request.timestamp}}function yi(t){switch(t.type){case"http":if(t.websocket){if(t.websocket.timestamp_end)return t.websocket.timestamp_end;if(t.websocket.messages_meta.timestamp_last)return t.websocket.messages_meta.timestamp_last}return t.response?t.response.timestamp_end:void 0;case"tcp":return t.server_conn?.timestamp_end;case"udp":return t.messages_meta.timestamp_last;case"dns":return t.response?.timestamp}}const wi=t=>{switch(t.type){case"http":{let e=t.request.contentLength||0;return t.response&&(e+=t.response.contentLength||0),t.websocket&&(e+=t.websocket.messages_meta.contentLength||0),e}case"tcp":case"udp":return t.messages_meta.contentLength||0;case"dns":return t.response?.size??0}},xs=t=>t.type==="http"&&!t.websocket,bi=t=>t.modified,_s=t=>t.intercepted,Si=t=>{if(t.type!=="http")return t.client_conn.tls_version==="QUICv1"?"resource-icon-quic":`resource-icon-${t.type}`;if(t.websocket)return"resource-icon-websocket";if(!t.response)return"resource-icon-plain";const e=mt.getContentType(t.response)||"";return t.response.status_code===304?"resource-icon-not-modified":300<=t.response.status_code&&t.response.status_code<400?"resource-icon-redirect":e.indexOf("image")>=0?"resource-icon-image":e.indexOf("javascript")>=0?"resource-icon-js":e.indexOf("css")>=0?"resource-icon-css":e.indexOf("html")>=0?"resource-icon-document":"resource-icon-plain"},$i=t=>{switch(t.type){case"http":return ct.pretty_url(t.request);case"tcp":case"udp":return`${t.client_conn.peername.join(":")} ↔ ${t.server_conn?.address?.join(":")}`;case"dns":return`${t.request.questions.map(e=>`${e.name} ${e.type}`).join(", ")} = ${(t.response?.answers.map(e=>e.data).join(", ")??"...")||"?"}`}},Ci=t=>{switch(t.type){case"http":return t.response?.status_code;case"dns":return t.response?.response_code;default:return}},Ni=t=>{switch(t.type){case"http":return t.websocket?t.client_conn.tls_established?"WSS":"WS":t.request.method;case"dns":return t.request.op_code;default:return t.type.toUpperCase()}},ki=t=>{switch(t.type){case"http":return t.request.http_version;default:return""}},Ei={tls:t=>t.type==="http"&&t.request.scheme,icon:Si,index:()=>0,path:$i,method:Ni,version:ki,status:Ci,size:wi,time:t=>{const e=Wt(t),s=yi(t);return e&&s&&s-e},timestamp:Wt,quickactions:()=>0,comment:t=>t.comment};function zl(t){return t in Ei}var ve=(t=>(t.Search="search",t.Highlight="highlight",t))(ve||{});const Ti={search:"",highlight:""},Gl=fe({name:"ui/filters",initialState:Ti,reducers:{setFilter(t,e){t.search=e.payload},setHighlight(t,e){t.highlight=e.payload}}}),{actions:Yl,reducer:Jl}=Gl,{setFilter:Ri,setHighlight:Ai}=Yl;function rs(t,e){return t.toSorted?t.toSorted(e):[...t].sort(e)}function js(t,...e){if(t.toSpliced)return t.toSpliced(...e);{const s=[...t];return s.splice(...e),s}}function jt(t){return new Map(t.map((e,s)=>[e.id,s]))}function os(t){return new Set(t.map(e=>e.id))}function Un(t,e){return t.has(e)&&(t=new Set(t),t.delete(e)),t}function Bn(t,e,s){const i=js(t,s,1),r=new Map(e);r.delete(t[s].id);for(let n=i.length-1;n>=s;n--)r.set(i[n].id,n);return{view:i,_viewIndex:r}}function Ql(t,e,s,i){const r=[...t],n=r.length;let l=e,a=l.get(s.id);if(a+10){l=new Map(l);do{const d=r[a+1];r[a]=d,l.set(d.id,a),a++}while(a+10);l.set(s.id,a)}else if(a>0&&i(s,r[a-1])<0){l=new Map(l);do{const d=r[a-1];r[a]=d,l.set(d.id,a),a--}while(a>0&&i(s,r[a-1])<0);l.set(s.id,a)}return r[a]=s,{view:r,_viewIndex:l}}function Wn(t,e,s,i){const r=Xl(t,s,i),n=js(t,r,0,s),l=new Map(e);for(let a=n.length-1;a>=r;a--)l.set(n[a].id,a);return{view:n,_viewIndex:l}}function Xl(t,e,s){let i=0,r=t.length;if(r===0||s(t[r-1],e)<=0)return r;for(;i>>1;s(e,t[n])>=0?i=n+1:r=n}return i}function ys(t){return t=t.filter(_s),()=>Promise.all(t.map(e=>ne(`/flows/${e.id}/resume`,{method:"POST"})))}function Di(){return()=>ne("/flows/resume",{method:"POST"})}function Fi(t){return t=t.filter(_s),()=>Promise.all(t.map(e=>ne(`/flows/${e.id}/kill`,{method:"POST"})))}function Zl(){return()=>ne("/flows/kill",{method:"POST"})}function Ii(t){return()=>Promise.all(t.map(e=>ne(`/flows/${e.id}`,{method:"DELETE"})))}function Li(t){return()=>Promise.all(t.map(e=>ne(`/flows/${e.id}/duplicate`,{method:"POST"})))}function ws(t){return t=t.filter(xs),()=>Promise.all(t.map(e=>ne(`/flows/${e.id}/replay`,{method:"POST"})))}function Pi(t){return t=t.filter(bi),()=>Promise.all(t.map(e=>ne(`/flows/${e.id}/revert`,{method:"POST"})))}function Kn(t,e){return()=>Promise.all(t.map(s=>Le(s,{marked:e})()))}function Le(t,e){return()=>ne.put(`/flows/${t.id}`,e)}function ec(t,e,s){const i=new FormData;return e=new window.Blob([e],{type:"plain/text"}),i.append("file",e),()=>ne(`/flows/${t.id}/${s}/content.data`,{method:"POST",body:i})}function Oi(){return()=>ne("/clear",{method:"POST"})}function tc(t){const e=new FormData;return e.append("file",t),()=>ne("/flows/dump",{method:"POST",body:e})}const Mi=_e("flows/add"),qi=_e("flows/update"),Hi=_e("flows/remove"),bs=_e("flows/receive"),Vi=_e("flows/filterUpdate"),Ui=_e("flows/sort"),Ve=_e("flows/select"),sc={list:[],_listIndex:new Map,byId:new Map,view:[],_viewIndex:new Map,sort:{column:void 0,desc:!1},selected:[],selectedIds:new Set,highlightedIds:new Set};function nc(t=sc,e){if(bs.match(e)){const{sort:s}=t,i=e.payload,r=jt(i),n=new Map(i.map(h=>[h.id,h])),l=rs(i,pt(s)),a=jt(l),d=t.selected.map(h=>n.get(h.id)).filter(h=>h!==void 0),f=os(d);return{list:i,_listIndex:r,byId:n,view:l,_viewIndex:a,sort:s,selected:d,selectedIds:f,highlightedIds:new Set}}else if(Mi.match(e)){const{flow:s,matching_filters:i}=e.payload;if(t._listIndex.has(s.id))return t;const{sort:r,selected:n,selectedIds:l}=t;let{view:a,_viewIndex:d,highlightedIds:f}=t;const p=new Map(t._listIndex);p.set(s.id,t.list.length);const h=[...t.list,s],g=new Map(t.byId);return g.set(s.id,s),(i[ve.Search]===!0||i[ve.Search]===void 0)&&({view:a,_viewIndex:d}=Wn(a,d,s,pt(r))),i[ve.Highlight]===!0&&(f=new Set(f),f.add(s.id)),{list:h,_listIndex:p,byId:g,view:a,_viewIndex:d,sort:r,selected:n,selectedIds:l,highlightedIds:f}}else if(qi.match(e)){const{flow:s,matching_filters:i}=e.payload,{_listIndex:r,sort:n,selectedIds:l}=t;let{view:a,_viewIndex:d,selected:f,highlightedIds:p}=t;const h=t._listIndex.get(s.id),g=[...t.list];h!==void 0?g[h]=s:g.push(s);const _=new Map(t.byId);_.set(s.id,s);const j=d.get(s.id),y=j!==void 0,w=i[ve.Search]===!0||i[ve.Search]===void 0;return w&&!y?{view:a,_viewIndex:d}=Wn(a,d,s,pt(n)):!w&&y?{view:a,_viewIndex:d}=Bn(a,d,j):w&&y&&({view:a,_viewIndex:d}=Ql(a,d,s,pt(n))),l.has(s.id)&&(f=f.map($=>$.id===s.id?s:$)),i[ve.Highlight]===!0?p.has(s.id)||(p=new Set(p),p.add(s.id)):p=Un(p,s.id),{list:g,_listIndex:r,byId:_,view:a,_viewIndex:d,sort:n,selected:f,selectedIds:l,highlightedIds:p}}else if(Hi.match(e)){const s=e.payload,{sort:i}=t;let{view:r,_viewIndex:n,selected:l,selectedIds:a}=t;const d=t._listIndex.get(s);if(d===void 0)return t;const f=js(t.list,d,1),p=jt(f),h=new Map(t.byId);h.delete(s);const g=n.get(s);if(g!==void 0&&({view:r,_viewIndex:n}=Bn(r,n,g)),a.has(s)){if(l.length===1&&g!==void 0){const j=r[g]??r[g-1];l=j?[j]:[]}else l=l.filter(j=>j.id!==s);a=os(l)}const _=Un(t.highlightedIds,s);return{list:f,_listIndex:p,byId:h,view:r,_viewIndex:n,sort:i,selected:l,selectedIds:a,highlightedIds:_}}else if(Vi.match(e)){const{name:s,matching_flow_ids:i}=e.payload;switch(s){case ve.Search:{const r=rs(i===null?t.list:i.map(l=>t.byId.get(l)).filter(l=>l!==void 0),pt(t.sort)),n=jt(r);return{...t,view:r,_viewIndex:n}}case ve.Highlight:return{...t,highlightedIds:new Set(i)};default:Ct(s)}}else if(Ui.match(e)){const s=e.payload;let i;s.column?i=rs(t.view,pt(s)):i=t.list.filter(n=>t._viewIndex.has(n.id));const r=jt(i);return{...t,sort:s,view:i,_viewIndex:r}}else return Ve.match(e)?{...t,selected:e.payload,selectedIds:os(e.payload)}:t}function pt({column:t,desc:e}){if(!t)return(i,r)=>0;const s=Ei[t];return(i,r)=>{const n=s(i),l=s(r);return n>l?e?-1:1:n{const{flows:i}=s();i.selectedIds.has(t.id)?e(Ve(i.selected.filter(r=>r!==t))):e(Ve([...i.selected,t]))}}function rc(t){return(e,s)=>{const{flows:i}=s(),r=i.selected[i.selected.length-1],n=i._viewIndex.get(t.id),l=i._viewIndex.get(r?.id);if(n===void 0||l===void 0)return e(Ve([t]));let a;return n<=l?a=i.view.slice(n,l+1):(a=i.view.slice(l+1,n+1),a.push(r)),e(Ve(a))}}const oc={activeModal:void 0},Bi=fe({name:"ui/modal",initialState:oc,reducers:{setActiveModal(t,e){t.activeModal=e.payload},hideModal(t){t.activeModal=void 0}}}),{actions:lc,reducer:cc}=Bi,ac=Bi.actions.hideModal.type,{setActiveModal:dc,hideModal:Wi}=lc,zn=(()=>{const t=document.createElement("div");return t.setAttribute("contenteditable","PLAINTEXT-ONLY"),t.contentEditable==="plaintext-only"?"plaintext-only":"true"})();class ce extends I.Component{input=Te.createRef();render(){const e=je("inline-input",this.props.className);return o.jsx("span",{ref:this.input,tabIndex:0,className:e,placeholder:this.props.placeholder,onFocus:this.onFocus,onBlur:this.onBlur,onKeyDown:this.onKeyDown,onInput:this.onInput,onPaste:this.onPaste,onMouseDown:this.onMouseDown,onClick:this.onClick,children:this.props.content})}componentDidUpdate(e){e.content!==this.props.content&&this.props.onInput?.(this.props.content)}isEditing=()=>this.input.current?.contentEditable===zn;startEditing=()=>{if(!this.input.current)return console.error("unreachable");this.isEditing()||(this.suppress_events=!0,this.input.current.blur(),this.input.current.contentEditable=zn,window.requestAnimationFrame(()=>{if(this.input.current){if(this.input.current.focus(),this.suppress_events=!1,this.props.selectAllOnClick){const e=document.createRange();e.selectNodeContents(this.input.current);const s=window.getSelection();s?.removeAllRanges(),s?.addRange(e)}this.props.onEditStart?.()}}))};resetValue=()=>{if(!this.input.current)return console.error("unreachable");this.input.current.textContent=this.props.content,this.props.onInput?.(this.props.content)};finishEditing=()=>{if(!this.input.current)return console.error("unreachable");this.props.onEditDone(this.input.current.textContent||""),this.input.current.blur(),this.input.current.contentEditable="inherit"};onPaste=e=>{e.preventDefault();const s=e.clipboardData.getData("text/plain");document.execCommand("insertHTML",!1,s)};suppress_events=!1;onMouseDown=e=>{this.suppress_events=!0,window.addEventListener("mouseup",this.onMouseUp,{once:!0})};onMouseUp=e=>{const s=e.target===this.input.current,i=!window.getSelection()?.toString();this.props.selectAllOnClick?s&&i&&this.startEditing():s&&this.startEditing(),this.suppress_events=!1};onClick=e=>{};onFocus=e=>{if(!this.input.current)throw"unreachable";this.suppress_events||this.startEditing()};onInput=e=>{this.props.onInput?.(this.input.current?.textContent||"")};onBlur=e=>{this.suppress_events||this.finishEditing()};onKeyDown=e=>{switch(e.stopPropagation(),e.key){case"Escape":e.preventDefault(),this.resetValue(),this.finishEditing();break;case"Enter":e.shiftKey||(e.preventDefault(),this.finishEditing());break}this.props.onKeyDown?.(e)}}function bt(t){const e=k.c(15);let s;e[0]!==t.content||e[1]!==t.isValid?(s=t.isValid(t.content),e[0]=t.content,e[1]=t.isValid,e[2]=s):s=e[2];const[i,r]=I.useState(s),n=I.useRef(null);let l;e[3]!==t?(l=_=>{t.isValid(_)?t.onEditDone(_):n.current?.resetValue()},e[3]=t,e[4]=l):l=e[4];const a=l,d=i?"has-success":"has-warning";let f;e[5]!==t.className||e[6]!==d?(f=je(t.className,d),e[5]=t.className,e[6]=d,e[7]=f):f=e[7];const p=f;let h;e[8]!==t?(h=_=>r(t.isValid(_)),e[8]=t,e[9]=h):h=e[9];let g;return e[10]!==p||e[11]!==a||e[12]!==t||e[13]!==h?(g=o.jsx(ce,{...t,className:p,onInput:h,onEditDone:a,ref:n}),e[10]=p,e[11]=a,e[12]=t,e[13]=h,e[14]=g):g=e[14],g}const G=()=>Nl(),D=kl,uc=ui.withTypes(),Ss=_e("EVENTS_ADD"),Ki=_e("EVENTS_RECEIVE"),Gt=_e("events/toggleVisibility"),zi=_e("events/toggleFilter");var Gi=(t=>(t.debug="debug",t.info="info",t.web="web",t.warn="warn",t.error="error",t))(Gi||{});const fc={visible:!1,filters:{debug:!1,info:!0,web:!0,warn:!0,error:!0},list:[],view:[]};function pc(t=fc,e){if(Ss.match(e)){const s=e.payload;return{...t,list:[...t.list,s],view:t.filters[s.level]?[...t.view,s]:t.view}}else{if(Ki.match(e))return{...t,list:e.payload,view:e.payload.filter(s=>t.filters[s.level])};if(Gt.match(e))return{...t,visible:!t.visible};if(zi.match(e)){const s={...t.filters,[e.payload]:!t.filters[e.payload]};return{...t,filters:s,view:t.list.filter(i=>s[i.level])}}else return t}}function hc(t,e="web"){return Ss({id:Math.random().toString(),message:t,level:e})}const Gn={},mc=fe({name:"ui/optionsEditor",initialState:Gn,reducers:{startUpdate(t,e){t[e.payload.option]={isUpdating:!0,value:e.payload.value,error:!1}},updateSuccess(t,e){t[e.payload.option]=void 0},updateError(t,e){let s=t[e.payload.option].value;typeof s=="boolean"&&(s=!s),t[e.payload.option]={value:s,isUpdating:!1,error:e.payload.error}}},extraReducers:t=>{t.addCase(ac,()=>Gn)}}),{actions:gc,reducer:vc}=mc,{startUpdate:xc,updateSuccess:_c,updateError:jc}=gc;var xe=(t=>(t[t.Capture=0]="Capture",t[t.FlowList=1]="FlowList",t[t.Options=2]="Options",t[t.Flow=3]="Flow",t))(xe||{});const yc=fe({name:"ui/tabs",initialState:{current:1},reducers:{setCurrent(t,e){t.current=e.payload}}}),{actions:wc,reducer:bc}=yc,{setCurrent:Vt}=wc,Sc=fi({flow:Vl,modal:cc,optionsEditor:vc,tabs:bc,filter:Jl});var wt=(t=>(t.INIT="CONNECTION_INIT",t.FETCHING="CONNECTION_FETCHING",t.ESTABLISHED="CONNECTION_ESTABLISHED",t.ERROR="CONNECTION_ERROR",t))(wt||{});const $c={state:"CONNECTION_INIT",message:void 0},Yi=fe({name:"connection",initialState:$c,reducers:{startFetching:t=>{t.state==="CONNECTION_INIT"&&(t.state="CONNECTION_FETCHING")},finishFetching:t=>{t.state==="CONNECTION_FETCHING"&&(t.state="CONNECTION_ESTABLISHED")},connectionError:(t,e)=>{t.state="CONNECTION_ERROR",t.message=e.payload}}}),{startFetching:Cc,finishFetching:Nc,connectionError:kc}=Yi.actions,Ec=Yi.reducer,Tc={add_upstream_certs_to_client_chain:!1,allow_hosts:[],anticache:!1,anticomp:!1,block_global:!0,block_list:[],block_private:!1,body_size_limit:void 0,cert_passphrase:void 0,certs:[],ciphers_client:void 0,ciphers_server:void 0,client_certs:void 0,client_replay:[],client_replay_concurrency:1,command_history:!0,confdir:"~/.mitmproxy",connect_addr:void 0,connection_strategy:"eager",console_focus_follow:!1,content_view_lines_cutoff:512,dns_name_servers:[],dns_use_hosts_file:!0,export_preserve_original_ip:!1,hardump:"",http2:!0,http2_ping_keepalive:58,http3:!0,http_connect_send_host_header:!0,ignore_hosts:[],intercept:void 0,intercept_active:!1,keep_alt_svc_header:!1,keep_host_header:!1,key_size:2048,listen_host:"",listen_port:void 0,map_local:[],map_remote:[],mode:["regular"],modify_body:[],modify_headers:[],normalize_outbound_headers:!0,onboarding:!0,onboarding_host:"mitm.it",protobuf_definitions:void 0,proxy_debug:!1,proxyauth:void 0,rawtcp:!0,readfile_filter:void 0,request_client_cert:!1,rfile:void 0,save_stream_file:void 0,save_stream_filter:void 0,scripts:[],server:!0,server_replay:[],server_replay_extra:"forward",server_replay_ignore_content:!1,server_replay_ignore_host:!1,server_replay_ignore_params:[],server_replay_ignore_payload_params:[],server_replay_ignore_port:!1,server_replay_kill_extra:!1,server_replay_nopop:!1,server_replay_refresh:!0,server_replay_reuse:!1,server_replay_use_headers:[],show_ignored_hosts:!1,showhost:!1,ssl_insecure:!1,ssl_verify_upstream_trusted_ca:void 0,ssl_verify_upstream_trusted_confdir:void 0,stickyauth:void 0,stickycookie:void 0,store_streamed_bodies:!1,stream_large_bodies:void 0,strip_ech:!0,tcp_hosts:[],tcp_timeout:600,termlog_verbosity:"info",tls_ecdh_curve_client:void 0,tls_ecdh_curve_server:void 0,tls_version_client_max:"UNBOUNDED",tls_version_client_min:"TLS1_2",tls_version_server_max:"UNBOUNDED",tls_version_server_min:"TLS1_2",udp_hosts:[],upstream_auth:void 0,upstream_cert:!0,validate_inbound_headers:!0,view_filter:void 0,view_order:"time",view_order_reversed:!1,web_columns:["tls","icon","path","method","status","size","time"],web_debug:!1,web_host:"127.0.0.1",web_open_browser:!0,web_password:"",web_port:8081,web_static_viewer:"",websocket:!0},Yt=_e("OPTIONS_RECEIVE"),$s=_e("OPTIONS_UPDATE"),Rc=fe({name:"options",initialState:Tc,reducers:{},extraReducers:t=>{t.addCase(Yt,(e,s)=>{const i={};for(const[r,{value:n}]of Object.entries(s.payload))i[r]=n;return i}).addCase($s,(e,s)=>{for(const[i,{value:r}]of Object.entries(s.payload))e[i]=r})}}),Ac=Rc.reducer;async function Dc(t,e,s){try{const i=await ne.put("/options",{[t]:e});if(i.status===200)s(_c({option:t}));else throw await i.text()}catch(i){s(jc({option:t,error:i.toString()}))}}const Fc=Dc;function Cs(t,e){return s=>{s(xc({option:t,value:e})),Fc(t,e,s)}}const Ic={visible:!1},Lc=fe({name:"commandBar",initialState:Ic,reducers:{toggleVisibility(t){t.visible=!t.visible}}}),{actions:Pc,reducer:Oc}=Lc,{toggleVisibility:Ji}=Pc,Ue=_e("STATE_RECEIVE"),Be=_e("STATE_UPDATE"),Mc={available:!1,version:"",contentViews:[],servers:{},platform:"",localModeUnavailable:null},qc=fe({name:"backendState",initialState:Mc,reducers:{},extraReducers:t=>{t.addCase(Ue,(e,s)=>({...e,available:!0,...s.payload})).addCase(Be,(e,s)=>({...e,...s.payload}))}}),Hc=qc.reducer,Vc={},Uc=fe({name:"optionsMeta",initialState:Vc,reducers:{},extraReducers:t=>{t.addCase(Yt,(e,s)=>s.payload).addCase($s,(e,s)=>({...e,...s.payload}))}}),Bc=Uc.reducer,dt=(t,e)=>e.listen_host&&e.listen_port?`${t}@${e.listen_host}:${e.listen_port}`:e.listen_port?`${t}@${e.listen_port}`:t,Qi=t=>{let[e,s]=ps(t,"@");e||(e=s,s="");const[i,r]=vi(e,":");let n,l;if(s){let a;if(s.includes(":")?[n,a]=ps(s,":"):(n="",a=s),a&&(l=parseInt(a,10),isNaN(l)||l<0||l>65535))throw new Error(`invalid port: ${a}`)}return{full_spec:t,name:i,data:r,listen_host:n,listen_port:l}},Xi=t=>dt("regular",t),Yn=({listen_host:t,listen_port:e})=>({ui_id:Math.random(),active:!0,listen_host:t,listen_port:e}),Zi=t=>t.selectedProcesses?`local:${t.selectedProcesses}`:"local",Jn=({data:t})=>({ui_id:Math.random(),active:!0,selectedProcesses:t}),er=t=>{const e=t.file_path?`wireguard:${t.file_path}`:"wireguard";return dt(e,t)},Qn=({data:t,listen_host:e,listen_port:s})=>({ui_id:Math.random(),active:!0,listen_host:e,listen_port:s,file_path:t});var Jt=(t=>(t.HTTP="http",t.HTTPS="https",t.HTTP3="http3",t.TLS="tls",t.DTLS="dtls",t.TCP="tcp",t.UDP="udp",t.DNS="dns",t.QUIC="quic",t))(Jt||{}),ot=(t=>(t.CSS="css",t.JAVASCRIPT="javascript",t.XML="xml",t.YAML="yaml",t.NONE="none",t.ERROR="error",t))(ot||{});const hs=()=>({active:!1,protocol:Jt.HTTPS,destination:"",ui_id:Math.random()}),Ns=t=>dt(`reverse:${t.protocol}://${t.destination}`,t),Wc=({data:t,listen_host:e,listen_port:s})=>{let[i,r]=vi(t,"://");return r||(r=i,i=Jt.HTTPS),{ui_id:Math.random(),active:!0,protocol:i,destination:r,listen_host:e,listen_port:s}},tr=t=>dt("transparent",t),Xn=({listen_host:t,listen_port:e})=>({ui_id:Math.random(),active:!0,listen_host:t,listen_port:e}),sr=t=>dt("socks5",t),Zn=({listen_host:t,listen_port:e})=>({ui_id:Math.random(),active:!0,listen_host:t,listen_port:e}),nr=t=>dt(`upstream:${t.destination}`,t),ei=({data:t,listen_host:e,listen_port:s})=>({ui_id:Math.random(),active:!0,destination:t||"",listen_host:e,listen_port:s}),ir=t=>dt("dns",t),ti=({listen_host:t,listen_port:e})=>({ui_id:Math.random(),active:!0,listen_host:t,listen_port:e}),Xe=t=>t.active&&!t.error;async function Kc(t,e){const s=e.getState().modes,i=[...s.regular.filter(Xe).map(Xi),...s.local.filter(Xe).map(Zi),...s.wireguard.filter(Xe).map(er),...s.reverse.filter(Xe).map(Ns),...s.transparent.filter(Xe).map(tr),...s.socks.filter(Xe).map(sr),...s.upstream.filter(Xe).map(nr),...s.dns.filter(Xe).map(ir)],r=await ne.put("/options",{mode:i});if(r.status!==200)throw new Error(await r.text())}function ie(t){return uc(t,Kc)}function se(t,e,s){t.addCase(s.pending,(i,r)=>{const{server:n,value:l}=r.meta.arg,a=i.findIndex(d=>d.ui_id===n.ui_id);a>=0&&(i[a][e]=l,i[a].error=void 0)}),t.addCase(s.rejected,(i,r)=>{const{server:n}=r.meta.arg,l=i.findIndex(a=>a.ui_id===n.ui_id);l>=0&&(i[l].error=r.error.message)})}function be(t,e){return function(i,r){if(r.payload.servers){const n=Object.values(r.payload.servers).filter(l=>l.type===t).map(l=>Qi(l.full_spec));if(n.length>0)return n.map(e);for(const l of i)l.active=!1}}}const rr=ie("modes/regular/setActive"),or=ie("modes/regular/setListenHost"),lr=ie("modes/regular/setListenPort"),zc=[{active:!0,ui_id:Math.random()}],Gc=fe({name:"modes/regular",initialState:zc,reducers:{},extraReducers:t=>{se(t,"active",rr),se(t,"listen_host",or),se(t,"listen_port",lr),t.addCase(Ue,be("regular",Yn)),t.addCase(Be,be("regular",Yn))}}),Yc=Gc.reducer,cr=ie("modes/local/setActive"),St=ie("modes/local/setSelectedProcesses"),Jc=[{active:!1,selectedProcesses:"",ui_id:Math.random()}],Qc=fe({name:"modes/local",initialState:Jc,reducers:{},extraReducers:t=>{se(t,"active",cr),se(t,"selectedProcesses",St),t.addCase(Ue,be("local",Jn)),t.addCase(Be,be("local",Jn))}}),Xc=Qc.reducer,ar=ie("modes/wireguard/setActive"),dr=ie("modes/wireguard/setListenHost"),ur=ie("modes/wireguard/setListenPort"),fr=ie("modes/wireguard/setFilePath"),Zc=[{active:!1,ui_id:Math.random()}],ea=fe({name:"modes/wireguard",initialState:Zc,reducers:{},extraReducers:t=>{se(t,"active",ar),se(t,"listen_host",dr),se(t,"listen_port",ur),se(t,"file_path",fr),t.addCase(Ue,be("wireguard",Qn)),t.addCase(Be,be("wireguard",Qn))}}),ta=ea.reducer,ms=ie("modes/reverse/setActive"),pr=ie("modes/reverse/setListenHost"),hr=ie("modes/reverse/setListenPort"),mr=ie("modes/reverse/setProtocol"),gr=ie("modes/reverse/setDestination"),sa=[hs()],vr=fe({name:"modes/reverse",initialState:sa,reducers:{addServer:t=>{t.push(hs())},removeServer:(t,e)=>{const s=t.findIndex(i=>i.ui_id===e.payload.ui_id);s!==-1&&(t[s].active&&console.error("servers should be deactivated before removal"),t.splice(s,1))}},extraReducers:t=>{se(t,"active",ms),se(t,"listen_host",pr),se(t,"listen_port",hr),se(t,"protocol",mr),se(t,"destination",gr),t.addCase(Ue,e),t.addCase(Be,e);function e(s,i){if(i.payload.servers){const r=Object.fromEntries(Object.entries(i.payload.servers).filter(([l,a])=>a.type==="reverse").map(([l,a])=>[l,Qi(l)])),n=[];for(const l of s){const a=Ns(l),d=a in r;delete r[a],n.push({...l,active:d})}for(const l of Object.values(r))n.push(Wc(l));return n.length>1&&Kt({...n[0],ui_id:void 0},{...hs(),ui_id:void 0})&&n.shift(),n}}}}),{addServer:na,removeServer:ia}=vr.actions,ra=vr.reducer,xr=ie("modes/transparent/setActive"),_r=ie("modes/transparent/setListenHost"),jr=ie("modes/transparent/setListenPort"),oa=[{active:!1,ui_id:Math.random()}],la=fe({name:"modes/transparent",initialState:oa,reducers:{},extraReducers:t=>{se(t,"active",xr),se(t,"listen_host",_r),se(t,"listen_port",jr),t.addCase(Ue,be("transparent",Xn)),t.addCase(Be,be("transparent",Xn))}}),ca=la.reducer,yr=ie("modes/socks5/setActive"),wr=ie("modes/socks5/setListenHost"),br=ie("modes/socks5/setListenPort"),aa=[{active:!1,ui_id:Math.random()}],da=fe({name:"modes/socks5",initialState:aa,reducers:{},extraReducers:t=>{se(t,"active",yr),se(t,"listen_host",wr),se(t,"listen_port",br),t.addCase(Ue,be("socks5",Zn)),t.addCase(Be,be("socks5",Zn))}}),ua=da.reducer,Sr=ie("modes/upstream/setActive"),$r=ie("modes/upstream/setListenHost"),Cr=ie("modes/upstream/setListenPort"),Nr=ie("modes/upstream/setDestination"),fa=[{active:!1,destination:"",ui_id:Math.random()}],pa=fe({name:"modes/upstream",initialState:fa,reducers:{},extraReducers:t=>{se(t,"active",Sr),se(t,"listen_host",$r),se(t,"listen_port",Cr),se(t,"destination",Nr),t.addCase(Ue,be("upstream",ei)),t.addCase(Be,be("upstream",ei))}}),ha=pa.reducer,kr=ie("modes/dns/setActive"),Er=ie("modes/dns/setListenHost"),Tr=ie("modes/dns/setListenPort"),ma=[{active:!0,ui_id:Math.random()}],ga=fe({name:"modes/dns",initialState:ma,reducers:{},extraReducers:t=>{se(t,"active",kr),se(t,"listen_host",Er),se(t,"listen_port",Tr),t.addCase(Ue,be("dns",ti)),t.addCase(Be,be("dns",ti))}}),va=ga.reducer,xa=fi({regular:Yc,local:Xc,wireguard:ta,reverse:ra,transparent:ca,socks:ua,upstream:ha,dns:va}),$t=ui("fetchProcesses",async(t,{rejectWithValue:e})=>{try{return(await ne("/processes")).json()}catch(s){return e(s.message)}}),_a={currentProcesses:[],isLoading:!1},ja=fe({name:"processes",initialState:_a,reducers:{},extraReducers:t=>{t.addCase($t.pending,e=>{e.isLoading=!0,e.error=void 0}),t.addCase($t.fulfilled,(e,s)=>{e.isLoading=!1,e.currentProcesses=s.payload}),t.addCase($t.rejected,(e,s)=>{e.isLoading=!1,e.error=s.payload})}}),ya=ja.reducer,wa={commandBar:Oc,eventLog:pc,flows:nc,connection:Ec,modes:xa,ui:Sc,options:Ac,options_meta:Bc,backendState:Hc,processes:ya},ba={immutableCheck:{warnAfter:5e5},serializableCheck:{warnAfter:5e5,ignoredPaths:["flows"]}},Nt=El({reducer:wa,middleware:t=>t(ba),devTools:!1});class Sa extends I.Component{container=Te.createRef();nameInput=Te.createRef();valueInput=Te.createRef();render=()=>{const[e,s]=this.props.item;return o.jsxs("div",{ref:this.container,className:"kv-row",onClick:this.onClick,onKeyDownCapture:this.onKeyDown,children:[o.jsx(ce,{ref:this.nameInput,className:"kv-key",content:e,onEditStart:this.props.onEditStart,onEditDone:i=>this.props.onEditDone([i,s]),selectAllOnClick:!0}),": ",o.jsx(ce,{ref:this.valueInput,className:"kv-value",content:s,onEditStart:this.props.onEditStart,onEditDone:i=>this.props.onEditDone([e,i]),placeholder:"empty",selectAllOnClick:!0})]})};onClick=e=>{e.target===this.container.current&&this.props.onClickEmptyArea()};onKeyDown=e=>{e.target===this.valueInput.current?.input.current&&e.key==="Tab"&&this.props.onTabNext()}}class Rr extends I.Component{rowRefs={};currentlyEditing;justFinishedEditing;state={currentList:this.props.data||[],initialList:this.props.data};static getDerivedStateFromProps(e,s){return e.data!==s.initialList?{currentList:e.data||[],initialList:e.data}:null}render=()=>{this.rowRefs={};const e=this.state.currentList.map((s,i)=>o.jsx(Sa,{item:s,onEditStart:()=>this.currentlyEditing=i,onEditDone:r=>this.onEditDone(i,r),onClickEmptyArea:()=>this.onClickEmptyArea(i),onTabNext:()=>this.onTabNext(i),ref:r=>{this.rowRefs[i]=r}},i));return o.jsxs("div",{className:je("kv-editor",this.props.className),onMouseDown:this.onMouseDown,children:[e,o.jsx("div",{onClick:s=>{s.preventDefault(),this.onClickEmptyArea(this.state.currentList.length-1)},className:"kv-add-row fa fa-plus-square-o",role:"button","aria-label":"Add"})]})};onEditDone=(e,s)=>{const i=[...this.state.currentList];s[0]?i[e]=s:i.splice(e,1),this.currentlyEditing=void 0,Ht.isEqual(this.state.currentList,i)||this.props.onChange(i),this.setState({currentList:i})};onClickEmptyArea=e=>{if(this.justFinishedEditing)return;const s=[...this.state.currentList];s.splice(e+1,0,["",""]),this.setState({currentList:s},()=>this.rowRefs[e+1]?.nameInput.current?.startEditing())};onTabNext=e=>{e==this.state.currentList.length-1&&this.onClickEmptyArea(e)};onMouseDown=e=>{this.justFinishedEditing=this.currentlyEditing}}function Ar(t,e){const s=k.c(6),[i,r]=I.useState(),[n,l]=I.useState();let a;s[0]!==n||s[1]!==t?(a=()=>{n&&n.abort();const f=new AbortController;return ne(t,{signal:f.signal}).then($a).then(p=>{r(p)}).catch(p=>{f.signal.aborted||r(`Error getting content: ${p}.`)}),l(f),()=>{f.signal.aborted||f.abort()}},s[0]=n,s[1]=t,s[2]=a):a=s[2];let d;return s[3]!==e||s[4]!==t?(d=[t,e],s[3]=e,s[4]=t,s[5]=d):d=s[5],I.useEffect(a,d),i}function $a(t){if(!t.ok)throw`${t.status} ${t.statusText}`.trim();return t.text()}function Dr(t,e,s,i,r){const n=k.c(11);let l;n[0]!==t||n[1]!==i||n[2]!==e||n[3]!==s?(l=we.getContentURL(t,e,s,i),n[0]=t,n[1]=i,n[2]=e,n[3]=s,n[4]=l):l=n[4];const d=Ar(l,r);let f;if(d)try{let p;n[5]!==d?(p=JSON.parse(d),n[5]=d,n[6]=p):p=n[6],f=p}catch{let p;n[7]!==d?(p={text:d,description:"Network Error",syntax_highlight:"error",view_name:"raw"},n[7]=d,n[8]=p):p=n[8];const h=p;if(e==="messages"){let g;n[9]!==h?(g=[h],n[9]=h,n[10]=g):g=n[10],f=g}else f=h}else f=void 0;return f}const Fr=Te.memo(function({icon:e,text:s,className:i,title:r,onOpenFile:n,onClick:l}){let a;return o.jsxs("a",{href:"#",onClick:d=>{a.click(),l&&l(d)},className:i,title:r,children:[o.jsx("i",{className:"fa fa-fw "+e}),s,o.jsx("input",{ref:d=>{a=d},className:"hidden",type:"file",onChange:d=>{d.preventDefault(),d.target.files&&d.target.files.length>0&&n(d.target.files[0]),a.value=""}})]})});function pe(t){const e=k.c(11),{onClick:s,children:i,icon:r,disabled:n,className:l,title:a}=t;let d;e[0]!==l?(d=je(l,"btn btn-default"),e[0]=l,e[1]=d):d=e[1];const f=n?void 0:s;let p;e[2]!==r?(p=r&&o.jsxs(o.Fragment,{children:[o.jsx("i",{className:"fa "+r})," "]}),e[2]=r,e[3]=p):p=e[3];let h;return e[4]!==i||e[5]!==n||e[6]!==d||e[7]!==f||e[8]!==p||e[9]!==a?(h=o.jsxs("button",{className:d,onClick:f,disabled:n,title:a,children:[p,i]}),e[4]=i,e[5]=n,e[6]=d,e[7]=f,e[8]=p,e[9]=a,e[10]=h):h=e[10],h}function Ca(t){const e=k.c(11),{initialContent:s,onChange:i,language:r,readonly:n}=t,l=n===void 0?!1:n,a=Na;let d;e:switch(r){case ot.YAML:{let h;e[0]===Symbol.for("react.memo_cache_sentinel")?(h=[Dl()],e[0]=h):h=e[0],d=h;break e}case ot.XML:{let h;e[1]===Symbol.for("react.memo_cache_sentinel")?(h=[Al()],e[1]=h):h=e[1],d=h;break e}case ot.JAVASCRIPT:{let h;e[2]===Symbol.for("react.memo_cache_sentinel")?(h=[Rl()],e[2]=h):h=e[2],d=h;break e}case ot.CSS:{let h;e[3]===Symbol.for("react.memo_cache_sentinel")?(h=[Tl()],e[3]=h):h=e[3],d=h;break e}case void 0:case null:case ot.NONE:case ot.ERROR:{let h;e[4]===Symbol.for("react.memo_cache_sentinel")?(h=[],e[4]=h):h=e[4],d=h;break e}default:{console.error("Unexpected syntax highlighting language: ",r);let g;e[5]===Symbol.for("react.memo_cache_sentinel")?(g=[],e[5]=g):g=e[5],d=g}}const f=d;let p;return e[6]!==f||e[7]!==s||e[8]!==i||e[9]!==l?(p=o.jsx("div",{className:"codeeditor",onKeyDown:a,children:o.jsx(Fl,{value:s,onChange:i,readOnly:l,extensions:f})}),e[6]=f,e[7]=s,e[8]=i,e[9]=l,e[10]=p):p=e[10],p}function Na(t){return t.stopPropagation()}const Ir=Te.memo(function(e){const s=k.c(9),{content:i,maxLines:r,showMore:n}=e;if(i.length===0)return null;let l;if(s[0]!==i||s[1]!==r||s[2]!==n){let d;s[4]!==r||s[5]!==n?(d=(f,p)=>p===r?o.jsxs("button",{onClick:n,className:"btn btn-xs btn-info",children:[o.jsx("i",{className:"fa fa-angle-double-down","aria-hidden":"true"})," ","Show more"]},"showmore"):o.jsx("div",{children:f},p),s[4]=r,s[5]=n,s[6]=d):d=s[6],l=i.split(` `).map(d),s[0]=i,s[1]=r,s[2]=n,s[3]=l}else l=s[3];let a;return s[7]!==l?(a=o.jsx("pre",{children:l}),s[7]=l,s[8]=a):a=s[8],a}),ka=()=>{const t=k.c(1);let e;return t[0]===Symbol.for("react.memo_cache_sentinel")?(e=o.jsx("li",{role:"separator",className:"divider"}),t[0]=e):e=t[0],e};function ke(t){const e=k.c(8);let s,i,r;if(e[0]!==t){const{onClick:a,children:d,...f}=t;i=d,s=f,r=p=>{p.preventDefault(),a()},e[0]=t,e[1]=s,e[2]=i,e[3]=r}else s=e[1],i=e[2],r=e[3];const n=r;let l;return e[4]!==s||e[5]!==i||e[6]!==n?(l=o.jsx("li",{children:o.jsx("a",{href:"#",onClick:n,...s,children:i})}),e[4]=s,e[5]=i,e[6]=n,e[7]=l):l=e[7],l}const Et=Te.memo(function({text:e,children:s,options:i,className:r,onOpen:n,...l}){const[a,d]=I.useState(!1),{refs:f,floatingStyles:p}=Il(i),h=_=>{d(_),n&&n(_)};I.useEffect(()=>{f.floating.current&&document.addEventListener("click",_=>{f.floating.current?.contains(_.target)?document.addEventListener("click",()=>h(!1),{once:!0}):(_.preventDefault(),_.stopPropagation(),h(!1))},{once:!0,capture:!0})},[f.floating.current]);let g;return a?g=o.jsx("ul",{className:"dropdown-menu show",ref:f.setFloating,style:p,children:s}):g=null,o.jsxs(o.Fragment,{children:[o.jsx("a",{href:"#",ref:f.setReference,className:je(r,{open:a}),onClick:_=>{_.preventDefault(),h(!0)},...l,children:e}),g]})});function Lr(t){const e=k.c(16),{value:s,onChange:i}=t,r=D(Ea);let n;e[0]===Symbol.for("react.memo_cache_sentinel")?(n=o.jsx("i",{className:"fa fa-fw fa-files-o"}),e[0]=n):n=e[0];let l;e[1]===Symbol.for("react.memo_cache_sentinel")?(l=o.jsx("b",{children:"View:"}),e[1]=l):l=e[1];let a;e[2]!==s?(a=s.toLowerCase(),e[2]=s,e[3]=a):a=e[3];let d;e[4]===Symbol.for("react.memo_cache_sentinel")?(d=o.jsx("span",{className:"caret"}),e[4]=d):d=e[4];let f;e[5]!==a?(f=o.jsxs("span",{children:[n," ",l," ",a," ",d]}),e[5]=a,e[6]=f):f=e[6];const p=f;let h;e[7]===Symbol.for("react.memo_cache_sentinel")?(h={placement:"top-end"},e[7]=h):h=e[7];let g;if(e[8]!==r||e[9]!==i){let j;e[11]!==i?(j=y=>o.jsx(ke,{onClick:()=>i(y),children:y.toLowerCase().replace("_"," ")},y),e[11]=i,e[12]=j):j=e[12],g=r.map(j),e[8]=r,e[9]=i,e[10]=g}else g=e[10];let _;return e[13]!==p||e[14]!==g?(_=o.jsx(Et,{text:p,className:"btn btn-default btn-xs",options:h,children:g}),e[13]=p,e[14]=g,e[15]=_):_=e[15],_}function Ea(t){return t.backendState.contentViews||[]}function Ta(t){const e=k.c(8),{flow:s,message:i}=t,[r,n]=I.useState(!1);if(r){let l;e[0]===Symbol.for("react.memo_cache_sentinel")?(l=()=>n(!1),e[0]=l):l=e[0];let a;return e[1]!==s||e[2]!==i?(a=o.jsx(Ra,{flow:s,message:i,stopEdit:l}),e[1]=s,e[2]=i,e[3]=a):a=e[3],a}else{let l;e[4]===Symbol.for("react.memo_cache_sentinel")?(l=()=>n(!0),e[4]=l):l=e[4];let a;return e[5]!==s||e[6]!==i?(a=o.jsx(Aa,{flow:s,message:i,startEdit:l}),e[5]=s,e[6]=i,e[7]=a):a=e[7],a}}function Ra(t){const e=k.c(23),{flow:s,message:i,stopEdit:r}=t,n=G(),l=s.request===i?"request":"response";let a;e[0]!==s||e[1]!==i?(a=we.getContentURL(s,i),e[0]=s,e[1]=i,e[2]=a):a=e[2];const f=Ar(a,i.contentHash),[p,h]=I.useState();let g;e[3]!==f||e[4]!==n||e[5]!==p||e[6]!==s||e[7]!==l||e[8]!==r?(g=async()=>{await n(Le(s,{[l]:{content:p??f??""}})),r()},e[3]=f,e[4]=n,e[5]=p,e[6]=s,e[7]=l,e[8]=r,e[9]=g):g=e[9];const _=g;let j;e[10]===Symbol.for("react.memo_cache_sentinel")?(j=o.jsx("h5",{children:"[Editing]"}),e[10]=j):j=e[10];let y;e[11]!==_?(y=o.jsx(pe,{onClick:_,icon:"fa-check text-success",className:"btn-xs",children:"Done"}),e[11]=_,e[12]=y):y=e[12];let w;e[13]!==r?(w=o.jsx(pe,{onClick:()=>r(),icon:"fa-times text-danger",className:"btn-xs",children:"Cancel"}),e[13]=r,e[14]=w):w=e[14];let $;e[15]!==y||e[16]!==w?($=o.jsxs("div",{className:"controls",children:[j,y," ",w]}),e[15]=y,e[16]=w,e[17]=$):$=e[17];const N=f||"";let E;e[18]!==N?(E=o.jsx(Ca,{initialContent:N,onChange:h}),e[18]=N,e[19]=E):E=e[19];let T;return e[20]!==$||e[21]!==E?(T=o.jsxs("div",{className:"contentview",children:[$,E]},"edit"),e[20]=$,e[21]=E,e[22]=T):T=e[22],T}function Aa(t){const e=k.c(43),{flow:s,message:i,startEdit:r}=t,n=G(),l=s.request===i?"request":"response";let a;e[0]!==s.id||e[1]!==l?(a=V=>V.ui.flow.contentViewFor[s.id+l]||"Auto",e[0]=s.id,e[1]=l,e[2]=a):a=e[2];const d=D(a),[f,p]=I.useState(D(Da));let h;e[3]!==f?(h=()=>p(Math.max(1024,f*2)),e[3]=f,e[4]=h):h=e[4];const g=h,_=Dr(s,i,d,f+1,i.contentHash);let j;if(i.contentLength===0)j="No content";else if(_===void 0)j="Loading...";else{const V=`${_.view_name} ${_.description}`;let W;e[5]!==V?(W=V.trimEnd(),e[5]=V,e[6]=W):W=e[6],j=W}let y;e[7]!==j?(y=o.jsx("h5",{children:j}),e[7]=j,e[8]=y):y=e[8];let w;e[9]!==_||e[10]!==s||e[11]!==i?(w=_&&_?.text.length>0&&o.jsx(Fa,{flow:s,message:i}),e[9]=_,e[10]=s,e[11]=i,e[12]=w):w=e[12];let $;e[13]!==r?($=o.jsx(pe,{onClick:r,icon:"fa-edit",className:"btn-xs",children:"Edit"}),e[13]=r,e[14]=$):$=e[14];let N;e[15]!==n||e[16]!==s||e[17]!==l?(N=o.jsx(Fr,{icon:"fa-upload",text:"Replace",title:"Upload a file to replace the content.",onOpenFile:V=>n(ec(s,V,l)),className:"btn btn-default btn-xs"}),e[15]=n,e[16]=s,e[17]=l,e[18]=N):N=e[18];let E;e[19]!==n||e[20]!==s.id||e[21]!==l?(E=V=>n(pi({messageId:s.id+l,contentView:V})),e[19]=n,e[20]=s.id,e[21]=l,e[22]=E):E=e[22];let T;e[23]!==d||e[24]!==E?(T=o.jsx(Lr,{value:d,onChange:E}),e[23]=d,e[24]=E,e[25]=T):T=e[25];let P;e[26]!==y||e[27]!==w||e[28]!==$||e[29]!==N||e[30]!==T?(P=o.jsxs("div",{className:"controls",children:[y,w," ",$," ",N," ",T]}),e[26]=y,e[27]=w,e[28]=$,e[29]=N,e[30]=T,e[31]=P):P=e[31];let L;e[32]!==s||e[33]!==i?(L=gs.matches(i)&&o.jsx(gs,{flow:s,message:i}),e[32]=s,e[33]=i,e[34]=L):L=e[34];const O=_?.text??"";let M;e[35]!==f||e[36]!==g||e[37]!==O?(M=o.jsx(Ir,{content:O,maxLines:f,showMore:g}),e[35]=f,e[36]=g,e[37]=O,e[38]=M):M=e[38];let U;return e[39]!==L||e[40]!==M||e[41]!==P?(U=o.jsxs("div",{className:"contentview",children:[P,L,M]},"view"),e[39]=L,e[40]=M,e[41]=P,e[42]=U):U=e[42],U}function Da(t){return t.options.content_view_lines_cutoff}function Fa({flow:t,message:e}){const s=t.request===e?"request":"response",i=D(f=>f.ui.flow.contentViewFor[t.id+s]||"Auto"),[r,n]=I.useState(!1),[l,a]=I.useState(!1),d=async()=>{try{const f=we.getContentURL(t,e,i);a(!0);const p=await ne(f);if(!p.ok)throw new Error(`${p.status} ${p.statusText}`.trim());const h=await p.json();await Bl(h),n(!0),setTimeout(()=>n(!1),2e3)}catch(f){console.error(f)}finally{a(!1)}};return o.jsx(pe,{onClick:d,icon:"fa-clipboard",className:"btn-xs",disabled:l,children:r?"Copied!":"Copy"})}const Ia=/^image\/(png|jpe?g|gif|webp|vnc.microsoft.icon|x-icon|svg\+xml)$/i;gs.matches=t=>Ia.test(we.getContentType(t)||"");function gs(t){const e=k.c(5),{flow:s,message:i}=t;let r;e[0]!==s||e[1]!==i?(r=we.getContentURL(s,i),e[0]=s,e[1]=i,e[2]=r):r=e[2];let n;return e[3]!==r?(n=o.jsx("div",{className:"flowview-image",children:o.jsx("img",{src:r,alt:"preview",className:"img-thumbnail"})}),e[3]=r,e[4]=n):n=e[4],n}function La(t){const e=k.c(24),{flow:s}=t,i=G();let r;e[0]!==i||e[1]!==s?(r=g=>i(Le(s,{request:{method:g}})),e[0]=i,e[1]=s,e[2]=r):r=e[2];let n;e[3]!==s.request.method||e[4]!==r?(n=o.jsx(bt,{content:s.request.method,onEditDone:r,isValid:Oa,selectAllOnClick:!0}),e[3]=s.request.method,e[4]=r,e[5]=n):n=e[5];let l;e[6]!==s.request?(l=ct.pretty_url(s.request),e[6]=s.request,e[7]=l):l=e[7];let a;e[8]!==i||e[9]!==s?(a=g=>i(Le(s,{request:{path:"",..._i(g)}})),e[8]=i,e[9]=s,e[10]=a):a=e[10];let d;e[11]!==l||e[12]!==a?(d=o.jsx(bt,{content:l,onEditDone:a,isValid:Pa}),e[11]=l,e[12]=a,e[13]=d):d=e[13];let f;e[14]!==i||e[15]!==s?(f=g=>i(Le(s,{request:{http_version:g}})),e[14]=i,e[15]=s,e[16]=f):f=e[16];let p;e[17]!==s.request.http_version||e[18]!==f?(p=o.jsx(bt,{content:s.request.http_version,onEditDone:f,isValid:ji,selectAllOnClick:!0}),e[17]=s.request.http_version,e[18]=f,e[19]=p):p=e[19];let h;return e[20]!==n||e[21]!==d||e[22]!==p?(h=o.jsx("div",{className:"first-line request-line",children:o.jsxs("div",{children:[n," ",d," ",p]})}),e[20]=n,e[21]=d,e[22]=p,e[23]=h):h=e[23],h}function Pa(t){return!!_i(t)?.host}function Oa(t){return t.length>0}function Ma(t){const e=k.c(19),{flow:s}=t,i=G();let r;e[0]!==i||e[1]!==s?(r=h=>i(Le(s,{response:{http_version:h}})),e[0]=i,e[1]=s,e[2]=r):r=e[2];let n;e[3]!==s.response.http_version||e[4]!==r?(n=o.jsx(bt,{content:s.response.http_version,onEditDone:r,isValid:ji,selectAllOnClick:!0}),e[3]=s.response.http_version,e[4]=r,e[5]=n):n=e[5];const l=s.response.status_code+"";let a;e[6]!==i||e[7]!==s?(a=h=>i(Le(s,{response:{code:parseInt(h)}})),e[6]=i,e[7]=s,e[8]=a):a=e[8];let d;e[9]!==l||e[10]!==a?(d=o.jsx(bt,{content:l,onEditDone:a,isValid:qa,selectAllOnClick:!0}),e[9]=l,e[10]=a,e[11]=d):d=e[11];let f;e[12]!==i||e[13]!==s?(f=s.response.http_version!=="HTTP/2.0"&&o.jsxs(o.Fragment,{children:[" ",o.jsx(ce,{content:s.response.reason,onEditDone:h=>i(Le(s,{response:{msg:h}})),selectAllOnClick:!0})]}),e[12]=i,e[13]=s,e[14]=f):f=e[14];let p;return e[15]!==n||e[16]!==d||e[17]!==f?(p=o.jsxs("div",{className:"first-line response-line",children:[n," ",d,f]}),e[15]=n,e[16]=d,e[17]=f,e[18]=p):p=e[18],p}function qa(t){return/^\d+$/.test(t)}function Ha(t){const e=k.c(7),{flow:s,message:i}=t,r=G(),n=s.request===i?"request":"response";let l;e[0]!==r||e[1]!==s||e[2]!==n?(l=d=>r(Le(s,{[n]:{headers:d}})),e[0]=r,e[1]=s,e[2]=n,e[3]=l):l=e[3];let a;return e[4]!==i.headers||e[5]!==l?(a=o.jsx(Rr,{className:"headers",data:i.headers,onChange:l}),e[4]=i.headers,e[5]=l,e[6]=a):a=e[6],a}function Va(t){const e=k.c(9),{flow:s,message:i}=t,r=G(),n=s.request===i?"request":"response";if(!!!we.get_first_header(i,/^trailer$/i))return null;let a,d;e[0]===Symbol.for("react.memo_cache_sentinel")?(a=o.jsx("hr",{}),d=o.jsx("h5",{children:"HTTP Trailers"}),e[0]=a,e[1]=d):(a=e[0],d=e[1]);let f;e[2]!==r||e[3]!==s||e[4]!==n?(f=h=>r(Le(s,{[n]:{trailers:h}})),e[2]=r,e[3]=s,e[4]=n,e[5]=f):f=e[5];let p;return e[6]!==i.trailers||e[7]!==f?(p=o.jsxs(o.Fragment,{children:[a,d,o.jsx(Rr,{className:"trailers",data:i.trailers,onChange:f})]}),e[6]=i.trailers,e[7]=f,e[8]=p):p=e[8],p}const Pr=I.memo(function(e){const s=k.c(20),{flow:i,message:r}=e,n=i.request===r?"request":"response",l=i.request===r?La:Ma;let a;s[0]!==l||s[1]!==i?(a=o.jsx(l,{flow:i}),s[0]=l,s[1]=i,s[2]=a):a=s[2];let d;s[3]!==i||s[4]!==r?(d=o.jsx(Ha,{flow:i,message:r}),s[3]=i,s[4]=r,s[5]=d):d=s[5];let f;s[6]===Symbol.for("react.memo_cache_sentinel")?(f=o.jsx("hr",{}),s[6]=f):f=s[6];const p=i.id+n;let h;s[7]!==i||s[8]!==r||s[9]!==p?(h=o.jsx(Ta,{flow:i,message:r},p),s[7]=i,s[8]=r,s[9]=p,s[10]=h):h=s[10];let g;s[11]!==i||s[12]!==r?(g=o.jsx(Va,{flow:i,message:r}),s[11]=i,s[12]=r,s[13]=g):g=s[13];let _;return s[14]!==n||s[15]!==a||s[16]!==d||s[17]!==h||s[18]!==g?(_=o.jsxs("section",{className:n,children:[a,d,f,h,g]}),s[14]=n,s[15]=a,s[16]=d,s[17]=h,s[18]=g,s[19]=_):_=s[19],_});function Or(){const t=k.c(2),e=D(Ua);let s;return t[0]!==e?(s=o.jsx(Pr,{flow:e,message:e.request}),t[0]=e,t[1]=s):s=t[1],s}function Ua(t){return t.flows.selected[0]}Or.displayName="Request";function Mr(){const t=k.c(2),e=D(Ba);let s;return t[0]!==e?(s=o.jsx(Pr,{flow:e,message:e.response}),t[0]=e,t[1]=s):s=t[1],s}function Ba(t){return t.flows.selected[0]}Mr.displayName="Response";const Wa=t=>{const e=k.c(3),{message:s}=t,i=s.query?s.op_code:s.response_code,r=s.truncation?"(Truncated)":"";let n;return e[0]!==i||e[1]!==r?(n=o.jsxs("div",{children:[i," ",r]}),e[0]=i,e[1]=r,e[2]=n):n=e[2],n},Ka=t=>{const e=k.c(10),{message:s}=t,i=s.recursion_desired?"Recursive ":"";let r;e[0]!==i?(r=o.jsxs("h5",{children:[i,"Question"]}),e[0]=i,e[1]=r):r=e[1];let n;e[2]===Symbol.for("react.memo_cache_sentinel")?(n=o.jsx("thead",{children:o.jsxs("tr",{children:[o.jsx("th",{children:"Name"}),o.jsx("th",{children:"Type"}),o.jsx("th",{children:"Class"})]})}),e[2]=n):n=e[2];let l;e[3]!==s.questions?(l=s.questions.map(Ya),e[3]=s.questions,e[4]=l):l=e[4];let a;e[5]!==l?(a=o.jsxs("table",{children:[n,o.jsx("tbody",{children:l})]}),e[5]=l,e[6]=a):a=e[6];let d;return e[7]!==r||e[8]!==a?(d=o.jsxs(o.Fragment,{children:[r,a]}),e[7]=r,e[8]=a,e[9]=d):d=e[9],d},ls=t=>{const e=k.c(7),{name:s,values:i}=t;let r;e[0]!==s?(r=o.jsx("h5",{children:s}),e[0]=s,e[1]=r):r=e[1];let n;e[2]!==i?(n=i.length>0?o.jsxs("table",{children:[o.jsx("thead",{children:o.jsxs("tr",{children:[o.jsx("th",{children:"Name"}),o.jsx("th",{children:"Type"}),o.jsx("th",{children:"Class"}),o.jsx("th",{children:"TTL"}),o.jsx("th",{children:"Data"})]})}),o.jsx("tbody",{children:i.map(Ja)})]}):"—",e[2]=i,e[3]=n):n=e[3];let l;return e[4]!==r||e[5]!==n?(l=o.jsxs(o.Fragment,{children:[r,n]}),e[4]=r,e[5]=n,e[6]=l):l=e[6],l},qr=t=>{const e=k.c(24),{type:s,message:i}=t,r="dns-"+s,n=`first-line ${s}-line`;let l;e[0]!==i?(l=o.jsx(Wa,{message:i}),e[0]=i,e[1]=l):l=e[1];let a;e[2]!==n||e[3]!==l?(a=o.jsx("div",{className:n,children:l}),e[2]=n,e[3]=l,e[4]=a):a=e[4];let d;e[5]!==i?(d=o.jsx(Ka,{message:i}),e[5]=i,e[6]=d):d=e[6];let f;e[7]===Symbol.for("react.memo_cache_sentinel")?(f=o.jsx("hr",{}),e[7]=f):f=e[7];const p=`${i.authoritative_answer?"Authoritative ":""}${i.recursion_available?"Recursive ":""}Answer`;let h;e[8]!==i.answers||e[9]!==p?(h=o.jsx(ls,{name:p,values:i.answers}),e[8]=i.answers,e[9]=p,e[10]=h):h=e[10];let g;e[11]===Symbol.for("react.memo_cache_sentinel")?(g=o.jsx("hr",{}),e[11]=g):g=e[11];let _;e[12]!==i.authorities?(_=o.jsx(ls,{name:"Authority",values:i.authorities}),e[12]=i.authorities,e[13]=_):_=e[13];let j;e[14]===Symbol.for("react.memo_cache_sentinel")?(j=o.jsx("hr",{}),e[14]=j):j=e[14];let y;e[15]!==i.additionals?(y=o.jsx(ls,{name:"Additional",values:i.additionals}),e[15]=i.additionals,e[16]=y):y=e[16];let w;return e[17]!==r||e[18]!==_||e[19]!==y||e[20]!==a||e[21]!==d||e[22]!==h?(w=o.jsxs("section",{className:r,children:[a,d,f,h,g,_,j,y]}),e[17]=r,e[18]=_,e[19]=y,e[20]=a,e[21]=d,e[22]=h,e[23]=w):w=e[23],w};function Hr(){const t=k.c(2),e=D(za);let s;return t[0]!==e.request?(s=o.jsx(qr,{type:"request",message:e.request}),t[0]=e.request,t[1]=s):s=t[1],s}function za(t){return t.flows.selected[0]}Hr.displayName="Request";function Vr(){const t=k.c(2),e=D(Ga);let s;return t[0]!==e.response?(s=o.jsx(qr,{type:"response",message:e.response}),t[0]=e.response,t[1]=s):s=t[1],s}function Ga(t){return t.flows.selected[0]}Vr.displayName="Response";function Ya(t,e){return o.jsxs("tr",{children:[o.jsx("td",{children:t.name}),o.jsx("td",{children:t.type}),o.jsx("td",{children:t.class})]},e)}function Ja(t,e){return o.jsxs("tr",{children:[o.jsx("td",{children:t.name}),o.jsx("td",{children:t.type}),o.jsx("td",{children:t.class}),o.jsx("td",{children:t.ttl}),o.jsx("td",{children:JSON.stringify(t.data).replace(/^"|"$/g,"")})]},e)}function Mt(t,e){return e?(e=[e[0],e[1]],e[0].includes(":")&&(e[0]=`[${e[0]}]`),o.jsxs("tr",{children:[o.jsxs("td",{children:[t,":"]}),o.jsx("td",{children:e.join(":")})]})):o.jsx(o.Fragment,{})}function si(t){const e=k.c(26),{conn:s}=t;let i;if("address"in s){let f;e[0]!==s.address?(f=Mt("Address",s.address),e[0]=s.address,e[1]=f):f=e[1];let p;e[2]!==s.peername?(p=Mt("Resolved address",s.peername),e[2]=s.peername,e[3]=p):p=e[3];let h;e[4]!==s.sockname?(h=Mt("Source address",s.sockname),e[4]=s.sockname,e[5]=h):h=e[5];let g;e[6]!==f||e[7]!==p||e[8]!==h?(g=o.jsxs(o.Fragment,{children:[f,p,h]}),e[6]=f,e[7]=p,e[8]=h,e[9]=g):g=e[9],i=g}else{let f;e[10]!==s.peername?(f=Mt("Address",s.peername),e[10]=s.peername,e[11]=f):f=e[11],i=f}let r;e[12]!==s.sni?(r=s.sni?o.jsxs("tr",{children:[o.jsxs("td",{children:[o.jsx("abbr",{title:"TLS Server Name Indication",children:"SNI"}),":"]}),o.jsx("td",{children:s.sni})]}):null,e[12]=s.sni,e[13]=r):r=e[13];let n;e[14]!==s.alpn?(n=s.alpn?o.jsxs("tr",{children:[o.jsxs("td",{children:[o.jsx("abbr",{title:"ALPN protocol negotiated",children:"ALPN"}),":"]}),o.jsx("td",{children:s.alpn})]}):null,e[14]=s.alpn,e[15]=n):n=e[15];let l;e[16]!==s.tls_version?(l=s.tls_version?o.jsxs("tr",{children:[o.jsx("td",{children:"TLS Version:"}),o.jsx("td",{children:s.tls_version})]}):null,e[16]=s.tls_version,e[17]=l):l=e[17];let a;e[18]!==s.cipher?(a=s.cipher?o.jsxs("tr",{children:[o.jsx("td",{children:"TLS Cipher:"}),o.jsx("td",{children:s.cipher})]}):null,e[18]=s.cipher,e[19]=a):a=e[19];let d;return e[20]!==i||e[21]!==r||e[22]!==n||e[23]!==l||e[24]!==a?(d=o.jsx("table",{className:"connection-table",children:o.jsxs("tbody",{children:[i,r,n,l,a]})}),e[20]=i,e[21]=r,e[22]=n,e[23]=l,e[24]=a,e[25]=d):d=e[25],d}function ni(t){return o.jsx("dl",{className:"cert-attributes",children:t.map(([e,s])=>o.jsxs(I.Fragment,{children:[o.jsx("dt",{children:e}),o.jsx("dd",{children:s})]},e))})}function Qa(t){const e=k.c(46),{flow:s}=t,i=s.server_conn?.cert;if(!i){let W;return e[0]===Symbol.for("react.memo_cache_sentinel")?(W=o.jsx(o.Fragment,{}),e[0]=W):W=e[0],W}let r;e[1]===Symbol.for("react.memo_cache_sentinel")?(r=o.jsx("h4",{children:"Server Certificate"},"name"),e[1]=r):r=e[1];let n;e[2]===Symbol.for("react.memo_cache_sentinel")?(n=o.jsx("td",{children:"Type"}),e[2]=n):n=e[2];let l;e[3]!==i.keyinfo[0]||e[4]!==i.keyinfo[1]?(l=o.jsxs("tr",{children:[n,o.jsxs("td",{children:[i.keyinfo[0],", ",i.keyinfo[1]," bits"]})]}),e[3]=i.keyinfo[0],e[4]=i.keyinfo[1],e[5]=l):l=e[5];let a;e[6]===Symbol.for("react.memo_cache_sentinel")?(a=o.jsx("td",{children:"SHA256 digest"}),e[6]=a):a=e[6];let d;e[7]!==i.sha256?(d=o.jsxs("tr",{children:[a,o.jsx("td",{children:i.sha256})]}),e[7]=i.sha256,e[8]=d):d=e[8];let f;e[9]===Symbol.for("react.memo_cache_sentinel")?(f=o.jsx("td",{children:"Valid from"}),e[9]=f):f=e[9];let p;e[10]!==i.notbefore?(p=at(i.notbefore,{includeMilliseconds:!1}),e[10]=i.notbefore,e[11]=p):p=e[11];let h;e[12]!==p?(h=o.jsxs("tr",{children:[f,o.jsx("td",{children:p})]}),e[12]=p,e[13]=h):h=e[13];let g;e[14]===Symbol.for("react.memo_cache_sentinel")?(g=o.jsx("td",{children:"Valid to"}),e[14]=g):g=e[14];let _;e[15]!==i.notafter?(_=at(i.notafter,{includeMilliseconds:!1}),e[15]=i.notafter,e[16]=_):_=e[16];let j;e[17]!==_?(j=o.jsxs("tr",{children:[g,o.jsx("td",{children:_})]}),e[17]=_,e[18]=j):j=e[18];let y;e[19]===Symbol.for("react.memo_cache_sentinel")?(y=o.jsx("td",{children:"Subject Alternative Names"}),e[19]=y):y=e[19];let w;e[20]!==i.altnames?(w=i.altnames.join(", "),e[20]=i.altnames,e[21]=w):w=e[21];let $;e[22]!==w?($=o.jsxs("tr",{children:[y,o.jsx("td",{children:w})]}),e[22]=w,e[23]=$):$=e[23];let N;e[24]===Symbol.for("react.memo_cache_sentinel")?(N=o.jsx("td",{children:"Subject"}),e[24]=N):N=e[24];let E;e[25]!==i.subject?(E=ni(i.subject),e[25]=i.subject,e[26]=E):E=e[26];let T;e[27]!==E?(T=o.jsxs("tr",{children:[N,o.jsx("td",{children:E})]}),e[27]=E,e[28]=T):T=e[28];let P;e[29]===Symbol.for("react.memo_cache_sentinel")?(P=o.jsx("td",{children:"Issuer"}),e[29]=P):P=e[29];let L;e[30]!==i.issuer?(L=ni(i.issuer),e[30]=i.issuer,e[31]=L):L=e[31];let O;e[32]!==L?(O=o.jsxs("tr",{children:[P,o.jsx("td",{children:L})]}),e[32]=L,e[33]=O):O=e[33];let M;e[34]===Symbol.for("react.memo_cache_sentinel")?(M=o.jsx("td",{children:"Serial"}),e[34]=M):M=e[34];let U;e[35]!==i.serial?(U=o.jsxs("tr",{children:[M,o.jsx("td",{children:i.serial})]}),e[35]=i.serial,e[36]=U):U=e[36];let V;return e[37]!==j||e[38]!==$||e[39]!==T||e[40]!==O||e[41]!==U||e[42]!==l||e[43]!==d||e[44]!==h?(V=o.jsxs(o.Fragment,{children:[r,o.jsx("table",{className:"certificate-table",children:o.jsxs("tbody",{children:[l,d,h,j,$,T,O,U]})})]}),e[37]=j,e[38]=$,e[39]=T,e[40]=O,e[41]=U,e[42]=l,e[43]=d,e[44]=h,e[45]=V):V=e[45],V}function Ur(t){const e=k.c(11),{flow:s}=t;let i;e[0]===Symbol.for("react.memo_cache_sentinel")?(i=o.jsx("h4",{children:"Client Connection"}),e[0]=i):i=e[0];let r;e[1]!==s.client_conn?(r=o.jsx(si,{conn:s.client_conn}),e[1]=s.client_conn,e[2]=r):r=e[2];let n;e[3]!==s.server_conn?(n=s.server_conn?.address&&o.jsxs(o.Fragment,{children:[o.jsx("h4",{children:"Server Connection"}),o.jsx(si,{conn:s.server_conn})]}),e[3]=s.server_conn,e[4]=n):n=e[4];let l;e[5]!==s?(l=o.jsx(Qa,{flow:s}),e[5]=s,e[6]=l):l=e[6];let a;return e[7]!==r||e[8]!==n||e[9]!==l?(a=o.jsxs("section",{className:"detail",children:[i,r,n,l]}),e[7]=r,e[8]=n,e[9]=l,e[10]=a):a=e[10],a}Ur.displayName="Connection";function Br(t){const e=k.c(7),{flow:s}=t,i=s.error.msg;let r;e[0]!==s.error.timestamp?(r=at(s.error.timestamp),e[0]=s.error.timestamp,e[1]=r):r=e[1];let n;e[2]!==r?(n=o.jsx("div",{children:o.jsx("small",{children:r})}),e[2]=r,e[3]=n):n=e[3];let l;return e[4]!==s.error.msg||e[5]!==n?(l=o.jsx("section",{className:"error",children:o.jsxs("div",{className:"alert alert-warning",children:[i,n]})}),e[4]=s.error.msg,e[5]=n,e[6]=l):l=e[6],l}Br.displayName="Error";function Xa(t){const e=k.c(4),{t:s,deltaTo:i,title:r}=t;let n;return e[0]!==i||e[1]!==s||e[2]!==r?(n=s?o.jsxs("tr",{children:[o.jsxs("td",{children:[r,":"]}),o.jsxs("td",{children:[at(s),i&&o.jsxs("span",{className:"text-muted",children:["(",mi(1e3*(s-i)),")"]})]})]}):o.jsx("tr",{}),e[0]=i,e[1]=s,e[2]=r,e[3]=n):n=e[3],n}function Wr(t){const e=k.c(26),{flow:s}=t;let i;s.type==="http"?i=s.request.timestamp_start:i=s.client_conn.timestamp_start;const r=s.server_conn?.timestamp_start;let n,l,a,d;if(e[0]!==s.client_conn.timestamp_end||e[1]!==s.client_conn.timestamp_start||e[2]!==s.client_conn.timestamp_tls_setup||e[3]!==s.request||e[4]!==s.response?.timestamp_end||e[5]!==s.response?.timestamp_start||e[6]!==s.server_conn?.timestamp_end||e[7]!==s.server_conn?.timestamp_tcp_setup||e[8]!==s.server_conn?.timestamp_tls_setup||e[9]!==s.type||e[10]!==i||e[11]!==r){const g=[{title:"Server conn. initiated",t:r,deltaTo:i},{title:"Server conn. TCP handshake",t:s.server_conn?.timestamp_tcp_setup,deltaTo:i},{title:"Server conn. TLS handshake",t:s.server_conn?.timestamp_tls_setup,deltaTo:i},{title:"Server conn. closed",t:s.server_conn?.timestamp_end,deltaTo:i},{title:"Client conn. established",t:s.client_conn.timestamp_start,deltaTo:s.type==="http"?i:void 0},{title:"Client conn. TLS handshake",t:s.client_conn.timestamp_tls_setup,deltaTo:i},{title:"Client conn. closed",t:s.client_conn.timestamp_end,deltaTo:i}];s.type==="http"&&g.push({title:"First request byte",t:s.request.timestamp_start},{title:"Request complete",t:s.request.timestamp_end,deltaTo:i},{title:"First response byte",t:s.response?.timestamp_start,deltaTo:i},{title:"Response complete",t:s.response?.timestamp_end,deltaTo:i}),a="timing",e[16]===Symbol.for("react.memo_cache_sentinel")?(d=o.jsx("h4",{children:"Timing"}),e[16]=d):d=e[16],l="timing-table",n=g.filter(td).sort(ed).map(Za),e[0]=s.client_conn.timestamp_end,e[1]=s.client_conn.timestamp_start,e[2]=s.client_conn.timestamp_tls_setup,e[3]=s.request,e[4]=s.response?.timestamp_end,e[5]=s.response?.timestamp_start,e[6]=s.server_conn?.timestamp_end,e[7]=s.server_conn?.timestamp_tcp_setup,e[8]=s.server_conn?.timestamp_tls_setup,e[9]=s.type,e[10]=i,e[11]=r,e[12]=n,e[13]=l,e[14]=a,e[15]=d}else n=e[12],l=e[13],a=e[14],d=e[15];let f;e[17]!==n?(f=o.jsx("tbody",{children:n}),e[17]=n,e[18]=f):f=e[18];let p;e[19]!==l||e[20]!==f?(p=o.jsx("table",{className:l,children:f}),e[19]=l,e[20]=f,e[21]=p):p=e[21];let h;return e[22]!==a||e[23]!==d||e[24]!==p?(h=o.jsxs("section",{className:a,children:[d,p]}),e[22]=a,e[23]=d,e[24]=p,e[25]=h):h=e[25],h}function Za(t){const{title:e,t:s,deltaTo:i}=t;return o.jsx(Xa,{title:e,t:s,deltaTo:i},e)}function ed(t,e){return t.t-e.t}function td(t){return!!t.t}Wr.displayName="Timing";function ks({flow:t,messages_meta:e}){const s=G(),i=D(f=>f.ui.flow.contentViewFor[t.id+"messages"]||"Auto"),[r,n]=I.useState(D(f=>f.options.content_view_lines_cutoff)),l=I.useCallback(()=>n(Math.max(1024,r*2)),[r]),a=Dr(t,"messages",i,r+1,t.id+e.count)??[];let d=r;return o.jsxs("div",{className:"contentview",children:[o.jsxs("div",{className:"controls",children:[o.jsxs("h5",{children:[e.count," Messages"]}),o.jsx(Lr,{value:i,onChange:f=>s(pi({messageId:t.id+"messages",contentView:f}))})]}),a.map((f,p)=>{const h=`fa fa-fw fa-arrow-${f.from_client?"right text-primary":"left text-danger"}`,g=o.jsxs("div",{children:[o.jsxs("small",{children:[o.jsx("i",{className:h}),o.jsx("span",{className:"pull-right",children:f.timestamp&&at(f.timestamp)})]}),o.jsx(Ir,{content:f.text,maxLines:d,showMore:l})]},p);return d-=f.text.split(` `).length,g})]})}function Kr(t){const e=k.c(8),{flow:s}=t;let i;e[0]===Symbol.for("react.memo_cache_sentinel")?(i=o.jsx("h4",{children:"WebSocket"}),e[0]=i):i=e[0];let r;e[1]!==s?(r=o.jsx(ks,{flow:s,messages_meta:s.websocket.messages_meta}),e[1]=s,e[2]=r):r=e[2];let n;e[3]!==s.websocket?(n=o.jsx(sd,{websocket:s.websocket}),e[3]=s.websocket,e[4]=n):n=e[4];let l;return e[5]!==r||e[6]!==n?(l=o.jsxs("section",{className:"websocket",children:[i,r,n]}),e[5]=r,e[6]=n,e[7]=l):l=e[7],l}Kr.displayName="WebSocket";function sd(t){const e=k.c(10),{websocket:s}=t;if(!s.timestamp_end)return null;const i=s.close_reason?`(${s.close_reason})`:"";let r;e[0]===Symbol.for("react.memo_cache_sentinel")?(r=o.jsx("i",{className:"fa fa-fw fa-window-close text-muted"}),e[0]=r):r=e[0];const n=s.closed_by_client?"client":"server",l=s.close_code;let a;e[1]!==s.timestamp_end?(a=at(s.timestamp_end),e[1]=s.timestamp_end,e[2]=a):a=e[2];let d;e[3]!==a?(d=o.jsx("small",{className:"pull-right",children:a}),e[3]=a,e[4]=d):d=e[4];let f;return e[5]!==i||e[6]!==n||e[7]!==d||e[8]!==s.close_code?(f=o.jsxs("div",{children:[r,"  Closed by ",n," ","with code ",l," ",i,".",d]}),e[5]=i,e[6]=n,e[7]=d,e[8]=s.close_code,e[9]=f):f=e[9],f}function zr(t){const e=k.c(7),{flow:s}=t,i=G();let r;e[0]===Symbol.for("react.memo_cache_sentinel")?(r=o.jsx("h4",{children:"Comment"}),e[0]=r):r=e[0];let n;e[1]!==i||e[2]!==s?(n=a=>{i(Le(s,{comment:a}))},e[1]=i,e[2]=s,e[3]=n):n=e[3];let l;return e[4]!==s.comment||e[5]!==n?(l=o.jsxs("section",{className:"timing",children:[r,o.jsx(ce,{className:"kv-value",content:s.comment,onEditDone:n,placeholder:"empty",selectAllOnClick:!0})]}),e[4]=s.comment,e[5]=n,e[6]=l):l=e[6],l}zr.displayName="Comment";function Gr(t){const e=k.c(2),{flow:s}=t;let i;return e[0]!==s?(i=o.jsx("section",{className:"tcp",children:o.jsx(ks,{flow:s,messages_meta:s.messages_meta})}),e[0]=s,e[1]=i):i=e[1],i}Gr.displayName="Stream Data";function Yr(t){const e=k.c(2),{flow:s}=t;let i;return e[0]!==s?(i=o.jsx("section",{className:"udp",children:o.jsx(ks,{flow:s,messages_meta:s.messages_meta})}),e[0]=s,e[1]=i):i=e[1],i}Yr.displayName="Datagrams";const ii={request:Or,response:Mr,error:Br,connection:Ur,timing:Wr,websocket:Kr,tcpmessages:Gr,udpmessages:Yr,dnsrequest:Hr,dnsresponse:Vr,comment:zr};function vs(t){let e;switch(t.type){case"http":e=["request","response","websocket"].filter(s=>t[s]);break;case"tcp":e=["tcpmessages"];break;case"udp":e=["udpmessages"];break;case"dns":e=["request","response"].filter(s=>t[s]).map(s=>"dns"+s);break}return t.error&&e.push("error"),e.push("connection"),e.push("timing"),e.push("comment"),e}function nd(){const t=k.c(15),e=G(),s=D(rd);let i=D(id);if(s==null){let y;return t[0]===Symbol.for("react.memo_cache_sentinel")?(y=o.jsx(o.Fragment,{}),t[0]=y):y=t[0],y}const r=vs(s);r.indexOf(i)<0&&(i==="response"&&s.error?i="error":i==="error"&&"response"in s?i="response":i=r[0]);const n=ii[i],l="flow-detail",a="nav-tabs nav-tabs-sm";let d;t[1]!==e?(d=()=>e(Ve([])),t[1]=e,t[2]=d):d=t[2];let f;t[3]===Symbol.for("react.memo_cache_sentinel")?(f=o.jsx("i",{className:"fa fa-times-circle"}),t[3]=f):f=t[3];let p;t[4]!==d?(p=o.jsx("button",{"data-testid":"close-button-id",className:"close-button",onClick:d,children:f}),t[4]=d,t[5]=p):p=t[5];const h=r.map(y=>o.jsx("a",{href:"#",className:je({active:i===y}),onClick:w=>{w.preventDefault(),e(Ut(y))},children:ii[y].displayName},y));let g;t[6]!==p||t[7]!==h?(g=o.jsxs("nav",{className:a,children:[p,h]}),t[6]=p,t[7]=h,t[8]=g):g=t[8];let _;t[9]!==n||t[10]!==s?(_=o.jsx(n,{flow:s}),t[9]=n,t[10]=s,t[11]=_):_=t[11];let j;return t[12]!==g||t[13]!==_?(j=o.jsxs("div",{className:l,children:[g,_]}),t[12]=g,t[13]=_,t[14]=j):j=t[14],j}function id(t){return t.ui.flow.tab}function rd(t){return t.flows.selected[0]}function od(t){if(t.ctrlKey||t.metaKey)return()=>{};const e=t.key;return t.preventDefault(),(s,i)=>{const{flows:r}=i(),n=r.selected,l=n[0];switch(e){case"k":case"ArrowUp":s(ht(r,-1));break;case"j":case"ArrowDown":s(ht(r,1));break;case" ":case"PageDown":s(ht(r,10));break;case"PageUp":s(ht(r,-10));break;case"End":s(ht(r,1e10));break;case"Home":s(ht(r,-1e10));break;case"Escape":i().ui.modal.activeModal?s(Wi()):s(Ve([]));break;case"ArrowLeft":{if(!l)break;const a=vs(l),d=i().ui.flow.tab,f=a[(Math.max(0,a.indexOf(d))-1+a.length)%a.length];s(Ut(f));break}case"Tab":case"ArrowRight":{if(!l)break;const a=vs(l),d=i().ui.flow.tab,f=a[(Math.max(0,a.indexOf(d))+1)%a.length];s(Ut(f));break}case"Delete":case"d":{s(Ii(n));break}case"n":{Bt("view.flows.create","get","https://example.com/");break}case"D":{s(Li(n));break}case"a":{s(ys(n));break}case"A":{s(Di());break}case"r":{s(ws(n));break}case"v":{s(Pi(n));break}case"x":{s(Fi(n));break}case"X":{s(Zl());break}case"z":{s(Oi());break}default:return}}}class ld extends I.Component{static defaultProps={axis:"x"};node=Te.createRef();constructor(e,s){super(e,s),this.state={applied:!1,startPos:0,dragPointer:.1},this.onLostPointerCapture=this.onLostPointerCapture.bind(this),this.onPointerDown=this.onPointerDown.bind(this),this.onPointerMove=this.onPointerMove.bind(this)}onPointerDown(e){this.state.dragPointer===.1&&(e.target.setPointerCapture(e.pointerId),this.setState({startPos:this.props.axis==="x"?e.pageX:e.pageY,dragPointer:e.pointerId}))}onLostPointerCapture(e){if(this.state.dragPointer!==e.pointerId)return;const s=this.node.current,i=s.previousElementSibling,r=s.nextElementSibling;s.style.transform="",i.style.flex=`0 0 ${Math.max(0,(this.props.axis==="x"?i.offsetWidth+e.pageX:i.offsetHeight+e.pageY)-this.state.startPos)}px`,r.style.flex="1 1 auto",this.setState({applied:!0,dragPointer:.1}),this.onResize()}onPointerMove(e){this.state.dragPointer===e.pointerId&&(this.node.current.style.transform=this.props.axis==="x"?`translateX(${e.pageX-this.state.startPos}px)`:`translateY(${e.pageY-this.state.startPos}px)`)}onResize(){window.setTimeout(()=>window.dispatchEvent(new CustomEvent("resize")),1)}reset(e){this.state.applied&&(this.node.current?.previousElementSibling instanceof HTMLElement&&(this.node.current.previousElementSibling.style.flex=""),this.node.current?.nextElementSibling instanceof HTMLElement&&(this.node.current.nextElementSibling.style.flex=""),e||this.setState({applied:!1}),this.onResize())}componentWillUnmount(){this.reset(!0)}render(){return o.jsx("div",{ref:this.node,className:je("splitter",this.props.axis==="x"?"splitter-x":"splitter-y"),children:o.jsx("div",{onLostPointerCapture:this.onLostPointerCapture,onPointerDown:this.onPointerDown,onPointerMove:this.onPointerMove})})}}const Es=t=>{const e=t.current;return e===null||e.scrollTop===0?!1:Math.ceil(e.scrollTop)+e.clientHeight>=e.scrollHeight},Jr=t=>{t.current&&!Es(t)&&(t.current.scrollTop=t.current.scrollHeight)};function kt(t=void 0){if(!t)return{start:0,end:0,paddingTop:0,paddingBottom:0};const{itemCount:e,rowHeight:s,viewportTop:i,viewportHeight:r,itemHeights:n}=t,l=i+r;let a=0,d=0,f=0,p=0;if(n){let h=0;for(let g=0;g0&&ho.jsx("td",{className:je("col-tls",t.client_conn.tls_established?"col-tls-https":"col-tls-http")});Ts.headerName="";const Rs=({rowNumber:t})=>o.jsx("td",{className:"col-index",children:t+1});Rs.headerName="#";const As=({flow:t})=>o.jsx("td",{className:"col-icon",children:o.jsx("div",{className:je("resource-icon",Si(t))})});As.headerName="";const Ds=({flow:t})=>{let e;return t.error&&(t.error.msg==="Connection killed."?e=o.jsx("i",{className:"fa fa-fw fa-times pull-right"}):e=o.jsx("i",{className:"fa fa-fw fa-exclamation pull-right"})),o.jsxs("td",{className:"col-path",children:[t.is_replay==="request"&&o.jsx("i",{className:"fa fa-fw fa-repeat pull-right"}),t.intercepted&&o.jsx("i",{className:"fa fa-fw fa-pause pull-right"}),e,o.jsx("span",{className:"marker pull-right",children:t.marked}),$i(t)]})};Ds.headerName="Path";const Fs=({flow:t})=>o.jsx("td",{className:"col-method",children:Ni(t)});Fs.headerName="Method";const Is=({flow:t})=>o.jsx("td",{className:"col-http-version",children:ki(t)});Is.headerName="Version";const Ls=({flow:t})=>{let e="darkred";return t.type!=="http"&&t.type!="dns"||!t.response?o.jsx("td",{className:"col-status"}):(100<=t.response.status_code&&t.response.status_code<200?e="green":200<=t.response.status_code&&t.response.status_code<300?e="darkgreen":300<=t.response.status_code&&t.response.status_code<400?e="lightblue":(400<=t.response.status_code&&t.response.status_code<500||500<=t.response.status_code&&t.response.status_code<600)&&(e="red"),o.jsx("td",{className:"col-status",style:{color:e},children:Ci(t)}))};Ls.headerName="Status";const Ps=({flow:t})=>o.jsx("td",{className:"col-size",children:hi(wi(t))});Ps.headerName="Size";const Os=({flow:t})=>{const e=Wt(t),s=yi(t);return o.jsx("td",{className:"col-time",children:e&&s?mi(1e3*(s-e)):"..."})};Os.headerName="Time";const Ms=({flow:t})=>{const e=Wt(t);return o.jsx("td",{className:"col-timestamp",children:e?at(e):"..."})};Ms.headerName="Start time";const Qt=({flow:t})=>{const e=G();let s=null;return t.intercepted?s=o.jsx("a",{href:"#",className:"quickaction",onClick:()=>e(ys([t])),children:o.jsx("i",{className:"fa fa-fw fa-play text-success"})}):xs(t)&&(s=o.jsx("a",{href:"#",className:"quickaction",onClick:()=>e(ws([t])),children:o.jsx("i",{className:"fa fa-fw fa-repeat text-primary"})})),o.jsx("td",{className:"col-quickactions",children:s?o.jsx("div",{children:s}):o.jsx(o.Fragment,{})})};Qt.headerName="";const qs=({flow:t})=>{const e=t.comment;return o.jsx("td",{className:"col-comment",children:e})};qs.headerName="Comment";const Qr={icon:As,index:Rs,method:Fs,version:Is,path:Ds,quickactions:Qt,size:Ps,status:Ls,time:Os,timestamp:Ms,tls:Ts,comment:qs},cd=Object.freeze(Object.defineProperty({__proto__:null,comment:qs,default:Qr,icon:As,index:Rs,method:Fs,path:Ds,quickactions:Qt,size:Ps,status:Ls,time:Os,timestamp:Ms,tls:Ts,version:Is},Symbol.toStringTag,{value:"Module"})),ad=I.memo(function(){const e=k.c(13),s=G(),i=D(dd),r=D(ud),n=D(fd),l=i?"sort-desc":"sort-asc";let a;if(e[0]!==s||e[1]!==n||e[2]!==r||e[3]!==i||e[4]!==l){const f=n.filter(zl).concat("quickactions");let p;e[6]!==s||e[7]!==r||e[8]!==i||e[9]!==l?(p=h=>o.jsx("th",{className:je(`col-${h}`,r===h&&l),onClick:()=>s(Ui({column:h===r&&i?void 0:h,desc:h!==r?!1:!i})),children:Qr[h].headerName},h),e[6]=s,e[7]=r,e[8]=i,e[9]=l,e[10]=p):p=e[10],a=f.map(p),e[0]=s,e[1]=n,e[2]=r,e[3]=i,e[4]=l,e[5]=a}else a=e[5];let d;return e[11]!==a?(d=o.jsx("tr",{children:a}),e[11]=a,e[12]=d):d=e[12],d});function dd(t){return t.flows.sort.desc}function ud(t){return t.flows.sort.column}function fd(t){return t.options.web_columns}const pd=Te.memo(function({flow:e,selected:s,highlighted:i,displayColumnNames:r,rowNumber:n}){const l=G(),a=je({selected:s,highlighted:i,intercepted:e.intercepted,"has-request":e.type==="http"&&e.request,"has-response":e.type==="http"&&e.response}),d=I.useCallback(p=>{let h=p.target;for(;h.parentNode;){if(h.classList.contains("col-quickactions"))return;h=h.parentNode}p.metaKey||p.ctrlKey?l(ic(e)):p.shiftKey?(window.getSelection()?.empty(),l(rc(e))):l(Ve([e]))},[e]),f=r.map(p=>cd[p]).filter(p=>p).concat(Qt);return o.jsx("tr",{className:a,onClick:d,children:f.map(p=>o.jsx(p,{flow:e,rowNumber:n},p.name))})});class hd extends I.Component{static defaultProps={rowHeight:32};viewport=I.createRef();head=I.createRef();constructor(e,s){super(e,s),this.state={vScroll:kt(),viewportTop:0},this.onViewportUpdate=this.onViewportUpdate.bind(this)}componentDidMount(){window.addEventListener("resize",this.onViewportUpdate),this.onViewportUpdate()}componentWillUnmount(){window.removeEventListener("resize",this.onViewportUpdate)}getSnapshotBeforeUpdate(){return Es(this.viewport)}componentDidUpdate(e,s,i){i&&Jr(this.viewport),this.onViewportUpdate();const{onlySelectedId:r}=this.props;if(r&&r!==e.onlySelectedId){const{rowHeight:l,firstSelectedIndex:a}=this.props,d=this.viewport.current,f=this.head.current,p=f?f.offsetHeight:0,h=a*l+p,g=h+l,_=d.scrollTop,j=d.offsetHeight;h-p<_?d.scrollTop=h-p:g>_+j&&(d.scrollTop=g-j),this.onViewportUpdate()}}onViewportUpdate(){const e=this.viewport.current,s=e.scrollTop||0,i=kt({viewportTop:s,viewportHeight:e.offsetHeight||0,itemCount:this.props.flowView.length,rowHeight:this.props.rowHeight});if(this.state.viewportTop!==s||!Kt(this.state.vScroll,i)){const r=Math.min(s,i.end*this.props.rowHeight);this.setState({vScroll:i,viewportTop:r})}}render(){const{vScroll:e,viewportTop:s}=this.state,{flowView:i,selectedIds:r,highlightedIds:n,displayColumnNames:l,listIndex:a}=this.props;return o.jsx("div",{className:"flow-table",onScroll:this.onViewportUpdate,ref:this.viewport,children:o.jsxs("table",{children:[o.jsx("thead",{ref:this.head,style:{transform:`translateY(${s}px)`},children:o.jsx(ad,{})}),o.jsxs("tbody",{children:[o.jsx("tr",{style:{height:e.paddingTop}}),i.slice(e.start,e.end).map(d=>o.jsx(pd,{flow:d,selected:r.has(d.id),highlighted:n.has(d.id),displayColumnNames:l,rowNumber:a.get(d.id)},d.id)),o.jsx("tr",{style:{height:e.paddingBottom}})]})]})})}}const md=zt(t=>({flowView:t.flows.view,highlightedIds:t.flows.highlightedIds,selectedIds:t.flows.selectedIds,onlySelectedId:t.flows.selected.length===1&&t.flows.selected[0].id,firstSelectedIndex:t.flows._viewIndex.get(t.flows.selected[0]?.id),displayColumnNames:t.options.web_columns,listIndex:t.flows._listIndex}))(hd);function gd(){const t=k.c(3);let e,s;t[0]===Symbol.for("react.memo_cache_sentinel")?(e={padding:"1em 2em"},s=o.jsx("h3",{children:"mitmproxy is running."}),t[0]=e,t[1]=s):(e=t[0],s=t[1]);let i;return t[2]===Symbol.for("react.memo_cache_sentinel")?(i=o.jsxs("div",{style:e,children:[s,o.jsxs("p",{children:["No flows have been recorded yet.",o.jsx("br",{}),"To start capturing traffic, please configure your settings in the Capture tab."]})]}),t[2]=i):i=t[2],i}function vd(t){const e=k.c(20);let{description:s,listen_addrs:i,is_running:r,wireguard_conf:n,type:l}=t;const a=I.useRef(null);let d,f;e[0]!==n?(d=()=>{n&&a.current&&Ll.toCanvas(a.current,n,{margin:0,scale:3})},f=[n],e[0]=n,e[1]=d,e[2]=f):(d=e[1],f=e[2]),I.useEffect(d,f);let p;const h=i.length===1||i.length===2&&i[0][1]===i[1][1],g=i.every(xd);if(h&&g){let y;e[3]!==i[0][1]?(y=Hn(["*",i[0][1]]),e[3]=i[0][1],e[4]=y):y=e[4],p=y}else{let y;e[5]!==i?(y=i.map(Hn).join(" and "),e[5]=i,e[6]=y):y=e[6],p=y}s=s[0].toUpperCase()+s.substr(1);let _;if(r){let y;e[9]!==s||e[10]!==p||e[11]!==l?(y=l==="local"?o.jsxs("div",{className:"text-success",children:[s," is active."]}):o.jsxs("div",{className:"text-success",children:[s," listening at ",p,"."]}),e[9]=s,e[10]=p,e[11]=l,e[12]=y):y=e[12];let w;e[13]!==n?(w=n&&o.jsxs("div",{className:"wireguard-config",children:[o.jsx("pre",{children:n}),o.jsx("canvas",{ref:a})]}),e[13]=n,e[14]=w):w=e[14];let $;e[15]!==y||e[16]!==w?($=o.jsxs(o.Fragment,{children:[y,w]}),e[15]=y,e[16]=w,e[17]=$):$=e[17],_=$}else{let y;e[7]!==s?(y=o.jsx(o.Fragment,{children:o.jsxs("div",{className:"text-warning",children:[s," starting..."]})}),e[7]=s,e[8]=y):y=e[8],_=y}let j;return e[18]!==_?(j=o.jsx("div",{children:_}),e[18]=_,e[19]=j):j=e[19],j}function xd(t){return["::","0.0.0.0"].includes(t[0])}function et(t){const e=k.c(5),{error:s,backendState:i}=t;let r;e[0]!==i||e[1]!==s?(r=s?o.jsx("div",{className:"text-danger",children:s}):i&&o.jsx(vd,{...i}),e[0]=i,e[1]=s,e[2]=r):r=e[2];let n;return e[3]!==r?(n=o.jsx("div",{className:"mode-status",children:r}),e[3]=r,e[4]=n):n=e[4],n}function tt(t){const e=k.c(13),{value:s,onChange:i,children:r,label:n}=t,l=I.useId(),a=`mode-checkbox-${l}`,d=`mode-checkbox-${l}`;let f;e[0]!==i||e[1]!==a||e[2]!==d||e[3]!==s?(f=o.jsx("input",{type:"checkbox",name:a,id:d,checked:s,onChange:i}),e[0]=i,e[1]=a,e[2]=d,e[3]=s,e[4]=f):f=e[4];const p=`mode-checkbox-${l}`;let h;e[5]===Symbol.for("react.memo_cache_sentinel")?(h={marginBottom:0,fontWeight:"normal"},e[5]=h):h=e[5];let g;e[6]!==n||e[7]!==p?(g=o.jsx("label",{htmlFor:p,style:h,children:n}),e[6]=n,e[7]=p,e[8]=g):g=e[8];let _;return e[9]!==r||e[10]!==f||e[11]!==g?(_=o.jsxs("div",{className:"mode-entry",children:[f,g,r]}),e[9]=r,e[10]=f,e[11]=g,e[12]=_):_=e[12],_}function st(t){const e=k.c(22),{children:s,iconClass:i,classname:r,isVisible:n}=t,l=I.useId();let a;e[0]!==l?(a=[...l].map(_d),e[0]=l,e[1]=a):a=e[1];const d="--"+a.join(""),f=I.useRef(null),p=I.useRef(null);let h;e[2]!==d?(h=()=>{f.current.style.anchorName=d,p.current.style.positionAnchor=d},e[2]=d,e[3]=h):h=e[3];let g;e[4]===Symbol.for("react.memo_cache_sentinel")?(g=[],e[4]=g):g=e[4],I.useEffect(h,g);let _;e[5]!==l||e[6]!==n?(_=()=>{n===!0&&document.getElementById(l)?.showPopover()},e[5]=l,e[6]=n,e[7]=_):_=e[7];let j;e[8]!==n?(j=[n],e[8]=n,e[9]=j):j=e[9],I.useEffect(_,j);const y=r?`mode-popover ${r}`:"mode-popover";let w;e[10]!==i?(w=o.jsx("i",{className:i,"aria-hidden":"true"}),e[10]=i,e[11]=w):w=e[11];let $;e[12]!==l||e[13]!==w?($=o.jsx("button",{popoverTarget:l,ref:f,children:w}),e[12]=l,e[13]=w,e[14]=$):$=e[14];let N;e[15]!==s||e[16]!==l?(N=o.jsx("div",{id:l,popover:"auto",ref:p,children:s}),e[15]=s,e[16]=l,e[17]=N):N=e[17];let E;return e[18]!==y||e[19]!==$||e[20]!==N?(E=o.jsxs("div",{className:y,children:[$,N]}),e[18]=y,e[19]=$,e[20]=N,e[21]=E):E=e[21],E}function _d(t){return t.charCodeAt(0).toString(16)}function jd(t){const e=k.c(44),{server:s}=t,{currentProcesses:i,isLoading:r}=D(bd),{selectedProcesses:n}=D(wd);let l;e[0]===Symbol.for("react.memo_cache_sentinel")?(l=[],e[0]=l):l=e[0];const[a,d]=I.useState(l),[f,p]=I.useState(""),h=G(),{platform:g}=D(yd);let _;e[1]===Symbol.for("react.memo_cache_sentinel")?(_=B=>{p(B.target.value)},e[1]=_):_=e[1];const j=_;let y;e[2]!==g?(y=B=>{const oe=g.startsWith("win32")?"\\":"/";return ps(B.executable,oe)[1]},e[2]=g,e[3]=y):y=e[3];const w=y;let $;e[4]!==h||e[5]!==w||e[6]!==n||e[7]!==s?($=B=>{const oe=typeof B=="string"?B:w(B),q=n?`${n}, ${oe}`:oe;h(St({server:s,value:q}))},e[4]=h,e[5]=w,e[6]=n,e[7]=s,e[8]=$):$=e[8];const N=$;let E;e[9]!==h||e[10]!==w||e[11]!==n||e[12]!==s?(E=B=>{const oe=n?.split(/,\s*/).filter(q=>q!==w(B)).join(", ");h(St({server:s,value:oe}))},e[9]=h,e[10]=w,e[11]=n,e[12]=s,e[13]=E):E=e[13];const T=E,P=B=>{L(B)&&n?T(B):N(B)},L=B=>{const oe=w(B);return n?.includes(oe)};let O;e[14]!==i||e[15]!==h?(O=()=>{i.length===0&&h($t())},e[14]=i,e[15]=h,e[16]=O):O=e[16];let M;e[17]===Symbol.for("react.memo_cache_sentinel")?(M=[],e[17]=M):M=e[17],I.useEffect(O,M);let U;e[18]!==i||e[19]!==f||e[20]!==w||e[21]!==a?(U=()=>{if(f){const B=i.filter(oe=>w(oe).toLowerCase().includes(f.toLowerCase()));d(B)}else a!==i&&d(i)},e[18]=i,e[19]=f,e[20]=w,e[21]=a,e[22]=U):U=e[22];let V;e[23]!==i||e[24]!==f?(V=[f,i],e[23]=i,e[24]=f,e[25]=V):V=e[25],I.useEffect(U,V);let W;e[26]!==N||e[27]!==f?(W=B=>{B.stopPropagation(),B.key==="Enter"&&(N(f),p(""))},e[26]=N,e[27]=f,e[28]=W):W=e[28];const J=W,[z,te]=I.useState(!1),Y="local-dropdown",Q="dropdown-header",X=n&&n?.length>0?"Add more":"all applications";let Z,ae;e[29]===Symbol.for("react.memo_cache_sentinel")?(Z=()=>te(!0),ae=()=>te(!1),e[29]=Z,e[30]=ae):(Z=e[29],ae=e[30]);let le;e[31]!==f||e[32]!==J||e[33]!==X?(le=o.jsx("input",{type:"text",className:"autocomplete-input",placeholder:X,value:f,onChange:j,onKeyDown:J,onClick:Z,onBlur:ae}),e[31]=f,e[32]=J,e[33]=X,e[34]=le):le=e[34];const de=st,ye="fa fa-chevron-down",Pe="local-popover";let Se;e[35]===Symbol.for("react.memo_cache_sentinel")?(Se=o.jsx("h4",{children:"Current Applications running on machine"}),e[35]=Se):Se=e[35];const Ee=r?o.jsx("i",{className:"fa fa-spinner","aria-hidden":"true"}):a.length>0?o.jsxs("ul",{className:"dropdown-list",children:[o.jsxs("li",{className:`dropdown-item ${n===""?"selected":""}`,onClick:()=>{h(St({server:s,value:""}))},role:"menuitem",children:[o.jsxs("div",{className:"process-details",children:[o.jsx("div",{className:"process-icon"}),o.jsx("span",{className:"process-name",children:"All applications"})]}),n===""&&o.jsx("i",{className:"fa fa-check","aria-hidden":"true"})]}),o.jsx("hr",{className:"process-separator"}),a.map((B,oe)=>o.jsxs("li",{className:`dropdown-item ${L(B)?"selected":""}`,onClick:()=>P(B),role:"menuitem",children:[o.jsxs("div",{className:"process-details",children:[o.jsx("img",{className:"process-icon",src:`./executable-icon?path=${B.executable}`,loading:"lazy"}),o.jsx("span",{className:"process-name",children:w(B)})]}),L(B)&&o.jsx("i",{className:"fa fa-check","aria-hidden":"true"})]},oe))]}):o.jsxs("span",{children:["Press ",o.jsx("strong",{children:"Enter"})," to capture traffic for programs matching: ",o.jsx("strong",{children:f})]});let C;e[36]!==de||e[37]!==z||e[38]!==Se||e[39]!==Ee?(C=o.jsxs(de,{iconClass:ye,classname:Pe,isVisible:z,children:[Se,Ee]}),e[36]=de,e[37]=z,e[38]=Se,e[39]=Ee,e[40]=C):C=e[40];let he;return e[41]!==le||e[42]!==C?(he=o.jsx("div",{className:Y,children:o.jsxs("div",{className:Q,children:[le,C]})}),e[41]=le,e[42]=C,e[43]=he):he=e[43],he}function yd(t){return t.backendState}function wd(t){return t.modes.local[0]}function bd(t){return t.processes}function Sd(){const t=k.c(9),e=D(Cd),s=D($d);let i;if(t[0]!==s||t[1]!==e){let d;t[3]!==s?(d=f=>o.jsx(Nd,{server:f,backendState:s[Zi(f)]},f.ui_id),t[3]=s,t[4]=d):d=t[4],i=e.map(d),t[0]=s,t[1]=e,t[2]=i}else i=t[2];const r=i;let n,l;t[5]===Symbol.for("react.memo_cache_sentinel")?(n=o.jsx("h4",{className:"mode-title",children:"Local Applications"}),l=o.jsx("p",{className:"mode-description",children:"Transparently Intercept local application(s)."}),t[5]=n,t[6]=l):(n=t[5],l=t[6]);let a;return t[7]!==r?(a=o.jsxs("div",{children:[n,l,r]}),t[7]=r,t[8]=a):a=t[8],a}function $d(t){return t.backendState.servers}function Cd(t){return t.modes.local}function Nd(t){const e=k.c(31),{server:s,backendState:i}=t,r=G(),n=D(Ed),l=s.error||i?.last_exception||n||void 0;let a;e[0]!==r||e[1]!==s?(a=E=>{const T=s.selectedProcesses?.split(/,\s*/).filter(P=>P!==E).join(", ");r(St({server:s,value:T}))},e[0]=r,e[1]=s,e[2]=a):a=e[2];const d=a;let f;e[3]!==r||e[4]!==s?(f=()=>r(cr({server:s,value:!s.active})),e[3]=r,e[4]=s,e[5]=f):f=e[5];let p;e[6]!==d||e[7]!==s.selectedProcesses?(p=s.selectedProcesses?.split(/,\s*/).filter(kd).map(E=>o.jsxs("div",{className:"selected-process",children:[E,o.jsx("i",{className:"fa fa-times","aria-hidden":"true",onClick:()=>d(E)})]},E)),e[6]=d,e[7]=s.selectedProcesses,e[8]=p):p=e[8];let h;e[9]!==p?(h=o.jsx("div",{className:"selected-processes",children:p}),e[9]=p,e[10]=h):h=e[10];let g;e[11]!==s?(g=o.jsx(jd,{server:s}),e[11]=s,e[12]=g):g=e[12];let _;e[13]!==r?(_=o.jsx("i",{className:"fa fa-refresh","aria-hidden":"true",onClick:()=>r($t())}),e[13]=r,e[14]=_):_=e[14];let j;e[15]!==g||e[16]!==_?(j=o.jsxs("div",{className:"dropdown-container",children:[g,_]}),e[15]=g,e[16]=_,e[17]=j):j=e[17];let y;e[18]!==h||e[19]!==j?(y=o.jsxs("div",{className:"processes-container",children:[h,j]}),e[18]=h,e[19]=j,e[20]=y):y=e[20];let w;e[21]!==s.active||e[22]!==f||e[23]!==y?(w=o.jsx(tt,{value:s.active,label:"Intercept traffic for",onChange:f,children:y}),e[21]=s.active,e[22]=f,e[23]=y,e[24]=w):w=e[24];let $;e[25]!==i||e[26]!==l?($=o.jsx(et,{error:l,backendState:i}),e[25]=i,e[26]=l,e[27]=$):$=e[27];let N;return e[28]!==$||e[29]!==w?(N=o.jsxs("div",{className:"mode-local",children:[w,$]}),e[28]=$,e[29]=w,e[30]=N):N=e[30],N}function kd(t){return t.trim()!==""}function Ed(t){return t.processes.error}function Td(){const t=k.c(9),e=D(Ad),s=D(Rd);let i;if(t[0]!==s||t[1]!==e){let d;t[3]!==s?(d=f=>o.jsx(Dd,{server:f,backendState:s[Xi(f)]},f.ui_id),t[3]=s,t[4]=d):d=t[4],i=e.map(d),t[0]=s,t[1]=e,t[2]=i}else i=t[2];const r=i;let n,l;t[5]===Symbol.for("react.memo_cache_sentinel")?(n=o.jsx("h4",{className:"mode-title",children:"Explicit HTTP(S) Proxy"}),l=o.jsx("p",{className:"mode-description",children:"You manually configure your client application or device to use an HTTP(S) proxy."}),t[5]=n,t[6]=l):(n=t[5],l=t[6]);let a;return t[7]!==r?(a=o.jsxs("div",{children:[n,l,r]}),t[7]=r,t[8]=a):a=t[8],a}function Rd(t){return t.backendState.servers}function Ad(t){return t.modes.regular}function Dd(t){const e=k.c(33),{server:s,backendState:i}=t,r=G(),n=s.error||i?.last_exception||void 0;let l;e[0]!==r||e[1]!==s?(l=()=>r(rr({server:s,value:!s.active})),e[0]=r,e[1]=s,e[2]=l):l=e[2];let a,d;e[3]===Symbol.for("react.memo_cache_sentinel")?(a=o.jsx("h4",{children:"Advanced Configuration"}),d=o.jsx("p",{children:"Listen Host"}),e[3]=a,e[4]=d):(a=e[3],d=e[4]);const f=s.listen_host||"";let p;e[5]!==r||e[6]!==s?(p=T=>r(or({server:s,value:T})),e[5]=r,e[6]=s,e[7]=p):p=e[7];let h;e[8]!==f||e[9]!==p?(h=o.jsx(ce,{className:"mode-input",content:f,onEditDone:p}),e[8]=f,e[9]=p,e[10]=h):h=e[10];let g;e[11]===Symbol.for("react.memo_cache_sentinel")?(g=o.jsx("p",{children:"Listen Port"}),e[11]=g):g=e[11];let _;e[12]!==s.listen_port?(_=s.listen_port?s.listen_port.toString():"",e[12]=s.listen_port,e[13]=_):_=e[13];let j;e[14]!==r||e[15]!==s?(j=T=>r(lr({server:s,value:parseInt(T)})),e[14]=r,e[15]=s,e[16]=j):j=e[16];let y;e[17]!==_||e[18]!==j?(y=o.jsx(ce,{className:"mode-input",content:_,placeholder:"8080",onEditDone:j}),e[17]=_,e[18]=j,e[19]=y):y=e[19];let w;e[20]!==y||e[21]!==h?(w=o.jsxs(st,{iconClass:"fa fa-cog",children:[a,d,h,g,y]}),e[20]=y,e[21]=h,e[22]=w):w=e[22];let $;e[23]!==s.active||e[24]!==l||e[25]!==w?($=o.jsx(tt,{value:s.active,label:"Run HTTP/S Proxy",onChange:l,children:w}),e[23]=s.active,e[24]=l,e[25]=w,e[26]=$):$=e[26];let N;e[27]!==i||e[28]!==n?(N=o.jsx(et,{error:n,backendState:i}),e[27]=i,e[28]=n,e[29]=N):N=e[29];let E;return e[30]!==$||e[31]!==N?(E=o.jsxs("div",{children:[$,N]}),e[30]=$,e[31]=N,e[32]=E):E=e[32],E}function Fd(){const t=k.c(9),e=D(Ld),s=D(Id);let i;if(t[0]!==s||t[1]!==e){let d;t[3]!==s?(d=f=>o.jsx(Pd,{server:f,backendState:s[er(f)]},f.ui_id),t[3]=s,t[4]=d):d=t[4],i=e.map(d),t[0]=s,t[1]=e,t[2]=i}else i=t[2];const r=i;let n,l;t[5]===Symbol.for("react.memo_cache_sentinel")?(n=o.jsx("h4",{className:"mode-title",children:"WireGuard Server"}),l=o.jsx("p",{className:"mode-description",children:"Start a WireGuard™ server and connect an external device for transparent proxying."}),t[5]=n,t[6]=l):(n=t[5],l=t[6]);let a;return t[7]!==r?(a=o.jsxs("div",{children:[n,l,r]}),t[7]=r,t[8]=a):a=t[8],a}function Id(t){return t.backendState.servers}function Ld(t){return t.modes.wireguard}function Pd(t){const e=k.c(41),{server:s,backendState:i}=t,r=G(),n=s.error||i?.last_exception||void 0;let l;e[0]!==r||e[1]!==s?(l=()=>r(ar({server:s,value:!s.active})),e[0]=r,e[1]=s,e[2]=l):l=e[2];let a,d;e[3]===Symbol.for("react.memo_cache_sentinel")?(a=o.jsx("h4",{children:"Advanced Configuration"}),d=o.jsx("p",{children:"Listen Host"}),e[3]=a,e[4]=d):(a=e[3],d=e[4]);const f=s.listen_host||"";let p;e[5]!==r||e[6]!==s?(p=M=>r(dr({server:s,value:M})),e[5]=r,e[6]=s,e[7]=p):p=e[7];let h;e[8]!==f||e[9]!==p?(h=o.jsx(ce,{className:"mode-input",content:f,placeholder:"(all interfaces)",onEditDone:p}),e[8]=f,e[9]=p,e[10]=h):h=e[10];let g;e[11]===Symbol.for("react.memo_cache_sentinel")?(g=o.jsx("p",{children:"Listen Port"}),e[11]=g):g=e[11];let _;e[12]!==s.listen_port?(_=s.listen_port?s.listen_port.toString():"",e[12]=s.listen_port,e[13]=_):_=e[13];let j;e[14]!==r||e[15]!==s?(j=M=>r(ur({server:s,value:parseInt(M)})),e[14]=r,e[15]=s,e[16]=j):j=e[16];let y;e[17]!==_||e[18]!==j?(y=o.jsx(ce,{className:"mode-input",content:_,placeholder:"51820",onEditDone:j}),e[17]=_,e[18]=j,e[19]=y):y=e[19];let w;e[20]===Symbol.for("react.memo_cache_sentinel")?(w=o.jsx("p",{children:"Configuration File"}),e[20]=w):w=e[20];const $=s.file_path||"";let N;e[21]!==r||e[22]!==s?(N=M=>r(fr({server:s,value:M})),e[21]=r,e[22]=s,e[23]=N):N=e[23];let E;e[24]!==$||e[25]!==N?(E=o.jsx(ce,{className:"mode-input",content:$,placeholder:"~/.mitmproxy/wireguard.conf",onEditDone:N}),e[24]=$,e[25]=N,e[26]=E):E=e[26];let T;e[27]!==y||e[28]!==E||e[29]!==h?(T=o.jsxs(st,{iconClass:"fa fa-cog",children:[a,d,h,g,y,w,E]}),e[27]=y,e[28]=E,e[29]=h,e[30]=T):T=e[30];let P;e[31]!==s.active||e[32]!==l||e[33]!==T?(P=o.jsx(tt,{value:s.active,label:"Run WireGuard Server",onChange:l,children:T}),e[31]=s.active,e[32]=l,e[33]=T,e[34]=P):P=e[34];let L;e[35]!==i||e[36]!==n?(L=o.jsx(et,{error:n,backendState:i}),e[35]=i,e[36]=n,e[37]=L):L=e[37];let O;return e[38]!==P||e[39]!==L?(O=o.jsxs("div",{children:[P,L]}),e[38]=P,e[39]=L,e[40]=O):O=e[40],O}function Od(){const t=k.c(15),e=G(),s=D(qd),i=D(Md);let r,n;t[0]===Symbol.for("react.memo_cache_sentinel")?(r=o.jsx("h4",{className:"mode-title",children:"Reverse Proxy"}),n=o.jsx("p",{className:"mode-description",children:"Requests are forwarded to a preconfigured destination."}),t[0]=r,t[1]=n):(r=t[0],n=t[1]);let l;if(t[2]!==i||t[3]!==s){let h;t[5]!==i?(h=(g,_)=>o.jsx(Hd,{removable:_>0,server:g,backendState:i[Ns(g)]},g.ui_id),t[5]=i,t[6]=h):h=t[6],l=s.map(h),t[2]=i,t[3]=s,t[4]=l}else l=t[4];let a;t[7]!==e?(a=()=>e(na()),t[7]=e,t[8]=a):a=t[8];let d;t[9]===Symbol.for("react.memo_cache_sentinel")?(d=o.jsx("i",{className:"fa fa-plus-square-o","aria-hidden":"true"}),t[9]=d):d=t[9];let f;t[10]!==a?(f=o.jsxs("div",{className:"mode-reverse-add-server",onClick:a,children:[d,"Add additional server"]}),t[10]=a,t[11]=f):f=t[11];let p;return t[12]!==l||t[13]!==f?(p=o.jsxs("div",{children:[r,n,o.jsxs("div",{className:"mode-reverse-servers",children:[l,f]})]}),t[12]=l,t[13]=f,t[14]=p):p=t[14],p}function Md(t){return t.backendState.servers}function qd(t){return t.modes.reverse}function Hd(t){const e=k.c(56),{removable:s,server:i,backendState:r}=t,n=G();let l;e[0]===Symbol.for("react.memo_cache_sentinel")?(l=Object.values(Jt),e[0]=l):l=e[0];const a=l;let d;e[1]!==n||e[2]!==i?(d=async()=>{i.active&&await n(ms({server:i,value:!1})).unwrap(),await n(ia(i))},e[1]=n,e[2]=i,e[3]=d):d=e[3];const f=d,p=i.error||r?.last_exception||void 0,h=i.active;let g;e[4]!==n||e[5]!==i?(g=()=>{n(ms({server:i,value:!i.active}))},e[4]=n,e[5]=i,e[6]=g):g=e[6];const _=i.protocol;let j;e[7]!==n||e[8]!==i?(j=Z=>{n(mr({server:i,value:Z.target.value}))},e[7]=n,e[8]=i,e[9]=j):j=e[9];let y;e[10]===Symbol.for("react.memo_cache_sentinel")?(y=a.map(Vd),e[10]=y):y=e[10];let w;e[11]!==i.protocol||e[12]!==j?(w=o.jsx("select",{name:"protocols",className:"mode-reverse-dropdown",value:_,onChange:j,children:y}),e[11]=i.protocol,e[12]=j,e[13]=w):w=e[13];let $;e[14]!==i.destination?($=i.destination?.toString()||"",e[14]=i.destination,e[15]=$):$=e[15];let N;e[16]!==n||e[17]!==i?(N=Z=>n(gr({server:i,value:Z})),e[16]=n,e[17]=i,e[18]=N):N=e[18];let E;e[19]!==N||e[20]!==$?(E=o.jsx(ce,{className:"mode-reverse-input",content:$,onEditDone:N,placeholder:"example.com"}),e[19]=N,e[20]=$,e[21]=E):E=e[21];let T,P;e[22]===Symbol.for("react.memo_cache_sentinel")?(T=o.jsx("h4",{children:"Advanced Configuration"}),P=o.jsx("p",{children:"Listen Host"}),e[22]=T,e[23]=P):(T=e[22],P=e[23]);const L=i.listen_host||"";let O;e[24]!==n||e[25]!==i?(O=Z=>n(pr({server:i,value:Z})),e[24]=n,e[25]=i,e[26]=O):O=e[26];let M;e[27]!==L||e[28]!==O?(M=o.jsx(ce,{className:"mode-input",content:L,onEditDone:O,placeholder:"*"}),e[27]=L,e[28]=O,e[29]=M):M=e[29];let U;e[30]===Symbol.for("react.memo_cache_sentinel")?(U=o.jsx("p",{children:"Listen Port"}),e[30]=U):U=e[30];const V=String(i.listen_port||"");let W;e[31]!==n||e[32]!==i?(W=Z=>n(hr({server:i,value:Z})),e[31]=n,e[32]=i,e[33]=W):W=e[33];let J;e[34]!==V||e[35]!==W?(J=o.jsx(ce,{className:"mode-input",content:V,onEditDone:W,placeholder:"8080"}),e[34]=V,e[35]=W,e[36]=J):J=e[36];let z;e[37]!==M||e[38]!==J?(z=o.jsxs(st,{iconClass:"fa fa-cog",children:[T,P,M,U,J]}),e[37]=M,e[38]=J,e[39]=z):z=e[39];let te;e[40]!==f||e[41]!==s?(te=s&&o.jsx("i",{className:"fa fa-fw fa-trash fa-lg","aria-hidden":"true",onClick:f}),e[40]=f,e[41]=s,e[42]=te):te=e[42];let Y;e[43]!==i.active||e[44]!==E||e[45]!==z||e[46]!==te||e[47]!==g||e[48]!==w?(Y=o.jsxs(tt,{value:h,label:"Forward",onChange:g,children:[w,"traffic to",E,z,te]}),e[43]=i.active,e[44]=E,e[45]=z,e[46]=te,e[47]=g,e[48]=w,e[49]=Y):Y=e[49];let Q;e[50]!==r||e[51]!==p?(Q=o.jsx(et,{error:p,backendState:r}),e[50]=r,e[51]=p,e[52]=Q):Q=e[52];let X;return e[53]!==Y||e[54]!==Q?(X=o.jsxs("div",{children:[Y,Q]}),e[53]=Y,e[54]=Q,e[55]=X):X=e[55],X}function Vd(t){return o.jsx("option",{value:t,children:t},t)}function Ud(){const t=k.c(9),e=D(Wd),s=D(Bd);let i;if(t[0]!==s||t[1]!==e){let d;t[3]!==s?(d=f=>o.jsx(Kd,{server:f,backendState:s[tr(f)]},f.ui_id),t[3]=s,t[4]=d):d=t[4],i=e.map(d),t[0]=s,t[1]=e,t[2]=i}else i=t[2];const r=i;let n;t[5]===Symbol.for("react.memo_cache_sentinel")?(n=o.jsx("h4",{className:"mode-title",children:"Transparent Proxy"}),t[5]=n):n=t[5];let l;t[6]===Symbol.for("react.memo_cache_sentinel")?(l=o.jsxs("p",{className:"mode-description",children:["You"," ",o.jsx("a",{href:"https://docs.mitmproxy.org/stable/howto-transparent/",style:{textDecoration:"underline",color:"inherit"},children:"configure your routing table"})," ","to send traffic through mitmproxy."]}),t[6]=l):l=t[6];let a;return t[7]!==r?(a=o.jsxs("div",{children:[n,l,r]}),t[7]=r,t[8]=a):a=t[8],a}function Bd(t){return t.backendState.servers}function Wd(t){return t.modes.transparent}function Kd(t){const e=k.c(33),{server:s,backendState:i}=t,r=G(),n=s.error||i?.last_exception||void 0;let l;e[0]!==r||e[1]!==s?(l=()=>r(xr({server:s,value:!s.active})),e[0]=r,e[1]=s,e[2]=l):l=e[2];let a,d;e[3]===Symbol.for("react.memo_cache_sentinel")?(a=o.jsx("h4",{children:"Advanced Configuration"}),d=o.jsx("p",{children:"Listen Host"}),e[3]=a,e[4]=d):(a=e[3],d=e[4]);const f=s.listen_host||"";let p;e[5]!==r||e[6]!==s?(p=T=>r(_r({server:s,value:T})),e[5]=r,e[6]=s,e[7]=p):p=e[7];let h;e[8]!==f||e[9]!==p?(h=o.jsx(ce,{className:"mode-input",content:f,onEditDone:p}),e[8]=f,e[9]=p,e[10]=h):h=e[10];let g;e[11]===Symbol.for("react.memo_cache_sentinel")?(g=o.jsx("p",{children:"Listen Port"}),e[11]=g):g=e[11];let _;e[12]!==s.listen_port?(_=s.listen_port?s.listen_port.toString():"",e[12]=s.listen_port,e[13]=_):_=e[13];let j;e[14]!==r||e[15]!==s?(j=T=>r(jr({server:s,value:parseInt(T)})),e[14]=r,e[15]=s,e[16]=j):j=e[16];let y;e[17]!==_||e[18]!==j?(y=o.jsx(ce,{className:"mode-input",content:_,placeholder:"8080",onEditDone:j}),e[17]=_,e[18]=j,e[19]=y):y=e[19];let w;e[20]!==y||e[21]!==h?(w=o.jsxs(st,{iconClass:"fa fa-cog",children:[a,d,h,g,y]}),e[20]=y,e[21]=h,e[22]=w):w=e[22];let $;e[23]!==s.active||e[24]!==l||e[25]!==w?($=o.jsx(tt,{value:s.active,label:"Run Transparent Proxy",onChange:l,children:w}),e[23]=s.active,e[24]=l,e[25]=w,e[26]=$):$=e[26];let N;e[27]!==i||e[28]!==n?(N=o.jsx(et,{error:n,backendState:i}),e[27]=i,e[28]=n,e[29]=N):N=e[29];let E;return e[30]!==$||e[31]!==N?(E=o.jsxs("div",{children:[$,N]}),e[30]=$,e[31]=N,e[32]=E):E=e[32],E}function zd(){const t=k.c(9),e=D(Yd),s=D(Gd);let i;if(t[0]!==s||t[1]!==e){let d;t[3]!==s?(d=f=>o.jsx(Jd,{server:f,backendState:s[sr(f)]},f.ui_id),t[3]=s,t[4]=d):d=t[4],i=e.map(d),t[0]=s,t[1]=e,t[2]=i}else i=t[2];const r=i;let n,l;t[5]===Symbol.for("react.memo_cache_sentinel")?(n=o.jsx("h4",{className:"mode-title",children:"SOCKS Proxy"}),l=o.jsx("p",{className:"mode-description",children:"You manually configure your client application or device to use a SOCKS5 proxy."}),t[5]=n,t[6]=l):(n=t[5],l=t[6]);let a;return t[7]!==r?(a=o.jsxs("div",{children:[n,l,r]}),t[7]=r,t[8]=a):a=t[8],a}function Gd(t){return t.backendState.servers}function Yd(t){return t.modes.socks}function Jd(t){const e=k.c(33),{server:s,backendState:i}=t,r=G(),n=s.error||i?.last_exception||void 0;let l;e[0]!==r||e[1]!==s?(l=()=>r(yr({server:s,value:!s.active})),e[0]=r,e[1]=s,e[2]=l):l=e[2];let a,d;e[3]===Symbol.for("react.memo_cache_sentinel")?(a=o.jsx("h4",{children:"Advanced Configuration"}),d=o.jsx("p",{children:"Listen Host"}),e[3]=a,e[4]=d):(a=e[3],d=e[4]);const f=s.listen_host||"";let p;e[5]!==r||e[6]!==s?(p=T=>r(wr({server:s,value:T})),e[5]=r,e[6]=s,e[7]=p):p=e[7];let h;e[8]!==f||e[9]!==p?(h=o.jsx(ce,{className:"mode-input",content:f,onEditDone:p}),e[8]=f,e[9]=p,e[10]=h):h=e[10];let g;e[11]===Symbol.for("react.memo_cache_sentinel")?(g=o.jsx("p",{children:"Listen Port"}),e[11]=g):g=e[11];let _;e[12]!==s.listen_port?(_=s.listen_port?s.listen_port.toString():"",e[12]=s.listen_port,e[13]=_):_=e[13];let j;e[14]!==r||e[15]!==s?(j=T=>r(br({server:s,value:parseInt(T)})),e[14]=r,e[15]=s,e[16]=j):j=e[16];let y;e[17]!==_||e[18]!==j?(y=o.jsx(ce,{className:"mode-input",content:_,placeholder:"8080",onEditDone:j}),e[17]=_,e[18]=j,e[19]=y):y=e[19];let w;e[20]!==y||e[21]!==h?(w=o.jsxs(st,{iconClass:"fa fa-cog",children:[a,d,h,g,y]}),e[20]=y,e[21]=h,e[22]=w):w=e[22];let $;e[23]!==s.active||e[24]!==l||e[25]!==w?($=o.jsx(tt,{value:s.active,label:"Run SOCKS Proxy",onChange:l,children:w}),e[23]=s.active,e[24]=l,e[25]=w,e[26]=$):$=e[26];let N;e[27]!==i||e[28]!==n?(N=o.jsx(et,{error:n,backendState:i}),e[27]=i,e[28]=n,e[29]=N):N=e[29];let E;return e[30]!==$||e[31]!==N?(E=o.jsxs("div",{children:[$,N]}),e[30]=$,e[31]=N,e[32]=E):E=e[32],E}function Qd(){const t=k.c(9),e=D(Zd),s=D(Xd);let i;if(t[0]!==s||t[1]!==e){let d;t[3]!==s?(d=f=>o.jsx(eu,{server:f,backendState:s[nr(f)]},f.ui_id),t[3]=s,t[4]=d):d=t[4],i=e.map(d),t[0]=s,t[1]=e,t[2]=i}else i=t[2];const r=i;let n,l;t[5]===Symbol.for("react.memo_cache_sentinel")?(n=o.jsx("h4",{className:"mode-title",children:"Explicit HTTP(S) Proxy (With Upstream Proxy)"}),l=o.jsx("p",{className:"mode-description",children:"All requests are forwarded to a second HTTP(S) proxy server."}),t[5]=n,t[6]=l):(n=t[5],l=t[6]);let a;return t[7]!==r?(a=o.jsxs("div",{children:[n,l,r]}),t[7]=r,t[8]=a):a=t[8],a}function Xd(t){return t.backendState.servers}function Zd(t){return t.modes.upstream}function eu(t){const e=k.c(42),{server:s,backendState:i}=t,r=G(),n=s.error||i?.last_exception||void 0;let l;e[0]!==r||e[1]!==s?(l=()=>{r(Sr({server:s,value:!s.active}))},e[0]=r,e[1]=s,e[2]=l):l=e[2];let a;e[3]!==s.destination?(a=s.destination?.toString()||"",e[3]=s.destination,e[4]=a):a=e[4];let d;e[5]!==r||e[6]!==s?(d=O=>r(Nr({server:s,value:O})),e[5]=r,e[6]=s,e[7]=d):d=e[7];let f;e[8]!==a||e[9]!==d?(f=o.jsx(ce,{className:"mode-upstream-input",content:a,onEditDone:d,placeholder:"http://example.com:8080"}),e[8]=a,e[9]=d,e[10]=f):f=e[10];let p,h;e[11]===Symbol.for("react.memo_cache_sentinel")?(p=o.jsx("h4",{children:"Advanced Configuration"}),h=o.jsx("p",{children:"Listen Host"}),e[11]=p,e[12]=h):(p=e[11],h=e[12]);const g=s.listen_host||"";let _;e[13]!==r||e[14]!==s?(_=O=>r($r({server:s,value:O})),e[13]=r,e[14]=s,e[15]=_):_=e[15];let j;e[16]!==g||e[17]!==_?(j=o.jsx(ce,{className:"mode-input",content:g,onEditDone:_}),e[16]=g,e[17]=_,e[18]=j):j=e[18];let y;e[19]===Symbol.for("react.memo_cache_sentinel")?(y=o.jsx("p",{children:"Listen Port"}),e[19]=y):y=e[19];let w;e[20]!==s.listen_port?(w=s.listen_port?s.listen_port.toString():"",e[20]=s.listen_port,e[21]=w):w=e[21];let $;e[22]!==r||e[23]!==s?($=O=>r(Cr({server:s,value:parseInt(O)})),e[22]=r,e[23]=s,e[24]=$):$=e[24];let N;e[25]!==w||e[26]!==$?(N=o.jsx(ce,{className:"mode-input",content:w,placeholder:"8080",onEditDone:$}),e[25]=w,e[26]=$,e[27]=N):N=e[27];let E;e[28]!==N||e[29]!==j?(E=o.jsxs(st,{iconClass:"fa fa-cog",children:[p,h,j,y,N]}),e[28]=N,e[29]=j,e[30]=E):E=e[30];let T;e[31]!==s.active||e[32]!==l||e[33]!==E||e[34]!==f?(T=o.jsxs(tt,{value:s.active,label:"Run HTTP/S Proxy and forward requests to",onChange:l,children:[f,E]}),e[31]=s.active,e[32]=l,e[33]=E,e[34]=f,e[35]=T):T=e[35];let P;e[36]!==i||e[37]!==n?(P=o.jsx(et,{error:n,backendState:i}),e[36]=i,e[37]=n,e[38]=P):P=e[38];let L;return e[39]!==T||e[40]!==P?(L=o.jsxs("div",{children:[T,P]}),e[39]=T,e[40]=P,e[41]=L):L=e[41],L}function tu(){const t=k.c(9),e=D(nu),s=D(su);let i;if(t[0]!==s||t[1]!==e){let d;t[3]!==s?(d=f=>o.jsx(iu,{server:f,backendState:s[ir(f)]},f.ui_id),t[3]=s,t[4]=d):d=t[4],i=e.map(d),t[0]=s,t[1]=e,t[2]=i}else i=t[2];const r=i;let n,l;t[5]===Symbol.for("react.memo_cache_sentinel")?(n=o.jsx("h4",{className:"mode-title",children:"DNS Server"}),l=o.jsx("p",{className:"mode-description",children:"A recursive DNS resolver using the host's DNS configuration."}),t[5]=n,t[6]=l):(n=t[5],l=t[6]);let a;return t[7]!==r?(a=o.jsxs("div",{children:[n,l,r]}),t[7]=r,t[8]=a):a=t[8],a}function su(t){return t.backendState.servers}function nu(t){return t.modes.dns}function iu(t){const e=k.c(33),{server:s,backendState:i}=t,r=G(),n=s.error||i?.last_exception||void 0;let l;e[0]!==r||e[1]!==s?(l=()=>r(kr({server:s,value:!s.active})),e[0]=r,e[1]=s,e[2]=l):l=e[2];let a,d;e[3]===Symbol.for("react.memo_cache_sentinel")?(a=o.jsx("h4",{children:"Advanced Configuration"}),d=o.jsx("p",{children:"Listen Host"}),e[3]=a,e[4]=d):(a=e[3],d=e[4]);const f=s.listen_host||"";let p;e[5]!==r||e[6]!==s?(p=T=>r(Er({server:s,value:T})),e[5]=r,e[6]=s,e[7]=p):p=e[7];let h;e[8]!==f||e[9]!==p?(h=o.jsx(ce,{className:"mode-input",content:f,onEditDone:p}),e[8]=f,e[9]=p,e[10]=h):h=e[10];let g;e[11]===Symbol.for("react.memo_cache_sentinel")?(g=o.jsx("p",{children:"Listen Port"}),e[11]=g):g=e[11];let _;e[12]!==s.listen_port?(_=s.listen_port?s.listen_port.toString():"",e[12]=s.listen_port,e[13]=_):_=e[13];let j;e[14]!==r||e[15]!==s?(j=T=>r(Tr({server:s,value:parseInt(T)})),e[14]=r,e[15]=s,e[16]=j):j=e[16];let y;e[17]!==_||e[18]!==j?(y=o.jsx(ce,{className:"mode-input",content:_,placeholder:"8080",onEditDone:j}),e[17]=_,e[18]=j,e[19]=y):y=e[19];let w;e[20]!==y||e[21]!==h?(w=o.jsxs(st,{iconClass:"fa fa-cog",children:[a,d,h,g,y]}),e[20]=y,e[21]=h,e[22]=w):w=e[22];let $;e[23]!==s.active||e[24]!==l||e[25]!==w?($=o.jsx(tt,{value:s.active,label:"Run DNS Server",onChange:l,children:w}),e[23]=s.active,e[24]=l,e[25]=w,e[26]=$):$=e[26];let N;e[27]!==i||e[28]!==n?(N=o.jsx(et,{error:n,backendState:i}),e[27]=i,e[28]=n,e[29]=N):N=e[29];let E;return e[30]!==$||e[31]!==N?(E=o.jsxs("div",{children:[$,N]}),e[30]=$,e[31]=N,e[32]=E):E=e[32],E}function ri(t){const e=k.c(10),{title:s,description:i}=t;let r;e[0]!==s?(r=o.jsx("h4",{className:"mode-title",children:s}),e[0]=s,e[1]=r):r=e[1];let n;e[2]===Symbol.for("react.memo_cache_sentinel")?(n=o.jsx("i",{className:"fa fa-exclamation-triangle","aria-hidden":"true"}),e[2]=n):n=e[2];let l;e[3]!==r?(l=o.jsxs("div",{className:"title-icon-container",children:[r,n]}),e[3]=r,e[4]=l):l=e[4];let a;e[5]!==i?(a=o.jsx("p",{className:"mode-description",children:i}),e[5]=i,e[6]=a):a=e[6];let d;return e[7]!==l||e[8]!==a?(d=o.jsxs("div",{className:"missing-mode-container",children:[l,a]}),e[7]=l,e[8]=a,e[9]=d):d=e[9],d}function ru(){const t=k.c(19),{platform:e,localModeUnavailable:s}=D(ou);let i,r;t[0]===Symbol.for("react.memo_cache_sentinel")?(i=o.jsx("h2",{children:"Intercept Traffic"}),r=o.jsx("p",{children:"Configure how you want to intercept traffic with mitmproxy."}),t[0]=i,t[1]=r):(i=t[0],r=t[1]);let n;t[2]===Symbol.for("react.memo_cache_sentinel")?(n=o.jsx("h3",{children:"Recommended"}),t[2]=n):n=t[2];let l;t[3]===Symbol.for("react.memo_cache_sentinel")?(l=o.jsx(Td,{}),t[3]=l):l=t[3];let a;t[4]!==s?(a=s!==null?o.jsx(ri,{title:"Local Redirect Mode",description:s}):o.jsx(Sd,{}),t[4]=s,t[5]=a):a=t[5];let d,f;t[6]===Symbol.for("react.memo_cache_sentinel")?(d=o.jsx(Fd,{}),f=o.jsx(Od,{}),t[6]=d,t[7]=f):(d=t[6],f=t[7]);let p;t[8]!==a?(p=o.jsxs("div",{className:"modes-category green-left-border",children:[n,o.jsxs("div",{className:"modes-container",children:[l,a,d,f]})]}),t[8]=a,t[9]=p):p=t[9];let h;t[10]===Symbol.for("react.memo_cache_sentinel")?(h=o.jsx("h3",{children:"Advanced"}),t[10]=h):h=t[10];let g,_,j;t[11]===Symbol.for("react.memo_cache_sentinel")?(j=o.jsx(zd,{}),g=o.jsx(Qd,{}),_=o.jsx(tu,{}),t[11]=g,t[12]=_,t[13]=j):(g=t[11],_=t[12],j=t[13]);let y;t[14]!==e?(y=o.jsxs("div",{className:"modes-category gray-left-border",children:[h,o.jsxs("div",{className:"modes-container",children:[j,g,_,e.startsWith("win32")?o.jsx(ri,{title:"Transparent Proxy",description:"This mode is only supported on Linux and MacOS."}):o.jsx(Ud,{})]})]}),t[14]=e,t[15]=y):y=t[15];let w;return t[16]!==y||t[17]!==p?(w=o.jsxs("div",{className:"modes",children:[i,r,p,y]}),t[16]=y,t[17]=p,t[18]=w):w=t[18],w}function ou(t){return t.backendState}function lu(){const t=k.c(4),e=D(du),s=D(au),i=D(cu);let r;return t[0]!==i||t[1]!==s||t[2]!==e?(r=o.jsx("div",{className:"main-view",children:i===xe.Capture?o.jsx(ru,{}):o.jsxs(o.Fragment,{children:[s?o.jsx(md,{}):o.jsx(gd,{}),e&&o.jsxs(o.Fragment,{children:[o.jsx(ld,{},"splitter"),o.jsx(nd,{},"flowDetails")]})]})}),t[0]=i,t[1]=s,t[2]=e,t[3]=r):r=t[3],r}function cu(t){return t.ui.tabs.current}function au(t){return t.flows.list.length>0}function du(t){return t.flows.selected.length===1}function gt(t){const e=k.c(2),{children:s}=t;let i;return e[0]!==s?(i=window.MITMWEB_STATIC?null:o.jsx(o.Fragment,{children:s}),e[0]=s,e[1]=i):i=e[1],i}const uu=I.memo(function(){const e=k.c(20),s=G(),i=D(fu);let r;e[0]===Symbol.for("react.memo_cache_sentinel")?(r={placement:"bottom-start"},e[0]=r):r=e[0];let n;e[1]!==s?(n=o.jsx("li",{children:o.jsx(Fr,{icon:"fa-folder-open",text:" Open...",onClick:pu,onOpenFile:w=>{s(tc(w)),document.body.click()}})}),e[1]=s,e[2]=n):n=e[2];let l;e[3]===Symbol.for("react.memo_cache_sentinel")?(l=o.jsxs(ke,{onClick:hu,children:[o.jsx("i",{className:"fa fa-fw fa-floppy-o"})," Save"]}),e[3]=l):l=e[3];let a;e[4]!==i?(a=()=>location.replace("/flows/dump?filter="+i),e[4]=i,e[5]=a):a=e[5];let d;e[6]===Symbol.for("react.memo_cache_sentinel")?(d=o.jsx("i",{className:"fa fa-fw fa-floppy-o"}),e[6]=d):d=e[6];let f;e[7]!==a?(f=o.jsxs(ke,{onClick:a,children:[d," Save filtered"]}),e[7]=a,e[8]=f):f=e[8];let p;e[9]!==s?(p=()=>confirm("Delete all flows?")&&s(Oi()),e[9]=s,e[10]=p):p=e[10];let h;e[11]===Symbol.for("react.memo_cache_sentinel")?(h=o.jsx("i",{className:"fa fa-fw fa-trash"}),e[11]=h):h=e[11];let g;e[12]!==p?(g=o.jsxs(ke,{onClick:p,children:[h," Clear All"]}),e[12]=p,e[13]=g):g=e[13];let _;e[14]===Symbol.for("react.memo_cache_sentinel")?(_=o.jsx(ka,{}),e[14]=_):_=e[14];let j;e[15]===Symbol.for("react.memo_cache_sentinel")?(j=o.jsxs(gt,{children:[_,o.jsx("li",{children:o.jsxs("a",{href:"http://mitm.it/",target:"_blank",rel:"noreferrer",children:[o.jsx("i",{className:"fa fa-fw fa-external-link"})," Install Certificates..."]})})]}),e[15]=j):j=e[15];let y;return e[16]!==n||e[17]!==f||e[18]!==g?(y=o.jsxs(Et,{className:"pull-left special",text:"File",options:r,children:[n,l,f,g,j]}),e[16]=n,e[17]=f,e[18]=g,e[19]=y):y=e[19],y});function fu(t){return t.ui.filter[ve.Search]}function pu(t){return t.stopPropagation()}function hu(){return location.replace("/flows/dump")}const mu=I.memo(function(){const e=k.c(5),s=D(gu),i=D(vu);switch(s){case wt.INIT:{let r;return e[0]===Symbol.for("react.memo_cache_sentinel")?(r=o.jsx("span",{className:"connection-indicator init",children:"connecting…"}),e[0]=r):r=e[0],r}case wt.FETCHING:{let r;return e[1]===Symbol.for("react.memo_cache_sentinel")?(r=o.jsx("span",{className:"connection-indicator fetching",children:"fetching data…"}),e[1]=r):r=e[1],r}case wt.ESTABLISHED:{let r;return e[2]===Symbol.for("react.memo_cache_sentinel")?(r=o.jsx("span",{className:"connection-indicator established",children:"connected"}),e[2]=r):r=e[2],r}case wt.ERROR:{let r;return e[3]!==i?(r=o.jsx("span",{className:"connection-indicator error",title:i,children:"connection lost"}),e[3]=i,e[4]=r):r=e[4],r}default:Ct(s)}});function gu(t){return t.connection.state}function vu(t){return t.connection.message}Xr.title="Capture";function Xr(){const t=k.c(1);let e;return t[0]===Symbol.for("react.memo_cache_sentinel")?(e=o.jsx(o.Fragment,{}),t[0]=e):e=t[0],e}const oi=function(){function t(i,r){function n(){this.constructor=i}n.prototype=r.prototype,i.prototype=new n}function e(i,r,n,l){this.message=i,this.expected=r,this.found=n,this.location=l,this.name="SyntaxError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,e)}t(e,Error);function s(i){var r=arguments.length>1?arguments[1]:{},n={},l={start:_n},a=_n,d={type:"other",description:"filter expression"},f=function(c){return c},p={type:"other",description:"whitespace"},h=/^[ \t\n\r]/,g={type:"class",value:"[ \\t\\n\\r]",description:"[ \\t\\n\\r]"},_={type:"other",description:"control character"},j=/^[|&!()~"]/,y={type:"class",value:'[|&!()~"]',description:'[|&!()~"]'},w={type:"other",description:"optional whitespace"},$="|",N={type:"literal",value:"|",description:'"|"'},E=function(c,u){return il(c,u)},T="&",P={type:"literal",value:"&",description:'"&"'},L=function(c,u){return rl(c,u)},O="!",M={type:"literal",value:"!",description:'"!"'},U=function(c){return ol(c)},V="(",W={type:"literal",value:"(",description:'"("'},J=")",z={type:"literal",value:")",description:'")"'},te=function(c){return ll(c)},Y="~all",Q={type:"literal",value:"~all",description:'"~all"'},X=function(){return Sn},Z="~a",ae={type:"literal",value:"~a",description:'"~a"'},le=function(){return Cn},de="~b",ye={type:"literal",value:"~b",description:'"~b"'},Pe=function(c){return cl(c)},Se="~bq",Ee={type:"literal",value:"~bq",description:'"~bq"'},C=function(c){return al(c)},he="~bs",B={type:"literal",value:"~bs",description:'"~bs"'},oe=function(c){return dl(c)},q="~c",$e={type:"literal",value:"~c",description:'"~c"'},We=function(c){return ul(c)},Oe="~comment",ee={type:"literal",value:"~comment",description:'"~comment"'},Me=function(c){return fl(c)},Re="~d",re={type:"literal",value:"~d",description:'"~d"'},ue=function(c){return pl(c)},ge="~dns",Ae={type:"literal",value:"~dns",description:'"~dns"'},nt=function(){return Nn},Je="~dst",Zt={type:"literal",value:"~dst",description:'"~dst"'},b=function(c){return hl(c)},S="~e",A={type:"literal",value:"~e",description:'"~e"'},H=function(){return kn},Tt="~h",es={type:"literal",value:"~h",description:'"~h"'},Ce=function(c){return ml(c)},De="~hq",ut={type:"literal",value:"~hq",description:'"~hq"'},Ke=function(c){return gl(c)},vt="~hs",Rt={type:"literal",value:"~hs",description:'"~hs"'},it=function(c){return vl(c)},At="~http",ft={type:"literal",value:"~http",description:'"~http"'},Fe=function(){return En},Us="~marked",no={type:"literal",value:"~marked",description:'"~marked"'},io=function(){return Tn},Bs="~marker",ro={type:"literal",value:"~marker",description:'"~marker"'},oo=function(c){return xl(c)},Ws="~m",lo={type:"literal",value:"~m",description:'"~m"'},co=function(c){return _l(c)},Ks="~q",ao={type:"literal",value:"~q",description:'"~q"'},uo=function(){return Rn},zs="~replayq",fo={type:"literal",value:"~replayq",description:'"~replayq"'},po=function(){return An},Gs="~replays",ho={type:"literal",value:"~replays",description:'"~replays"'},mo=function(){return Dn},Ys="~replay",go={type:"literal",value:"~replay",description:'"~replay"'},vo=function(){return Fn},Js="~src",xo={type:"literal",value:"~src",description:'"~src"'},_o=function(c){return jl(c)},Qs="~s",jo={type:"literal",value:"~s",description:'"~s"'},yo=function(){return In},Xs="~tcp",wo={type:"literal",value:"~tcp",description:'"~tcp"'},bo=function(){return Ln},Zs="~udp",So={type:"literal",value:"~udp",description:'"~udp"'},$o=function(){return Pn},en="~tq",Co={type:"literal",value:"~tq",description:'"~tq"'},No=function(c){return yl(c)},tn="~ts",ko={type:"literal",value:"~ts",description:'"~ts"'},Eo=function(c){return wl(c)},sn="~t",To={type:"literal",value:"~t",description:'"~t"'},Ro=function(c){return bl(c)},nn="~u",Ao={type:"literal",value:"~u",description:'"~u"'},rn=function(c){return Sl(c)},on="~websocket",Do={type:"literal",value:"~websocket",description:'"~websocket"'},Fo=function(){return On},Io={type:"other",description:"integer"},ln=/^['"]/,cn={type:"class",value:`['"]`,description:`['"]`},an=/^[0-9]/,dn={type:"class",value:"[0-9]",description:"[0-9]"},Lo=function(c){return parseInt(c.join(""),10)},Po={type:"other",description:"string"},un='"',fn={type:"literal",value:'"',description:'"\\""'},ts=function(c){return c.join("")},pn="'",hn={type:"literal",value:"'",description:`"'"`},Oo=/^["\\]/,Mo={type:"class",value:'["\\\\]',description:'["\\\\]'},ss={type:"any",description:"any character"},xt=function(c){return c},mn="\\",gn={type:"literal",value:"\\",description:'"\\\\"'},qo=/^['\\]/,Ho={type:"class",value:"['\\\\]",description:"['\\\\]"},Vo=/^['"\\]/,Uo={type:"class",value:`['"\\\\]`,description:`['"\\\\]`},Bo="n",Wo={type:"literal",value:"n",description:'"n"'},Ko=function(){return` `},zo="r",Go={type:"literal",value:"r",description:'"r"'},Yo=function(){return"\r"},Jo="t",Qo={type:"literal",value:"t",description:'"t"'},Xo=function(){return" "},m=0,Dt=[{line:1,column:1,seenCR:!1}],qe=0,ns=[],R=0,Ft;if("startRule"in r){if(!(r.startRule in l))throw new Error(`Can't start parsing from rule "`+r.startRule+'".');a=l[r.startRule]}function vn(c){var u=Dt[c],v,x;if(u)return u;for(v=c-1;!Dt[v];)v--;for(u=Dt[v],u={line:u.line,column:u.column,seenCR:u.seenCR};v Date: Tue, 12 May 2026 13:02:14 +0000 Subject: [PATCH 20/30] reopen main for development --- mitmproxy/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mitmproxy/version.py b/mitmproxy/version.py index 7445df31bd..e4842b025c 100644 --- a/mitmproxy/version.py +++ b/mitmproxy/version.py @@ -2,7 +2,7 @@ import subprocess import sys -VERSION = "12.2.3" +VERSION = "13.0.0.dev" MITMPROXY = "mitmproxy " + VERSION # Serialization format version. This is displayed nowhere, it just needs to be incremented by one From b9958b2f2de1bc3fe9c5c3ef7878cadae13b0821 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 May 2026 16:14:25 +0200 Subject: [PATCH 21/30] Bump requests from 2.32.5 to 2.33.1 (#8230) * Bump requests from 2.32.5 to 2.33.1 Bumps [requests](https://github.com/psf/requests) from 2.32.5 to 2.33.1. - [Release notes](https://github.com/psf/requests/releases) - [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md) - [Commits](https://github.com/psf/requests/compare/v2.32.5...v2.33.1) --- updated-dependencies: - dependency-name: requests dependency-version: 2.33.1 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * [autofix.ci] apply automated fixes --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- uv.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 1c1fa7aed3..96bced429e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -73,7 +73,7 @@ dev = [ "pytest-timeout==2.4.0", "pytest-xdist==3.8.0", "pytest==8.4.2", - "requests==2.32.5", + "requests==2.33.1", "wheel==0.46.3", "build==1.4.2", "mypy==1.19.1", diff --git a/uv.lock b/uv.lock index 0d4ac4bce5..a3ffc97e9a 100644 --- a/uv.lock +++ b/uv.lock @@ -1077,7 +1077,7 @@ dev = [ { name = "pytest-cov", specifier = "==7.0.0" }, { name = "pytest-timeout", specifier = "==2.4.0" }, { name = "pytest-xdist", specifier = "==3.8.0" }, - { name = "requests", specifier = "==2.32.5" }, + { name = "requests", specifier = "==2.33.1" }, { name = "ruff", specifier = "==0.15.8" }, { name = "tox", specifier = "==4.50.3" }, { name = "tox-uv", specifier = "==1.33.4" }, @@ -1654,7 +1654,7 @@ wheels = [ [[package]] name = "requests" -version = "2.32.5" +version = "2.33.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, @@ -1662,9 +1662,9 @@ dependencies = [ { name = "idna" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload-time = "2025-08-18T20:46:02.573Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5f/a4/98b9c7c6428a668bf7e42ebb7c79d576a1c3c1e3ae2d47e674b468388871/requests-2.33.1.tar.gz", hash = "sha256:18817f8c57c6263968bc123d237e3b8b08ac046f5456bd1e307ee8f4250d3517", size = 134120, upload-time = "2026-03-30T16:09:15.531Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" }, + { url = "https://files.pythonhosted.org/packages/d7/8e/7540e8a2036f79a125c1d2ebadf69ed7901608859186c856fa0388ef4197/requests-2.33.1-py3-none-any.whl", hash = "sha256:4e6d1ef462f3626a1f0a0a9c42dd93c63bad33f9f1c1937509b8c5c8718ab56a", size = 64947, upload-time = "2026-03-30T16:09:13.83Z" }, ] [[package]] From 2f6f251ee6fe33d4274bcf6c2f01cef01095c84e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 May 2026 16:14:29 +0200 Subject: [PATCH 22/30] Bump awscli from 1.44.63 to 1.44.69 in the deploy group (#8228) * Bump awscli from 1.44.63 to 1.44.69 in the deploy group Bumps the deploy group with 1 update: [awscli](https://github.com/aws/aws-cli). Updates `awscli` from 1.44.63 to 1.44.69 - [Release notes](https://github.com/aws/aws-cli/releases) - [Commits](https://github.com/aws/aws-cli/compare/1.44.63...1.44.69) --- updated-dependencies: - dependency-name: awscli dependency-version: 1.44.69 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: deploy ... Signed-off-by: dependabot[bot] * [autofix.ci] apply automated fixes --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- uv.lock | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 96bced429e..f864d31aac 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -89,7 +89,7 @@ ruff = [ "ruff==0.15.8", ] deploy = [ - "awscli==1.44.63", + "awscli==1.44.69", "twine==6.2.0", ] diff --git a/uv.lock b/uv.lock index a3ffc97e9a..f3e1ffbbdc 100644 --- a/uv.lock +++ b/uv.lock @@ -100,7 +100,7 @@ wheels = [ [[package]] name = "awscli" -version = "1.44.63" +version = "1.44.69" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore" }, @@ -110,9 +110,9 @@ dependencies = [ { name = "rsa" }, { name = "s3transfer" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/83/39/0dddc7b57818f3bc5f7401481881a6eba867634af768458eaab46fbbf93c/awscli-1.44.63.tar.gz", hash = "sha256:81e0fb0028f48d0387782bc272a8e6df69a644520e0ce2a1bcf025ec157fe454", size = 1886381, upload-time = "2026-03-20T19:39:48.003Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ea/70/66302525cfe09acdaac2f90f73e9c37a34bed45f13c486718c5b9e25048b/awscli-1.44.69.tar.gz", hash = "sha256:b51c2bd7812f8f4e10c685065ee43a903e7cd7423379e8e0907e91927f896112", size = 1886708, upload-time = "2026-03-30T19:44:35.269Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/11/4f/5d16ee94872b2077ad202f91d6fdc1d38be1ac27906b2a61395f00759bdf/awscli-1.44.63-py3-none-any.whl", hash = "sha256:290298451e46aaf94018cbbf653ca1d7ab890e137888330191152d56f1c827ef", size = 4623761, upload-time = "2026-03-20T19:39:44.236Z" }, + { url = "https://files.pythonhosted.org/packages/f8/ac/587dc11db21315df7c89d5aed23e99d92f9178b9872965735a99d37cb2ec/awscli-1.44.69-py3-none-any.whl", hash = "sha256:a12783fc0cd83d1beb3aa733628f4a524adcf4265d7490da4f820ed4f4472bf3", size = 4624495, upload-time = "2026-03-30T19:44:32.595Z" }, ] [[package]] @@ -192,16 +192,16 @@ wheels = [ [[package]] name = "botocore" -version = "1.42.73" +version = "1.42.79" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jmespath" }, { name = "python-dateutil" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/28/23/0c88ca116ef63b1ae77c901cd5d2095d22a8dbde9e80df74545db4a061b4/botocore-1.42.73.tar.gz", hash = "sha256:575858641e4949aaf2af1ced145b8524529edf006d075877af6b82ff96ad854c", size = 15008008, upload-time = "2026-03-20T19:39:40.082Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/4b/ec7b3a9acc47a27a3e279d6532f8fcaf16e44c840895718129ca339a0719/botocore-1.42.79.tar.gz", hash = "sha256:1ea98f505a1a65c4b6eed4a6b7452f27613c9aa24532aa71650ec3f3e05fa32c", size = 15064434, upload-time = "2026-03-30T19:44:28.49Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8e/65/971f3d55015f4d133a6ff3ad74cd39f4b8dd8f53f7775a3c2ad378ea5145/botocore-1.42.73-py3-none-any.whl", hash = "sha256:7b62e2a12f7a1b08eb7360eecd23bb16fe3b7ab7f5617cf91b25476c6f86a0fe", size = 14681861, upload-time = "2026-03-20T19:39:35.341Z" }, + { url = "https://files.pythonhosted.org/packages/68/d9/289f94219c2ee4b2a38642bb4a6b8c71cf136c0983e25c0c8fe6b29b1c0a/botocore-1.42.79-py3-none-any.whl", hash = "sha256:edea07bb255e812908e783a9da6ee63ba97baa0cc6612adabbad54466281e330", size = 14741875, upload-time = "2026-03-30T19:44:23.959Z" }, ] [[package]] @@ -1060,7 +1060,7 @@ requires-dist = [ [package.metadata.requires-dev] deploy = [ - { name = "awscli", specifier = "==1.44.63" }, + { name = "awscli", specifier = "==1.44.69" }, { name = "twine", specifier = "==6.2.0" }, ] dev = [ From 48e58bebcb3439683dbc2b78ce8feb0be87f8a68 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 May 2026 16:14:36 +0200 Subject: [PATCH 23/30] Bump types-requests from 2.32.4.20260107 to 2.33.0.20260327 in the mypy group (#8225) * Bump types-requests in the mypy group Bumps the mypy group with 1 update: [types-requests](https://github.com/python/typeshed). Updates `types-requests` from 2.32.4.20260107 to 2.33.0.20260327 - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-requests dependency-version: 2.33.0.20260327 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: mypy ... Signed-off-by: dependabot[bot] * [autofix.ci] apply automated fixes --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- uv.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index f864d31aac..206fd5eac2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -77,7 +77,7 @@ dev = [ "wheel==0.46.3", "build==1.4.2", "mypy==1.19.1", - "types-requests==2.32.4.20260107", + "types-requests==2.33.0.20260327", {include-group = "tox"}, {include-group = "ruff"}, ] diff --git a/uv.lock b/uv.lock index f3e1ffbbdc..f614417c56 100644 --- a/uv.lock +++ b/uv.lock @@ -1081,7 +1081,7 @@ dev = [ { name = "ruff", specifier = "==0.15.8" }, { name = "tox", specifier = "==4.50.3" }, { name = "tox-uv", specifier = "==1.33.4" }, - { name = "types-requests", specifier = "==2.32.4.20260107" }, + { name = "types-requests", specifier = "==2.33.0.20260327" }, { name = "wheel", specifier = "==0.46.3" }, ] ruff = [{ name = "ruff", specifier = "==0.15.8" }] @@ -1909,14 +1909,14 @@ wheels = [ [[package]] name = "types-requests" -version = "2.32.4.20260107" +version = "2.33.0.20260327" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/0f/f3/a0663907082280664d745929205a89d41dffb29e89a50f753af7d57d0a96/types_requests-2.32.4.20260107.tar.gz", hash = "sha256:018a11ac158f801bfa84857ddec1650750e393df8a004a8a9ae2a9bec6fcb24f", size = 23165, upload-time = "2026-01-07T03:20:54.091Z" } +sdist = { url = "https://files.pythonhosted.org/packages/02/5f/2e3dbae6e21be6ae026563bad96cbf76602d73aa85ea09f13419ddbdabb4/types_requests-2.33.0.20260327.tar.gz", hash = "sha256:f4f74f0b44f059e3db420ff17bd1966e3587cdd34062fe38a23cda97868f8dd8", size = 23804, upload-time = "2026-03-27T04:23:38.737Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1c/12/709ea261f2bf91ef0a26a9eed20f2623227a8ed85610c1e54c5805692ecb/types_requests-2.32.4.20260107-py3-none-any.whl", hash = "sha256:b703fe72f8ce5b31ef031264fe9395cac8f46a04661a79f7ed31a80fb308730d", size = 20676, upload-time = "2026-01-07T03:20:52.929Z" }, + { url = "https://files.pythonhosted.org/packages/8c/55/951e733616c92cb96b57554746d2f65f4464d080cc2cc093605f897aba89/types_requests-2.33.0.20260327-py3-none-any.whl", hash = "sha256:fde0712be6d7c9a4d490042d6323115baf872d9a71a22900809d0432de15776e", size = 20737, upload-time = "2026-03-27T04:23:37.813Z" }, ] [[package]] From e33503dbd8f2b1cf623601f883799ab8c756d089 Mon Sep 17 00:00:00 2001 From: Matteo Luppi <100372313+lups2000@users.noreply.github.com> Date: Tue, 12 May 2026 16:15:20 +0200 Subject: [PATCH 24/30] Web: Remove Bootstrap dependency and keep mitmweb styling parity (#8147) * migrate bootstrap decoupling with dual classes and local less tokens * migrate form and utility bootstrap classes to m-/u- styles * remove remaining Bootstrap class aliases and migrate to internal m-* / u-* classes * fix tab link colors to match previous blue styling * update snapshots * adjust table styling and alignment * adjust divider style * adjust flowdetails panel style * adjust options modal style * fix icons position and color in capture tab page * adjust style search,highlight, intercept popovers * update snapshots * extract global styles into global.less * keep behavior aligned with pre-migration Bootstrap (same class names) * update snapshots * [autofix.ci] apply automated fixes --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- web/package-lock.json | 9 - web/package.json | 1 - web/src/css/app.less | 12 +- web/src/css/contentview.less | 15 + web/src/css/dropdown.less | 44 ++ web/src/css/eventlog.less | 2 +- web/src/css/flowdetail.less | 8 +- web/src/css/flowtable.less | 6 + web/src/css/global.less | 489 ++++++++++++++++++ web/src/css/header.less | 55 +- web/src/css/modal.less | 124 ++++- web/src/css/mode.less | 48 +- web/src/css/tabs.less | 7 + web/src/css/vendor-bootstrap-variables.less | 21 - web/src/css/vendor-bootstrap.less | 45 -- web/src/css/vendor.less | 2 - .../__snapshots__/FlowColumnsSpec.tsx.snap | 14 +- .../__snapshots__/FlowRowSpec.tsx.snap | 10 +- .../__snapshots__/FilterInputSpec.tsx.snap | 2 +- .../__snapshots__/MainMenuSpec.tsx.snap | 6 +- .../__snapshots__/OptionMenuSpec.tsx.snap | 3 + .../Modal/__snapshots__/ModalSpec.tsx.snap | 48 +- .../__snapshots__/OptionModalSpec.tsx.snap | 8 +- .../__snapshots__/CaptureSetupSpec.tsx.snap | 1 + .../__snapshots__/CommandBarSpec.tsx.snap | 4 +- .../__snapshots__/EventLogSpec.tsx.snap | 12 +- .../__snapshots__/FlowTableSpec.tsx.snap | 24 +- .../__snapshots__/FlowViewSpec.tsx.snap | 2 +- .../__snapshots__/HeaderSpec.tsx.snap | 12 +- .../__snapshots__/DocsLinkSpec.tsx.snap | 2 + .../__snapshots__/DropdownSpec.tsx.snap | 14 +- .../__snapshots__/ToggleButtonSpec.tsx.snap | 2 +- .../__snapshots__/ViewSelectorSpec.tsx.snap | 4 +- web/src/js/components/CommandBar.tsx | 2 +- web/src/js/components/EventLog.tsx | 2 +- .../js/components/FlowTable/FlowColumns.tsx | 12 +- web/src/js/components/FlowView/Messages.tsx | 2 +- web/src/js/components/FlowView/WebSocket.tsx | 2 +- web/src/js/components/Footer.tsx | 2 +- web/src/js/components/Header/FilterInput.tsx | 2 +- web/src/js/components/Modal/ModalLayout.tsx | 4 +- web/src/js/components/Modal/OptionInput.tsx | 2 +- web/src/js/components/Modal/OptionModal.tsx | 16 +- web/src/js/components/Modes/CaptureSetup.tsx | 2 +- web/src/js/components/common/DocsLink.tsx | 2 +- web/src/js/components/common/Dropdown.tsx | 13 +- web/src/js/components/common/ToggleButton.tsx | 8 +- 47 files changed, 911 insertions(+), 216 deletions(-) create mode 100644 web/src/css/global.less delete mode 100644 web/src/css/vendor-bootstrap-variables.less delete mode 100644 web/src/css/vendor-bootstrap.less diff --git a/web/package-lock.json b/web/package-lock.json index c0c97ad42c..d78d79bcd0 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -15,7 +15,6 @@ "@reduxjs/toolkit": "^2.8.1", "@types/react": "^19.2.6", "@uiw/react-codemirror": "^4.23.12", - "bootstrap": "^3.4.1", "classnames": "^2.3.1", "codemirror": "^6.0.1", "lodash": "^4.17.21", @@ -3590,14 +3589,6 @@ "baseline-browser-mapping": "dist/cli.js" } }, - "node_modules/bootstrap": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-3.4.1.tgz", - "integrity": "sha512-yN5oZVmRCwe5aKwzRj6736nSmKDX7pLYwsXiCj/EYmo16hODaBiT4En5btW/jhBF/seV+XMx3aYwukYC3A49DA==", - "engines": { - "node": ">=6" - } - }, "node_modules/brace-expansion": { "version": "1.1.12", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", diff --git a/web/package.json b/web/package.json index 07a623aa50..56a7a18c5a 100644 --- a/web/package.json +++ b/web/package.json @@ -18,7 +18,6 @@ "@reduxjs/toolkit": "^2.8.1", "@types/react": "^19.2.6", "@uiw/react-codemirror": "^4.23.12", - "bootstrap": "^3.4.1", "classnames": "^2.3.1", "codemirror": "^6.0.1", "lodash": "^4.17.21", diff --git a/web/src/css/app.less b/web/src/css/app.less index 49084ae714..165572e828 100644 --- a/web/src/css/app.less +++ b/web/src/css/app.less @@ -1,14 +1,4 @@ -// www.paulirish.com/2012/box-sizing-border-box-ftw/ -html { - box-sizing: border-box; -} - -*, -*:before, -*:after { - box-sizing: inherit; -} - +@import (less) "global.less"; @import (less) "sprites.less"; @import (less) "layout.less"; @import (less) "tabs.less"; diff --git a/web/src/css/contentview.less b/web/src/css/contentview.less index da789730d4..043ab62938 100644 --- a/web/src/css/contentview.less +++ b/web/src/css/contentview.less @@ -1,4 +1,19 @@ .contentview { + pre { + display: block; + padding: 9.5px; + margin: 0 0 10px; + font-size: 13px; + line-height: 1.42857143; + color: #333; + word-break: break-all; + word-wrap: break-word; + background-color: #f5f5f5; + border: 1px solid #ccc; + border-radius: 4px; + overflow: auto; + } + .header { font-weight: bold; } diff --git a/web/src/css/dropdown.less b/web/src/css/dropdown.less index bc1cebd5d2..5c56754a7c 100644 --- a/web/src/css/dropdown.less +++ b/web/src/css/dropdown.less @@ -1,11 +1,55 @@ .dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: block; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + list-style: none; + font-size: 14px; + text-align: left; + background-color: #fff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 15%); + border-radius: 4px; + box-shadow: 0 6px 12px rgba(0, 0, 0, 17.5%); + background-clip: padding-box; + // setting a margin is not compatible with popper. margin: 0 !important; + > li { + display: block; + } + > li > a { + display: block; padding: 3px 10px; + clear: both; + font-weight: 400; + line-height: 1.42857143; + color: #333; + white-space: nowrap; + text-decoration: none; + } + + > li > a:hover, + > li > a:focus { + text-decoration: none; + color: #262626; + background-color: #f5f5f5; } max-height: 250px; overflow-y: scroll; } + +.menu-divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; +} diff --git a/web/src/css/eventlog.less b/web/src/css/eventlog.less index bc38101c86..8321cc5b31 100644 --- a/web/src/css/eventlog.less +++ b/web/src/css/eventlog.less @@ -34,7 +34,7 @@ } } - .btn-toggle { + .toggle { margin-top: -2px; margin-left: 3px; padding: 2px 2px; diff --git a/web/src/css/flowdetail.less b/web/src/css/flowdetail.less index fa256b749d..b525d4b577 100644 --- a/web/src/css/flowdetail.less +++ b/web/src/css/flowdetail.less @@ -67,6 +67,8 @@ } hr { + border: 0; + border-top: 1px solid #eee; margin: 0; } } @@ -122,10 +124,8 @@ table-layout: fixed; word-break: break-all; - tr { - &:not(:first-child) { - border-top: 1px solid #f7f7f7; - } + tr:not(:first-child) td { + border-top: 1px solid #f7f7f7; } td { diff --git a/web/src/css/flowtable.less b/web/src/css/flowtable.less index 652c0d54af..239f840763 100644 --- a/web/src/css/flowtable.less +++ b/web/src/css/flowtable.less @@ -15,6 +15,8 @@ table { width: 100%; table-layout: fixed; + border-collapse: collapse; + border-spacing: 0; } thead tr { @@ -25,7 +27,10 @@ th { font-weight: normal; + text-align: left; + vertical-align: bottom; position: relative !important; + padding: 0; padding-left: 1px; .user-select(none); @@ -86,6 +91,7 @@ } td { + padding: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; diff --git a/web/src/css/global.less b/web/src/css/global.less new file mode 100644 index 0000000000..add4778ff8 --- /dev/null +++ b/web/src/css/global.less @@ -0,0 +1,489 @@ +// www.paulirish.com/2012/box-sizing-border-box-ftw/ +html { + box-sizing: border-box; + font-size: 10px; +} + +*, +*:before, +*:after { + box-sizing: inherit; +} + +@font-family-sans-serif: + system-ui, + -apple-system, + "Segoe UI", + Roboto, + "Helvetica Neue", + Arial, + "Noto Sans", + "Liberation Sans", + sans-serif, + "Apple Color Emoji", + "Segoe UI Emoji", + "Segoe UI Symbol", + "Noto Color Emoji"; +@font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, + "Liberation Mono", "Courier New", monospace; + +body { + margin: 0; + font-family: @font-family-sans-serif; + font-size: 14px; + line-height: 1.42857143; + color: #333; + background-color: #fff; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: inherit; + font-weight: 500; + line-height: 1.1; + color: inherit; +} + +h1, +h2, +h3 { + margin-top: 20px; + margin-bottom: 10px; +} + +h4, +h5, +h6 { + margin-top: 10px; + margin-bottom: 10px; +} + +h1 { + font-size: 36px; +} + +h2 { + font-size: 30px; +} + +h3 { + font-size: 24px; +} + +h4 { + font-size: 18px; +} + +h5 { + font-size: 14px; +} + +h6 { + font-size: 12px; +} + +p { + margin: 0 0 10px; +} + +ul, +ol { + margin-top: 0; + margin-bottom: 10px; +} + +ul ul, +ul ol, +ol ul, +ol ol { + margin-bottom: 0; +} + +input, +button, +select, +textarea { + font: inherit; +} + +.float-right { + float: right; +} + +.text-primary { + color: #337ab7; +} + +.docs-link, +.docs-link:visited { + color: #337ab7; + text-decoration: none; +} + +.docs-link:hover, +.docs-link:focus { + color: #23527c; +} + +.text-success { + color: #3c763d; +} + +.text-info { + color: #31708f; +} + +.text-warning { + color: #8a6d3b; +} + +.text-danger { + color: #a94442; +} + +.text-muted { + color: #777; +} + +.hidden { + display: none !important; +} + +.caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 2px; + vertical-align: middle; + border-top: 4px dashed; + border-right: 4px solid transparent; + border-left: 4px solid transparent; +} + +.btn { + display: inline-block; + text-decoration: none; + margin-bottom: 0; + font-weight: 400; + text-align: center; + vertical-align: middle; + touch-action: manipulation; + cursor: pointer; + background-image: none; + border: 1px solid transparent; + white-space: nowrap; + padding: 6px 12px; + font-size: 14px; + line-height: 1.42857143; + border-radius: 4px; + user-select: none; +} + +.btn:focus, +.btn:hover { + color: #333; + text-decoration: none; +} + +.btn:active { + background-image: none; + outline: 0; + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 12.5%); +} + +.btn:disabled, +.btn.disabled { + cursor: not-allowed; + opacity: 0.65; + box-shadow: none; +} + +.btn-default { + color: #333; + background-color: #fff; + border-color: #ccc; +} + +.btn-default:hover, +.btn-default:focus { + color: #333; + background-color: #e6e6e6; + border-color: #adadad; +} + +.btn-primary { + color: #fff; + background-color: #337ab7; + border-color: #2e6da4; +} + +.btn-primary:hover, +.btn-primary:focus { + color: #fff; + background-color: #286090; + border-color: #204d74; +} + +.btn-info { + color: #fff; + background-color: #5bc0de; + border-color: #46b8da; +} + +.btn-info:hover, +.btn-info:focus { + color: #fff; + background-color: #31b0d5; + border-color: #269abc; +} + +.btn-sm { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} + +.btn-xs { + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} + +.label { + display: inline; + padding: 0.2em 0.6em 0.3em; + font-size: 75%; + font-weight: 700; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: 0.25em; +} + +.label-default { + background-color: #777; +} + +.label-primary { + background-color: #337ab7; +} + +.label-success { + background-color: #5cb85c; +} + +.label-danger { + background-color: #d9534f; +} + +.alert { + padding: 15px; + margin-bottom: 20px; + border: 1px solid transparent; + border-radius: 4px; +} + +.alert-warning { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #faebcc; +} + +.input-group { + position: relative; + display: table; + border-collapse: separate; +} + +.input-group .input, +.input-group-addon { + display: table-cell; +} + +.input-group .input { + position: relative; + z-index: 2; + float: left; + width: 100%; + margin-bottom: 0; +} + +.input-group-addon { + width: 1%; + white-space: nowrap; + vertical-align: middle; + padding: 6px 12px; + font-size: 14px; + font-weight: 400; + line-height: 1; + color: #555; + text-align: center; + background-color: #eee; + border: 1px solid #ccc; + border-radius: 4px; +} + +.input-group .input-group-addon:first-child { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + border-right: 0; +} + +.input-group .input:last-child { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1060; + display: none; + max-width: 276px; + padding: 1px; + text-align: left; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 20%); + border-radius: 6px; + box-shadow: 0 5px 10px rgba(0, 0, 0, 20%); +} + +.popover-content { + padding: 9px 14px; +} + +.popover > .arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} + +.popover > .arrow:after { + content: ""; + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} + +.popover.top { + margin-top: -10px; +} + +.popover.top > .arrow { + bottom: -11px; + left: 50%; + margin-left: -11px; + border-width: 11px 11px 0; + border-top-color: rgba(0, 0, 0, 25%); +} + +.popover.top > .arrow:after { + bottom: 1px; + margin-left: -10px; + border-width: 10px 10px 0; + border-top-color: #fff; +} + +.popover.bottom { + margin-top: 10px; +} + +.popover.bottom > .arrow { + top: -11px; + left: 50%; + margin-left: -11px; + border-width: 0 11px 11px; + border-bottom-color: rgba(0, 0, 0, 25%); +} + +.popover.bottom > .arrow:after { + top: 1px; + margin-left: -10px; + border-width: 0 10px 10px; + border-bottom-color: #fff; +} + +.close { + float: right; + font-size: 21px; + font-weight: 700; + line-height: 1; + color: #000; + text-shadow: 0 1px 0 #fff; + opacity: 0.2; + background: transparent; + border: 0; + padding: 0; + cursor: pointer; +} + +.close:hover, +.close:focus { + color: #000; + text-decoration: none; + cursor: pointer; + opacity: 0.5; +} + +.img-thumbnail { + display: inline-block; + max-width: 100%; + height: auto; + padding: 4px; + line-height: 1.42857143; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 4px; + transition: all 0.2s ease-in-out; +} + +.input { + display: block; + width: 100%; + height: 34px; + padding: 6px 12px; + font-size: 14px; + line-height: 1.42857143; + color: #555; + background-color: #fff; + border: 1px solid #ccc; + border-radius: 4px; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 7.5%); + transition: + border-color ease-in-out 0.15s, + box-shadow ease-in-out 0.15s; +} + +.input:focus { + border-color: #66afe9; + outline: 0; + box-shadow: + inset 0 1px 1px rgba(0, 0, 0, 7.5%), + 0 0 8px rgba(102, 175, 233, 60%); +} + +select.input { + padding-right: 24px; +} + +textarea.input { + height: auto; +} + +.has-error .input { + border-color: #a94442; +} diff --git a/web/src/css/header.less b/web/src/css/header.less index 00d696853b..76f9e112e6 100644 --- a/web/src/css/header.less +++ b/web/src/css/header.less @@ -1,7 +1,21 @@ -@import (reference) "../../node_modules/bootstrap/less/variables.less"; -@import (reference) "../../node_modules/bootstrap/less/mixins/grid.less"; -@import (reference) "../../node_modules/bootstrap/less/mixins/labels.less"; -@import (reference) "../../node_modules/bootstrap/less/labels.less"; +@screen-xs-max: 767px; +@label-info-bg: #5bc0de; +@label-success-bg: #5cb85c; +@label-danger-bg: #d9534f; +@label-warning-bg: #f0ad4e; + +.connection-label-base() { + display: inline; + padding: 0.2em 0.6em 0.3em; + font-size: 75%; + font-weight: 700; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: 0.25em; +} @menu-height: 95px; @@ -127,6 +141,37 @@ header { max-height: 500px; overflow-y: auto; + .table { + width: 100%; + margin-bottom: 0; + border-collapse: collapse; + border-spacing: 0; + + td, + th { + padding: 5px; + line-height: 1.42857143; + vertical-align: top; + } + + a { + color: #337ab7; + } + + a:hover, + a:focus { + color: #23527c; + } + + tbody tr + tr { + border-top: 1px solid #ddd; + } + + tbody tr:first-child { + border-top: 1px solid #ddd; + } + } + tr { cursor: pointer; &:hover { @@ -137,7 +182,7 @@ header { } .connection-indicator { - .label(); + .connection-label-base(); float: right; margin: 5px; opacity: 1; diff --git a/web/src/css/modal.less b/web/src/css/modal.less index 13ef997f77..dc5ebaefb9 100644 --- a/web/src/css/modal.less +++ b/web/src/css/modal.less @@ -1,8 +1,11 @@ -.modal-visible { +.modal.is-visible { display: block; } .modal-dialog { + position: relative; + width: auto; + margin: 30px auto; overflow-y: initial !important; } @@ -10,3 +13,122 @@ max-height: calc(100vh - 200px); overflow-y: auto; } + +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000; +} + +.modal-backdrop.is-visible { + opacity: 0.5; +} + +.modal { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1050; + overflow-y: auto; + outline: 0; +} + +.modal-lg { + width: 900px; +} + +@media (max-width: 991px) { + .modal-lg { + width: auto; + margin-left: 10px; + margin-right: 10px; + } +} + +.modal-content { + position: relative; + background-color: #fff; + border: 1px solid rgba(0, 0, 0, 20%); + border-radius: 6px; + box-shadow: 0 3px 9px rgba(0, 0, 0, 50%); + background-clip: padding-box; + outline: 0; +} + +.modal-header { + padding: 15px; + border-bottom: 1px solid #e5e5e5; + min-height: 16.42857143px; +} + +.modal-title { + margin: 0; + line-height: 1.42857143; +} + +.modal-body { + position: relative; + padding: 15px; +} + +.modal-footer { + padding: 15px; + text-align: right; + border-top: 1px solid #e5e5e5; +} + +.form-horizontal .form-row { + margin-left: -15px; + margin-right: -15px; + margin-bottom: 15px; + display: flex; +} + +.form-horizontal .col-6 { + width: 50%; + min-height: 1px; + padding-left: 15px; + padding-right: 15px; +} + +.form-horizontal .checkbox { + margin-top: 0; + margin-bottom: 0; + padding-top: 7px; +} + +.form-horizontal .checkbox label { + display: inline-flex; + align-items: center; + gap: 6px; + margin: 0; + font-weight: 400; +} + +.form-horizontal .checkbox input[type="checkbox"] { + margin: 0; +} + +.help-block { + display: block; + margin-top: 5px; + margin-bottom: 10px; + color: #737373; +} + +.control-label { + display: inline-block; + max-width: 100%; + margin-bottom: 5px; + font-weight: 700; +} + +.text-small { + font-size: 85%; +} diff --git a/web/src/css/mode.less b/web/src/css/mode.less index b165ea5cbf..caee8316b7 100644 --- a/web/src/css/mode.less +++ b/web/src/css/mode.less @@ -1,16 +1,11 @@ -@import (reference) "../../node_modules/bootstrap/less/variables.less"; -@import (reference) "../../node_modules/bootstrap/less/mixins/grid.less"; -@import (reference) "../../node_modules/bootstrap/less/mixins/labels.less"; -@import (reference) "../../node_modules/bootstrap/less/labels.less"; - .modes { padding: 1em 2em 2em 2em; overflow-y: auto; height: 100%; width: 100vw; - h3 { - margin-bottom: 10px; + h2 { + margin-bottom: 0; } .modes-category { @@ -123,11 +118,13 @@ align-items: center; margin-right: 10px; height: 30px; + overflow: hidden; } input { border: none; flex: 1; + min-width: 0; outline: none; color: black; } @@ -190,9 +187,22 @@ .local-popover { button { font-size: 1rem; + display: inline-flex; + align-items: center; + justify-content: center; + padding: 0; + width: 24px; + height: 24px; } - i { - font-size: 1.5rem; + + > button i { + font-size: 1.2rem; + line-height: 1; + } + + .dropdown-item > .fa-check { + font-size: 1.2rem; + line-height: 1; } @supports (anchor-name: --test) { @@ -281,6 +291,26 @@ font-size: 2rem; } + > button i { + color: #777; + } + + &.local-popover > button { + font-size: 1rem; + display: inline-flex; + align-items: center; + justify-content: center; + padding: 0; + width: 26px; + height: 26px; + flex: 0 0 auto; + } + + &.local-popover > button i { + font-size: 1.5rem; + line-height: 1; + } + @supports (anchor-name: --test) { > div { margin: 0; diff --git a/web/src/css/tabs.less b/web/src/css/tabs.less index 5a19705e14..024b3aa02f 100644 --- a/web/src/css/tabs.less +++ b/web/src/css/tabs.less @@ -5,12 +5,19 @@ > a { display: inline-block; + color: #337ab7; border: solid transparent 1px; text-decoration: none; //text-transform: uppercase; //font-family: Lato; + &:hover, + &:focus { + color: #23527c; + } + &.active { + color: #337ab7; background-color: white; border-color: @separator-color; border-bottom-color: white; diff --git a/web/src/css/vendor-bootstrap-variables.less b/web/src/css/vendor-bootstrap-variables.less deleted file mode 100644 index 77ae785773..0000000000 --- a/web/src/css/vendor-bootstrap-variables.less +++ /dev/null @@ -1,21 +0,0 @@ -@navbar-height: 32px; -@navbar-default-link-color: #303030; -@navbar-default-color: #303030; -@navbar-default-bg: #ffffff; -@navbar-default-border: #e0e0e0; -@font-family-sans-serif: - system-ui, - -apple-system, - "Segoe UI", - Roboto, - "Helvetica Neue", - Arial, - "Noto Sans", - "Liberation Sans", - sans-serif, - "Apple Color Emoji", - "Segoe UI Emoji", - "Segoe UI Symbol", - "Noto Color Emoji"; -@font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, - "Liberation Mono", "Courier New", monospace; diff --git a/web/src/css/vendor-bootstrap.less b/web/src/css/vendor-bootstrap.less deleted file mode 100644 index 73d6bcdc27..0000000000 --- a/web/src/css/vendor-bootstrap.less +++ /dev/null @@ -1,45 +0,0 @@ -// Core variables and mixins -@import "../../node_modules/bootstrap/less/variables.less"; -@import "vendor-bootstrap-variables.less"; -@import "../../node_modules/bootstrap/less/mixins.less"; -// Reset and dependencies -@import "../../node_modules/bootstrap/less/normalize.less"; -@import "../../node_modules/bootstrap/less/print.less"; -// Core CSS -@import "../../node_modules/bootstrap/less/scaffolding.less"; -@import "../../node_modules/bootstrap/less/type.less"; -@import "../../node_modules/bootstrap/less/code.less"; -@import "../../node_modules/bootstrap/less/grid.less"; -@import "../../node_modules/bootstrap/less/tables.less"; -@import "../../node_modules/bootstrap/less/forms.less"; -@import "../../node_modules/bootstrap/less/buttons.less"; -// Components -@import "../../node_modules/bootstrap/less/component-animations.less"; -@import "../../node_modules/bootstrap/less/dropdowns.less"; -@import "../../node_modules/bootstrap/less/button-groups.less"; -@import "../../node_modules/bootstrap/less/input-groups.less"; -@import "../../node_modules/bootstrap/less/navs.less"; -@import "../../node_modules/bootstrap/less/navbar.less"; -@import "../../node_modules/bootstrap/less/breadcrumbs.less"; -@import "../../node_modules/bootstrap/less/pagination.less"; -@import "../../node_modules/bootstrap/less/pager.less"; -@import "../../node_modules/bootstrap/less/labels.less"; -@import "../../node_modules/bootstrap/less/badges.less"; -@import "../../node_modules/bootstrap/less/jumbotron.less"; -@import "../../node_modules/bootstrap/less/thumbnails.less"; -@import "../../node_modules/bootstrap/less/alerts.less"; -@import "../../node_modules/bootstrap/less/progress-bars.less"; -@import "../../node_modules/bootstrap/less/media.less"; -@import "../../node_modules/bootstrap/less/list-group.less"; -@import "../../node_modules/bootstrap/less/panels.less"; -@import "../../node_modules/bootstrap/less/responsive-embed.less"; -@import "../../node_modules/bootstrap/less/wells.less"; -@import "../../node_modules/bootstrap/less/close.less"; -// Components w/ JavaScript -@import "../../node_modules/bootstrap/less/modals.less"; -@import "../../node_modules/bootstrap/less/tooltip.less"; -@import "../../node_modules/bootstrap/less/popovers.less"; -@import "../../node_modules/bootstrap/less/carousel.less"; -// Utility classes -@import "../../node_modules/bootstrap/less/utilities.less"; -@import "../../node_modules/bootstrap/less/responsive-utilities.less"; diff --git a/web/src/css/vendor.less b/web/src/css/vendor.less index eb6208842a..5c7ee9a18a 100644 --- a/web/src/css/vendor.less +++ b/web/src/css/vendor.less @@ -1,3 +1 @@ -// Bootstrap -@import "vendor-bootstrap.less"; @import (less) "../fonts/font-awesome.css"; diff --git a/web/src/js/__tests__/components/FlowTable/__snapshots__/FlowColumnsSpec.tsx.snap b/web/src/js/__tests__/components/FlowTable/__snapshots__/FlowColumnsSpec.tsx.snap index 9330f72338..1f1963c451 100644 --- a/web/src/js/__tests__/components/FlowTable/__snapshots__/FlowColumnsSpec.tsx.snap +++ b/web/src/js/__tests__/components/FlowTable/__snapshots__/FlowColumnsSpec.tsx.snap @@ -237,10 +237,10 @@ exports[`Flowcolumns Components should render pathColumn 1`] = ` class="col-path" > http://address:22/path @@ -259,13 +259,13 @@ exports[`Flowcolumns Components should render pathColumn 2`] = ` class="col-path" > http://address:22/path @@ -350,10 +350,10 @@ exports[`should render columns: path 1`] = ` class="col-path" > http://address:22/path diff --git a/web/src/js/__tests__/components/FlowTable/__snapshots__/FlowRowSpec.tsx.snap b/web/src/js/__tests__/components/FlowTable/__snapshots__/FlowRowSpec.tsx.snap index d9177c7959..4ea552d038 100644 --- a/web/src/js/__tests__/components/FlowTable/__snapshots__/FlowRowSpec.tsx.snap +++ b/web/src/js/__tests__/components/FlowTable/__snapshots__/FlowRowSpec.tsx.snap @@ -21,13 +21,13 @@ exports[`FlowRow 1`] = ` class="col-path" > http://address:22/path @@ -84,10 +84,10 @@ exports[`FlowRow 1`] = ` class="col-path" > dns.google A = 8.8.8.8, 8.8.4.4 diff --git a/web/src/js/__tests__/components/Header/__snapshots__/FilterInputSpec.tsx.snap b/web/src/js/__tests__/components/Header/__snapshots__/FilterInputSpec.tsx.snap index 88112df697..eabd6a6baf 100644 --- a/web/src/js/__tests__/components/Header/__snapshots__/FilterInputSpec.tsx.snap +++ b/web/src/js/__tests__/components/Header/__snapshots__/FilterInputSpec.tsx.snap @@ -14,7 +14,7 @@ exports[`FilterInput Component should render correctly 1`] = ` /> Strip cache headers Use host header for display Don't verify server certificates