pulp-python 3.32.0__tar.gz → 3.32.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. {pulp_python-3.32.0 → pulp_python-3.32.1}/CHANGES.md +9 -0
  2. {pulp_python-3.32.0 → pulp_python-3.32.1}/PKG-INFO +1 -1
  3. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/__init__.py +1 -1
  4. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/cache.py +5 -4
  5. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/pytest_plugin.py +14 -12
  6. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/tests/functional/api/test_attestations.py +14 -16
  7. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/tests/functional/api/test_pypi_apis.py +14 -6
  8. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/tests/functional/api/test_simple_cache.py +41 -1
  9. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/tests/functional/api/test_upload.py +3 -3
  10. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python.egg-info/PKG-INFO +1 -1
  11. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python.egg-info/SOURCES.txt +0 -2
  12. {pulp_python-3.32.0 → pulp_python-3.32.1}/pyproject.toml +3 -2
  13. pulp_python-3.32.0/pulp_python/tests/functional/assets/shelf-reader-0.1.tar.gz.publish.attestation +0 -1
  14. pulp_python-3.32.0/pulp_python/tests/functional/assets/shelf_reader-0.1-py2-none-any.whl.publish.attestation +0 -1
  15. {pulp_python-3.32.0 → pulp_python-3.32.1}/COMMITMENT +0 -0
  16. {pulp_python-3.32.0 → pulp_python-3.32.1}/COPYRIGHT +0 -0
  17. {pulp_python-3.32.0 → pulp_python-3.32.1}/LICENSE +0 -0
  18. {pulp_python-3.32.0 → pulp_python-3.32.1}/MANIFEST.in +0 -0
  19. {pulp_python-3.32.0 → pulp_python-3.32.1}/README.md +0 -0
  20. {pulp_python-3.32.0 → pulp_python-3.32.1}/functest_requirements.txt +0 -0
  21. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/__init__.py +0 -0
  22. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/exceptions.py +0 -0
  23. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/global_access_conditions.py +0 -0
  24. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/management/__init__.py +0 -0
  25. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/management/commands/__init__.py +0 -0
  26. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/management/commands/repair-python-metadata.py +0 -0
  27. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/migrations/0001_initial.py +0 -0
  28. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/migrations/0001_squashed_0010_update_json_field.py +0 -0
  29. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/migrations/0002_pythonpackagecontent_python_version.py +0 -0
  30. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/migrations/0003_new_sync_filters.py +0 -0
  31. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/migrations/0004_DATA_swap_distribution_model.py +0 -0
  32. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/migrations/0005_pythonpackagecontent_sha256.py +0 -0
  33. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/migrations/0006_pythonrepository_autopublish.py +0 -0
  34. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/migrations/0007_pythonpackagecontent_mv-2-1.py +0 -0
  35. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/migrations/0008_pythonpackagecontent_unique_sha256.py +0 -0
  36. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/migrations/0009_pythondistribution_allow_uploads.py +0 -0
  37. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/migrations/0010_update_json_field.py +0 -0
  38. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/migrations/0011_alter_pythondistribution_distribution_ptr_and_more.py +0 -0
  39. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/migrations/0012_add_domain.py +0 -0
  40. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/migrations/0013_add_rbac_permissions.py +0 -0
  41. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/migrations/0014_pythonpackagecontent_dynamic_and_more.py +0 -0
  42. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/migrations/0015_alter_pythonpackagecontent_options.py +0 -0
  43. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/migrations/0016_pythonpackagecontent_metadata_sha256.py +0 -0
  44. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/migrations/0017_pythonpackagecontent_size.py +0 -0
  45. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/migrations/0018_packageprovenance.py +0 -0
  46. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/migrations/0019_create_missing_metadata_artifacts.py +0 -0
  47. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/migrations/0020_pythonpackagecontent_name_normalized.py +0 -0
  48. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/migrations/0021_pythonrepository_upload_duplicate_filenames.py +0 -0
  49. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/migrations/0022_pythonblocklistentry.py +0 -0
  50. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/migrations/__init__.py +0 -0
  51. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/modelresource.py +0 -0
  52. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/models.py +0 -0
  53. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/provenance.py +0 -0
  54. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/pypi/__init__.py +0 -0
  55. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/pypi/serializers.py +0 -0
  56. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/pypi/views.py +0 -0
  57. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/replica.py +0 -0
  58. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/serializers.py +0 -0
  59. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/settings.py +0 -0
  60. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/tasks/__init__.py +0 -0
  61. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/tasks/publish.py +0 -0
  62. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/tasks/repair.py +0 -0
  63. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/tasks/sync.py +0 -0
  64. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/tasks/upload.py +0 -0
  65. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/tasks/vulnerability_report.py +0 -0
  66. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/urls.py +0 -0
  67. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/utils.py +0 -0
  68. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/viewsets.py +0 -0
  69. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/webserver_snippets/__init__.py +0 -0
  70. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/webserver_snippets/apache.conf +0 -0
  71. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/app/webserver_snippets/nginx.conf +0 -0
  72. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/tests/__init__.py +0 -0
  73. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/tests/functional/__init__.py +0 -0
  74. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/tests/functional/api/__init__.py +0 -0
  75. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/tests/functional/api/test_auto_publish.py +0 -0
  76. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/tests/functional/api/test_blocklist.py +0 -0
  77. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/tests/functional/api/test_consume_content.py +0 -0
  78. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/tests/functional/api/test_crud_content_unit.py +0 -0
  79. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/tests/functional/api/test_crud_publications.py +0 -0
  80. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/tests/functional/api/test_crud_remotes.py +0 -0
  81. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/tests/functional/api/test_domains.py +0 -0
  82. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/tests/functional/api/test_download_content.py +0 -0
  83. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/tests/functional/api/test_export_import.py +0 -0
  84. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/tests/functional/api/test_full_mirror.py +0 -0
  85. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/tests/functional/api/test_pypi_simple_api.py +0 -0
  86. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/tests/functional/api/test_rbac.py +0 -0
  87. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/tests/functional/api/test_repair.py +0 -0
  88. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/tests/functional/api/test_sync.py +0 -0
  89. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/tests/functional/api/test_vulnerability_report.py +0 -0
  90. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/tests/functional/constants.py +0 -0
  91. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/tests/functional/utils.py +0 -0
  92. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/tests/unit/__init__.py +0 -0
  93. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python/tests/unit/test_models.py +0 -0
  94. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python.egg-info/dependency_links.txt +0 -0
  95. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python.egg-info/entry_points.txt +0 -0
  96. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python.egg-info/requires.txt +0 -0
  97. {pulp_python-3.32.0 → pulp_python-3.32.1}/pulp_python.egg-info/top_level.txt +0 -0
  98. {pulp_python-3.32.0 → pulp_python-3.32.1}/setup.cfg +0 -0
  99. {pulp_python-3.32.0 → pulp_python-3.32.1}/test_requirements.txt +0 -0
  100. {pulp_python-3.32.0 → pulp_python-3.32.1}/unittest_requirements.txt +0 -0
@@ -8,6 +8,15 @@
8
8
 
9
9
  [//]: # (towncrier release notes start)
10
10
 
11
+ ## 3.32.1 (2026-07-29) {: #3.32.1 }
12
+
13
+ #### Bugfixes {: #3.32.1-bugfix }
14
+
15
+ - Fixed Simple API cache incorrectly serving JSON responses for HTML requests when clients used `?format=json`.
16
+ [#1302](https://github.com/pulp/pulp_python/issues/1302)
17
+
18
+ ---
19
+
11
20
  ## 3.32.0 (2026-07-21) {: #3.32.0 }
12
21
 
13
22
  #### Features {: #3.32.0-feature }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pulp-python
3
- Version: 3.32.0
3
+ Version: 3.32.1
4
4
  Summary: pulp-python plugin for the Pulp Project
5
5
  Author-email: Pulp Team <pulp-list@redhat.com>
6
6
  Project-URL: Homepage, https://pulpproject.org
@@ -12,7 +12,7 @@ class PulpPythonPluginAppConfig(PulpPluginAppConfig):
12
12
 
13
13
  name = "pulp_python.app"
14
14
  label = "python"
15
- version = "3.32.0"
15
+ version = "3.32.1"
16
16
  python_package_name = "pulp-python"
17
17
  domain_compatible = True
18
18
 
@@ -1,25 +1,26 @@
1
1
  from pulpcore.plugin.cache import CacheKeys, SyncContentCache
2
2
  from pulpcore.plugin.util import cache_key
3
3
 
4
- ACCEPT_HEADER_KEY = "accept_header"
4
+ MEDIA_TYPE_KEY = "media_type"
5
5
 
6
6
 
7
7
  class PythonApiCache(SyncContentCache):
8
8
  """
9
9
  Cache for the Simple API.
10
10
 
11
- Adds Accept header to the cache key so HTML and JSON responses are cached separately.
11
+ Keys on the negotiated media type so HTML and JSON are cached separately,
12
+ including when the same Accept header is used with `?format=json`.
12
13
  """
13
14
 
14
15
  def __init__(self, base_key=None):
15
- keys = (CacheKeys.path, CacheKeys.method, ACCEPT_HEADER_KEY)
16
+ keys = (CacheKeys.path, CacheKeys.method, MEDIA_TYPE_KEY)
16
17
  super().__init__(base_key=base_key, keys=keys)
17
18
 
18
19
  def make_key(self, request):
19
20
  all_keys = {
20
21
  CacheKeys.path: request.path,
21
22
  CacheKeys.method: request.method,
22
- ACCEPT_HEADER_KEY: request.headers.get("accept", ""),
23
+ MEDIA_TYPE_KEY: getattr(request, "accepted_media_type", "") or "",
23
24
  }
24
25
  return ":".join(all_keys[k] for k in self.keys)
25
26
 
@@ -7,11 +7,8 @@ from pulpcore.tests.functional.utils import BindingsNamespace
7
7
 
8
8
  from pulp_python.tests.functional.constants import (
9
9
  PYTHON_EGG_FILENAME,
10
- PYTHON_EGG_URL,
11
10
  PYTHON_FIXTURE_URL,
12
11
  PYTHON_URL,
13
- PYTHON_WHEEL_FILENAME,
14
- PYTHON_WHEEL_URL,
15
12
  PYTHON_XS_PROJECT_SPECIFIER,
16
13
  )
17
14
 
@@ -239,12 +236,17 @@ def get_href(item):
239
236
 
240
237
  @pytest.fixture(scope="session")
241
238
  def python_package_dist_directory(tmp_path_factory, http_get):
242
- """Creates a temp dir to hold package distros for uploading."""
243
- dist_dir = tmp_path_factory.mktemp("dist")
244
- egg_file = dist_dir / PYTHON_EGG_FILENAME
245
- wheel_file = dist_dir / PYTHON_WHEEL_FILENAME
246
- with open(egg_file, "wb") as f:
247
- f.write(http_get(PYTHON_EGG_URL))
248
- with open(wheel_file, "wb") as f:
249
- f.write(http_get(PYTHON_WHEEL_URL))
250
- yield dist_dir, egg_file, wheel_file
239
+ """Returns a factory that downloads packages into a temp directory."""
240
+
241
+ def _download(*urls):
242
+ dist_dir = tmp_path_factory.mktemp("dist")
243
+ paths = []
244
+ for url in urls:
245
+ filename = url.rsplit("/", 1)[-1]
246
+ path = dist_dir / filename
247
+ with open(path, "wb") as f:
248
+ f.write(http_get(url))
249
+ paths.append(path)
250
+ return (dist_dir, *paths)
251
+
252
+ return _download
@@ -1,7 +1,5 @@
1
1
  import json
2
- import shutil
3
2
  import subprocess
4
- from pathlib import Path
5
3
  from urllib.parse import urljoin
6
4
 
7
5
  import pytest
@@ -10,6 +8,8 @@ from pypi_simple import PyPISimple
10
8
 
11
9
  from pulpcore.tests.functional.utils import PulpTaskError
12
10
 
11
+ from pulp_python.tests.functional.constants import PYTHON_FIXTURES_URL
12
+
13
13
 
14
14
  @pytest.fixture(scope="session")
15
15
  def twine_package():
@@ -207,24 +207,22 @@ def test_attestation_twine_upload(
207
207
  python_content_summary,
208
208
  python_empty_repo_distro,
209
209
  python_package_dist_directory,
210
+ http_get,
210
211
  monitor_task,
211
212
  ):
212
213
  """Tests that packages with attestations can be properly uploaded through Twine."""
214
+ packages_url = urljoin(PYTHON_FIXTURES_URL, "packages/")
215
+ filenames = ("twine-6.2.0.tar.gz", "twine-6.2.0-py3-none-any.whl")
216
+ dist_dir = python_package_dist_directory(*(urljoin(packages_url, f) for f in filenames))[0]
217
+
218
+ for filename in filenames:
219
+ provenance = json.loads(http_get(urljoin(packages_url, f"{filename}.provenance.json")))
220
+ attestation = provenance["attestation_bundles"][0]["attestations"][0]
221
+ with open(dist_dir / f"{filename}.publish.attestation", "w") as f:
222
+ json.dump(attestation, f)
223
+
213
224
  repo, distro = python_empty_repo_distro()
214
225
  url = urljoin(distro.base_url, "legacy/")
215
- dist_dir, _, _ = python_package_dist_directory
216
-
217
- # Copy attestation files from test assets to dist_dir
218
- assets_dir = Path(__file__).parent.parent / "assets"
219
- attestation_files = [
220
- "shelf-reader-0.1.tar.gz.publish.attestation",
221
- "shelf_reader-0.1-py2-none-any.whl.publish.attestation",
222
- ]
223
- for attestation_file in attestation_files:
224
- src = assets_dir / attestation_file
225
- dst = dist_dir / attestation_file
226
- shutil.copy2(src, dst)
227
-
228
226
  username, password = "admin", "password"
229
227
  subprocess.run(
230
228
  (
@@ -245,7 +243,7 @@ def test_attestation_twine_upload(
245
243
  tasks = pulpcore_bindings.TasksApi.list(reserved_resources=repo.pulp_href).results
246
244
  for task in reversed(tasks):
247
245
  t = monitor_task(task.pulp_href)
248
- repo_ver_href = t.created_resources[0]
246
+ repo_ver_href = [r for r in t.created_resources if "versions" in r][0]
249
247
 
250
248
  assert repo_ver_href.endswith("versions/2/")
251
249
  summary = python_content_summary(repository_version=repo_ver_href)
@@ -11,10 +11,13 @@ from pulp_python.tests.functional.constants import (
11
11
  PYPI_SIMPLE_V1_JSON,
12
12
  PYTHON_EGG_FILENAME,
13
13
  PYTHON_EGG_SHA256,
14
+ PYTHON_EGG_URL,
15
+ PYTHON_FIXTURES_URL,
14
16
  PYTHON_MD_PROJECT_SPECIFIER,
15
17
  PYTHON_MD_PYPI_SUMMARY,
16
18
  PYTHON_WHEEL_FILENAME,
17
19
  PYTHON_WHEEL_SHA256,
20
+ PYTHON_WHEEL_URL,
18
21
  SHELF_PYTHON_JSON,
19
22
  TWINE_WHEEL_FILENAME,
20
23
  TWINE_WHEEL_URL,
@@ -70,7 +73,7 @@ def test_package_upload(
70
73
  ):
71
74
  """Tests that packages can be uploaded."""
72
75
  repo, distro = python_empty_repo_distro()
73
- dist_dir, egg_file, wheel_file = python_package_dist_directory
76
+ dist_dir, egg_file, wheel_file = python_package_dist_directory(PYTHON_EGG_URL, PYTHON_WHEEL_URL)
74
77
  url = urljoin(distro.base_url, "legacy/")
75
78
  response = requests.post(
76
79
  url,
@@ -100,7 +103,7 @@ def test_package_upload_session(
100
103
  """Tests that multiple uploads will be broken up into multiple tasks."""
101
104
  repo, distro = python_empty_repo_distro()
102
105
  url = urljoin(distro.base_url, "legacy/")
103
- dist_dir, egg_file, wheel_file = python_package_dist_directory
106
+ dist_dir, egg_file, wheel_file = python_package_dist_directory(PYTHON_EGG_URL, PYTHON_WHEEL_URL)
104
107
  session = requests.Session()
105
108
  response = session.post(
106
109
  url,
@@ -130,7 +133,7 @@ def test_package_upload_simple(
130
133
  """Tests that the package upload endpoint exposed at `/simple/` works."""
131
134
  repo, distro = python_empty_repo_distro()
132
135
  url = urljoin(distro.base_url, "simple/")
133
- dist_dir, egg_file, wheel_file = python_package_dist_directory
136
+ dist_dir, egg_file, wheel_file = python_package_dist_directory(PYTHON_EGG_URL, PYTHON_WHEEL_URL)
134
137
  response = requests.post(
135
138
  url,
136
139
  data={"sha256_digest": PYTHON_EGG_SHA256},
@@ -156,7 +159,7 @@ def test_package_upload_with_metadata(
156
159
  """
157
160
  repo, distro = python_empty_repo_distro()
158
161
  url = urljoin(distro.base_url, "simple/")
159
- dist_dir, egg_file, wheel_file = python_package_dist_directory
162
+ dist_dir, egg_file, wheel_file = python_package_dist_directory(PYTHON_EGG_URL, PYTHON_WHEEL_URL)
160
163
  response = requests.post(
161
164
  url,
162
165
  data={"sha256_digest": PYTHON_WHEEL_SHA256},
@@ -183,9 +186,14 @@ def test_twine_upload(
183
186
  monitor_task,
184
187
  ):
185
188
  """Tests that packages can be properly uploaded through Twine."""
189
+ packages_url = urljoin(PYTHON_FIXTURES_URL, "packages/")
190
+ dist_dir, _, _ = python_package_dist_directory(
191
+ urljoin(packages_url, "pytz-2023.3.tar.gz"),
192
+ urljoin(packages_url, "pytz-2023.3-py2.py3-none-any.whl"),
193
+ )
194
+
186
195
  repo, distro = python_empty_repo_distro()
187
196
  url = urljoin(distro.base_url, "legacy/")
188
- dist_dir, _, _ = python_package_dist_directory
189
197
  username, password = "admin", "password"
190
198
  subprocess.run(
191
199
  (
@@ -205,7 +213,7 @@ def test_twine_upload(
205
213
  tasks = pulpcore_bindings.TasksApi.list(reserved_resources=repo.pulp_href).results
206
214
  for task in reversed(tasks):
207
215
  t = monitor_task(task.pulp_href)
208
- repo_ver_href = t.created_resources[-1]
216
+ repo_ver_href = [r for r in t.created_resources if "versions" in r][0]
209
217
  summary = python_content_summary(repository_version=repo_ver_href)
210
218
  assert summary.present["python.python"]["count"] == 2
211
219
 
@@ -6,6 +6,7 @@ import requests
6
6
  from pulp_python.tests.functional.constants import (
7
7
  PYPI_SIMPLE_V1_HTML,
8
8
  PYPI_SIMPLE_V1_JSON,
9
+ PYPI_TEXT_HTML,
9
10
  PYTHON_SM_PROJECT_SPECIFIER,
10
11
  )
11
12
 
@@ -59,7 +60,7 @@ def test_simple_cache_hit_miss_and_headers(synced_distro):
59
60
  @pytest.mark.parallel
60
61
  def test_simple_cache_separate_accept_headers(synced_distro):
61
62
  """
62
- HTML and JSON responses are cached separately.
63
+ HTML and JSON responses are cached separately by negotiated media type.
63
64
  """
64
65
  url = urljoin(synced_distro.base_url, "simple/")
65
66
 
@@ -74,6 +75,45 @@ def test_simple_cache_separate_accept_headers(synced_distro):
74
75
  assert r.headers["X-PULP-CACHE"] == "HIT"
75
76
 
76
77
 
78
+ @pytest.mark.parallel
79
+ def test_simple_cache_format_json_does_not_poison_html(synced_distro):
80
+ """
81
+ A ?format=json response must not poison a later request with the same Accept.
82
+
83
+ Clients like uv/pip send an Accept that allows both JSON and HTML. DRF's
84
+ ?format=json overrides negotiation to JSON, while the same Accept without
85
+ that query param selects HTML. Caching must key on the negotiated type so
86
+ the JSON entry is not served (and re-rendered) for the HTML request.
87
+ """
88
+ url = f"{urljoin(synced_distro.base_url, 'simple/')}aiohttp"
89
+ # pip/uv-style Accept: JSON preferred, HTML still acceptable
90
+ headers = {
91
+ "Accept": (f"{PYPI_SIMPLE_V1_JSON}, {PYPI_SIMPLE_V1_HTML};q=0.1, {PYPI_TEXT_HTML};q=0.01")
92
+ }
93
+
94
+ r_json = requests.get(url, headers=headers, params={"format": "json"})
95
+ assert r_json.status_code == 200
96
+ assert PYPI_SIMPLE_V1_JSON in r_json.headers["Content-Type"]
97
+ assert r_json.headers["X-PULP-CACHE"] == "MISS"
98
+ assert r_json.json()["name"] == "aiohttp"
99
+
100
+ r_html = requests.get(url, headers=headers)
101
+ assert r_html.status_code == 200
102
+ assert PYPI_TEXT_HTML in r_html.headers["Content-Type"]
103
+ assert r_html.headers["X-PULP-CACHE"] == "MISS"
104
+ assert b"<a href=" in r_html.content
105
+
106
+ r_html_hit = requests.get(url, headers=headers)
107
+ assert r_html_hit.status_code == 200
108
+ assert r_html_hit.headers["X-PULP-CACHE"] == "HIT"
109
+ assert PYPI_TEXT_HTML in r_html_hit.headers["Content-Type"]
110
+
111
+ r_json_hit = requests.get(url, headers=headers, params={"format": "json"})
112
+ assert r_json_hit.status_code == 200
113
+ assert r_json_hit.headers["X-PULP-CACHE"] == "HIT"
114
+ assert PYPI_SIMPLE_V1_JSON in r_json_hit.headers["Content-Type"]
115
+
116
+
77
117
  @pytest.mark.parallel
78
118
  def test_simple_cache_etag_conditional_request(synced_distro):
79
119
  """
@@ -82,7 +82,7 @@ def test_synchronous_package_upload_with_metadata(
82
82
  def test_legacy_upload_invalid_protocol_version(
83
83
  python_empty_repo_distro, python_package_dist_directory
84
84
  ):
85
- _, egg_file, _ = python_package_dist_directory
85
+ _, egg_file, _ = python_package_dist_directory(PYTHON_EGG_URL, PYTHON_WHEEL_URL)
86
86
  _, distro = python_empty_repo_distro()
87
87
  url = urljoin(distro.base_url, "legacy/")
88
88
  with open(egg_file, "rb") as f:
@@ -108,7 +108,7 @@ def test_legacy_upload_invalid_protocol_version(
108
108
 
109
109
  @pytest.mark.parallel
110
110
  def test_legacy_upload_invalid_filetype(python_empty_repo_distro, python_package_dist_directory):
111
- _, egg_file, wheel_file = python_package_dist_directory
111
+ _, egg_file, wheel_file = python_package_dist_directory(PYTHON_EGG_URL, PYTHON_WHEEL_URL)
112
112
  _, distro = python_empty_repo_distro()
113
113
  url = urljoin(distro.base_url, "legacy/")
114
114
  with open(egg_file, "rb") as f:
@@ -140,7 +140,7 @@ def test_legacy_upload_invalid_filetype(python_empty_repo_distro, python_package
140
140
  def test_legacy_upload_invalid_metadata_version(
141
141
  python_empty_repo_distro, python_package_dist_directory
142
142
  ):
143
- _, egg_file, _ = python_package_dist_directory
143
+ _, egg_file, _ = python_package_dist_directory(PYTHON_EGG_URL, PYTHON_WHEEL_URL)
144
144
  _, distro = python_empty_repo_distro()
145
145
  url = urljoin(distro.base_url, "legacy/")
146
146
  with open(egg_file, "rb") as f:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pulp-python
3
- Version: 3.32.0
3
+ Version: 3.32.1
4
4
  Summary: pulp-python plugin for the Pulp Project
5
5
  Author-email: Pulp Team <pulp-list@redhat.com>
6
6
  Project-URL: Homepage, https://pulpproject.org
@@ -92,7 +92,5 @@ pulp_python/tests/functional/api/test_simple_cache.py
92
92
  pulp_python/tests/functional/api/test_sync.py
93
93
  pulp_python/tests/functional/api/test_upload.py
94
94
  pulp_python/tests/functional/api/test_vulnerability_report.py
95
- pulp_python/tests/functional/assets/shelf-reader-0.1.tar.gz.publish.attestation
96
- pulp_python/tests/functional/assets/shelf_reader-0.1-py2-none-any.whl.publish.attestation
97
95
  pulp_python/tests/unit/__init__.py
98
96
  pulp_python/tests/unit/test_models.py
@@ -7,7 +7,7 @@ build-backend = 'setuptools.build_meta'
7
7
 
8
8
  [project]
9
9
  name = "pulp-python"
10
- version = "3.32.0"
10
+ version = "3.32.1"
11
11
  description = "pulp-python plugin for the Pulp Project"
12
12
  readme = "README.md"
13
13
  authors = [
@@ -79,7 +79,7 @@ ignore = [
79
79
  [tool.bumpversion]
80
80
  # This section is managed by the plugin template. Do not edit manually.
81
81
 
82
- current_version = "3.32.0"
82
+ current_version = "3.32.1"
83
83
  commit = false
84
84
  tag = false
85
85
  parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<alpha>0a)?(?P<patch>\\d+)(\\.(?P<release>[a-z]+))?"
@@ -138,6 +138,7 @@ extend-exclude = [
138
138
 
139
139
  [tool.ruff.lint]
140
140
  # This section is managed by the plugin template. Do not edit manually.
141
+ select = ["E4", "E7", "E9", "F"]
141
142
  extend-select = [
142
143
  "I",
143
144
  "INT",
@@ -1 +0,0 @@
1
- {"version":1,"verification_material":{"certificate":"MIIIMzCCB7igAwIBAgIUKrdo9OfFJy6MuUewIeE/ILWw/tswCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjUxMjA0MjAzMjM5WhcNMjUxMjA0MjA0MjM5WjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEleubASHneG8xQmJ/HacfPp63RpBRb71lTUW3uqc/dxFttAkIu11LtR5Y1aRa7h/uFP6e9B/3WAV11xiu29vxRqOCBtcwggbTMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUcDHutpRx316lThqpRMpz2kw+/f4wHwYDVR0jBBgwFoAUcYYwphR8Ym/599b0BRp/X//rb6wwgaUGA1UdEQEB/wSBmjCBl4aBlGh0dHBzOi8vZ2l0aHViLmNvbS9zaWdzdG9yZS1jb25mb3JtYW5jZS9leHRyZW1lbHktZGFuZ2Vyb3VzLXB1YmxpYy1vaWRjLWJlYWNvbi8uZ2l0aHViL3dvcmtmbG93cy9leHRyZW1lbHktZGFuZ2Vyb3VzLW9pZGMtYmVhY29uLnltbEByZWZzL2hlYWRzL21haW4wOQYKKwYBBAGDvzABAQQraHR0cHM6Ly90b2tlbi5hY3Rpb25zLmdpdGh1YnVzZXJjb250ZW50LmNvbTAfBgorBgEEAYO/MAECBBF3b3JrZmxvd19kaXNwYXRjaDA2BgorBgEEAYO/MAEDBCg3OTU4NmMxZGVhZDhiODhmYmZhOWE3ODgyZGExMTZkZWNmNjc0YTQyMC0GCisGAQQBg78wAQQEH0V4dHJlbWVseSBkYW5nZXJvdXMgT0lEQyBiZWFjb24wSQYKKwYBBAGDvzABBQQ7c2lnc3RvcmUtY29uZm9ybWFuY2UvZXh0cmVtZWx5LWRhbmdlcm91cy1wdWJsaWMtb2lkYy1iZWFjb24wHQYKKwYBBAGDvzABBgQPcmVmcy9oZWFkcy9tYWluMDsGCisGAQQBg78wAQgELQwraHR0cHM6Ly90b2tlbi5hY3Rpb25zLmdpdGh1YnVzZXJjb250ZW50LmNvbTCBpgYKKwYBBAGDvzABCQSBlwyBlGh0dHBzOi8vZ2l0aHViLmNvbS9zaWdzdG9yZS1jb25mb3JtYW5jZS9leHRyZW1lbHktZGFuZ2Vyb3VzLXB1YmxpYy1vaWRjLWJlYWNvbi8uZ2l0aHViL3dvcmtmbG93cy9leHRyZW1lbHktZGFuZ2Vyb3VzLW9pZGMtYmVhY29uLnltbEByZWZzL2hlYWRzL21haW4wOAYKKwYBBAGDvzABCgQqDCg3OTU4NmMxZGVhZDhiODhmYmZhOWE3ODgyZGExMTZkZWNmNjc0YTQyMB0GCisGAQQBg78wAQsEDwwNZ2l0aHViLWhvc3RlZDBeBgorBgEEAYO/MAEMBFAMTmh0dHBzOi8vZ2l0aHViLmNvbS9zaWdzdG9yZS1jb25mb3JtYW5jZS9leHRyZW1lbHktZGFuZ2Vyb3VzLXB1YmxpYy1vaWRjLWJlYWNvbjA4BgorBgEEAYO/MAENBCoMKDc5NTg2YzFkZWFkOGI4OGZiZmE5YTc4ODJkYTExNmRlY2Y2NzRhNDIwHwYKKwYBBAGDvzABDgQRDA9yZWZzL2hlYWRzL21haW4wGQYKKwYBBAGDvzABDwQLDAk2MzI1OTY4OTcwNwYKKwYBBAGDvzABEAQpDCdodHRwczovL2dpdGh1Yi5jb20vc2lnc3RvcmUtY29uZm9ybWFuY2UwGQYKKwYBBAGDvzABEQQLDAkxMzE4MDQ1NjMwgaYGCisGAQQBg78wARIEgZcMgZRodHRwczovL2dpdGh1Yi5jb20vc2lnc3RvcmUtY29uZm9ybWFuY2UvZXh0cmVtZWx5LWRhbmdlcm91cy1wdWJsaWMtb2lkYy1iZWFjb24vLmdpdGh1Yi93b3JrZmxvd3MvZXh0cmVtZWx5LWRhbmdlcm91cy1vaWRjLWJlYWNvbi55bWxAcmVmcy9oZWFkcy9tYWluMDgGCisGAQQBg78wARMEKgwoNzk1ODZjMWRlYWQ4Yjg4ZmJmYTlhNzg4MmRhMTE2ZGVjZjY3NGE0MjAhBgorBgEEAYO/MAEUBBMMEXdvcmtmbG93X2Rpc3BhdGNoMIGCBgorBgEEAYO/MAEVBHQMcmh0dHBzOi8vZ2l0aHViLmNvbS9zaWdzdG9yZS1jb25mb3JtYW5jZS9leHRyZW1lbHktZGFuZ2Vyb3VzLXB1YmxpYy1vaWRjLWJlYWNvbi9hY3Rpb25zL3J1bnMvMTk5NDMwMzAxOTkvYXR0ZW1wdHMvMTAWBgorBgEEAYO/MAEWBAgMBnB1YmxpYzCBigYKKwYBBAHWeQIEAgR8BHoAeAB2ACswvNxoiMni4dgmKV50H0g5MZYC8pwzy15DQP6yrIZ6AAABmusRH1wAAAQDAEcwRQIgMjrB10EwMTKAWmjTMab2AX1YMg1lWJp7xV3yhBx7GyYCIQC5zr44ZzUSPnJ3Gtm6k8M1CBoIzDYWzwBIoRAdh5NE3TAKBggqhkjOPQQDAwNpADBmAjEAgyfhSQno+h3UugP0A6V0A8b++q1IV4hYm4dVfi6skZKkEYMFbs0ocMWqWlJg8PaFAjEAt7+HDiWOfa3MxLPnIdzeEPz4kbgXZqKQDMHY5m1ZG976bnJBwttMAbAEXhELfyHl","transparency_entries":[{"logIndex":"51125016","logId":{"keyId":"0y8wo8MtY5wrdiIFohx7sHeI5oKDpK5vQhGHI6G+pJY="},"kindVersion":{"kind":"dsse","version":"0.0.1"},"integratedTime":"1764880360","inclusionPromise":{"signedEntryTimestamp":"MEUCIQC48Y/s6Rv+IoXoftvGOhM3sccchkODD/YqwIKJgwJAiAIgWkva5KEaCl3P78T21oElOTbq9cOxurz//9N9giFPDWw="},"inclusionProof":{"logIndex":"19442604","rootHash":"EdmMTYTkzJL0XRtufY9DMHS2axO0Vg6jO4eVM/Cetd4=","treeSize":"19442605","hashes":["k5UsnMaUY0kOQlFg0Za5deoskYSOUTFQ2Jzl3upcbX0=","F8+CGCoMNj9Jb1Csuk4bxbAWW35iktydoLKPPLk6Hb8=","P6IFMwnZlp99wiunjusnNW+K5V06iOEtzfoD9MtHCSU=","V4//f/ISXnSeJjUckmcLLzwS38XjXwMjrMAw6B3hKfg=","baLnSFGPpXZDhE38YKkGPW9P35RXQTaZlgDJ2i/u5xA=","YPKEUUZB3AVufkBQm5r7wLJeJMECETlxWoHo3+sKnHE=","VEcYk6UKGgyx1fCjyU6cfCPViC8OZFBjvHz8fco4eGM=","tf738kZ3YKyYiskKppTF5etATmFZgyY6H1ktyC0leCA=","gXQKVsGeO2E9oDbviE7+SuHFG5g7UH35dYGHc9JSz8s=","6kC2DcsZfB5F/TmenKHUzDr2UH6XK//Ch6hC8PZWJ5c=","JA9P8Q8v916uA/xomSrsiXeVBiyxxQAD5Mer9MBIYzA=","BrjYsYvo65dTDWKO8aY0s+9WaWHlVdZuOEzsBHLHe8U="],"checkpoint":{"envelope":"rekor.sigstage.dev - 8202293616175992157\n19442605\nEdmMTYTkzJL0XRtufY9DMHS2axO0Vg6jO4eVM/Cetd4=\n\n— rekor.sigstage.dev 0y8wozBFAiAPcLZnrw7rn8sFhxqGjp5q58EtMUibZptS8W1Mk6CcAAIhAJ6c+pCBCCe4+K1+zxuUsofR9Y56J5pTBvqvfGceJI/l\n"}},"canonicalizedBody":"eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiZHNzZSIsInNwZWMiOnsiZW52ZWxvcGVIYXNoIjp7ImFsZ29yaXRobSI6InNoYTI1NiIsInZhbHVlIjoiYzJkZjczOTEzMzgyZmVkM2MzNTU5ODRjOTdiN2Y2NTc5YTYxZmVmZDAwOWMxYmM3M2M2ODE0ODk3ZjMxNDY3MyJ9LCJwYXlsb2FkSGFzaCI6eyJhbGdvcml0aG0iOiJzaGEyNTYiLCJ2YWx1ZSI6IjRkMjdjMTZjMTI3ZDM4ZGE2NDU3MGVmMmY3Mjc2MjIwOWVjMzlkMmU0NjhiYjQ0YTU5NjE1MjhlOTMyNDNjNWQifSwic2lnbmF0dXJlcyI6W3sic2lnbmF0dXJlIjoiTUVZQ0lRQ2hSUGN1N2w5QXBIbTAxNlE3bnpob3pxaHkvYXVBV1NiWWc5MUpxQzluYlFJaEFOdGtFV01hV2RHS0dUZHVNZW4yQ081eDhPY1N0UStyazlnWVFWeDk1YU9VIiwidmVyaWZpZXIiOiJMUzB0TFMxQ1JVZEpUaUJEUlZKVVNVWkpRMEZVUlMwdExTMHRDazFKU1VsTmVrTkRRamRwWjBGM1NVSkJaMGxWUzNKa2J6bFBaa1pLZVRaTmRWVmxkMGxsUlM5SlRGZDNMM1J6ZDBObldVbExiMXBKZW1vd1JVRjNUWGNLVG5wRlZrMUNUVWRCTVZWRlEyaE5UV015Ykc1ak0xSjJZMjFWZFZwSFZqSk5ValIzU0VGWlJGWlJVVVJGZUZaNllWZGtlbVJIT1hsYVV6RndZbTVTYkFwamJURnNXa2RzYUdSSFZYZElhR05PVFdwVmVFMXFRVEJOYWtGNlRXcE5OVmRvWTA1TmFsVjRUV3BCTUUxcVFUQk5hazAxVjJwQlFVMUdhM2RGZDFsSUNrdHZXa2w2YWpCRFFWRlpTVXR2V2tsNmFqQkVRVkZqUkZGblFVVnNaWFZpUVZOSWJtVkhPSGhSYlVvdlNHRmpabEJ3TmpOU2NFSlNZamN4YkZSVlZ6TUtkWEZqTDJSNFJuUjBRV3RKZFRFeFRIUlNOVmt4WVZKaE4yZ3ZkVVpRTm1VNVFpOHpWMEZXTVRGNGFYVXlPWFo0VW5GUFEwSjBZM2RuWjJKVVRVRTBSd3BCTVZWa1JIZEZRaTkzVVVWQmQwbElaMFJCVkVKblRsWklVMVZGUkVSQlMwSm5aM0pDWjBWR1FsRmpSRUY2UVdSQ1owNVdTRkUwUlVablVWVmpSRWgxQ25Sd1VuZ3pNVFpzVkdoeGNGSk5jSG95YTNjckwyWTBkMGgzV1VSV1VqQnFRa0puZDBadlFWVmpXVmwzY0doU09GbHRMelU1T1dJd1FsSndMMWd2TDNJS1lqWjNkMmRoVlVkQk1WVmtSVkZGUWk5M1UwSnRha05DYkRSaFFteEhhREJrU0VKNlQyazRkbG95YkRCaFNGWnBURzFPZG1KVE9YcGhWMlI2WkVjNWVRcGFVekZxWWpJMWJXSXpTblJaVnpWcVdsTTViR1ZJVW5sYVZ6RnNZa2hyZEZwSFJuVmFNbFo1WWpOV2VreFlRakZaYlhod1dYa3hkbUZYVW1wTVYwcHNDbGxYVG5aaWFUaDFXakpzTUdGSVZtbE1NMlIyWTIxMGJXSkhPVE5qZVRsc1pVaFNlVnBYTVd4aVNHdDBXa2RHZFZveVZubGlNMVo2VEZjNWNGcEhUWFFLV1cxV2FGa3lPWFZNYm14MFlrVkNlVnBYV25wTU1taHNXVmRTZWt3eU1XaGhWelIzVDFGWlMwdDNXVUpDUVVkRWRucEJRa0ZSVVhKaFNGSXdZMGhOTmdwTWVUa3dZakowYkdKcE5XaFpNMUp3WWpJMWVreHRaSEJrUjJneFdXNVdlbHBZU21waU1qVXdXbGMxTUV4dFRuWmlWRUZtUW1kdmNrSm5SVVZCV1U4dkNrMUJSVU5DUWtZellqTktjbHB0ZUhaa01UbHJZVmhPZDFsWVVtcGhSRUV5UW1kdmNrSm5SVVZCV1U4dlRVRkZSRUpEWnpOUFZGVTBUbTFOZUZwSFZtZ0tXa1JvYVU5RWFHMVpiVnBvVDFkRk0wOUVaM2xhUjBWNFRWUmFhMXBYVG0xT2FtTXdXVlJSZVUxRE1FZERhWE5IUVZGUlFtYzNPSGRCVVZGRlNEQldOQXBrU0Vwc1lsZFdjMlZUUW10WlZ6VnVXbGhLZG1SWVRXZFVNR3hGVVhsQ2FWcFhSbXBpTWpSM1UxRlpTMHQzV1VKQ1FVZEVkbnBCUWtKUlVUZGpNbXh1Q21NelVuWmpiVlYwV1RJNWRWcHRPWGxpVjBaMVdUSlZkbHBZYURCamJWWjBXbGQ0TlV4WFVtaGliV1JzWTIwNU1XTjVNWGRrVjBwellWZE5kR0l5YkdzS1dYa3hhVnBYUm1waU1qUjNTRkZaUzB0M1dVSkNRVWRFZG5wQlFrSm5VVkJqYlZadFkzazViMXBYUm10amVUbDBXVmRzZFUxRWMwZERhWE5IUVZGUlFncG5OemgzUVZGblJVeFJkM0poU0ZJd1kwaE5Oa3g1T1RCaU1uUnNZbWsxYUZrelVuQmlNalY2VEcxa2NHUkhhREZaYmxaNldsaEthbUl5TlRCYVZ6VXdDa3h0VG5aaVZFTkNjR2RaUzB0M1dVSkNRVWRFZG5wQlFrTlJVMEpzZDNsQ2JFZG9NR1JJUW5wUGFUaDJXakpzTUdGSVZtbE1iVTUyWWxNNWVtRlhaSG9LWkVjNWVWcFRNV3BpTWpWdFlqTktkRmxYTldwYVV6bHNaVWhTZVZwWE1XeGlTR3QwV2tkR2RWb3lWbmxpTTFaNlRGaENNVmx0ZUhCWmVURjJZVmRTYWdwTVYwcHNXVmRPZG1KcE9IVmFNbXd3WVVoV2FVd3paSFpqYlhSdFlrYzVNMk41T1d4bFNGSjVXbGN4YkdKSWEzUmFSMFoxV2pKV2VXSXpWbnBNVnpsd0NscEhUWFJaYlZab1dUSTVkVXh1YkhSaVJVSjVXbGRhZWt3eWFHeFpWMUo2VERJeGFHRlhOSGRQUVZsTFMzZFpRa0pCUjBSMmVrRkNRMmRSY1VSRFp6TUtUMVJWTkU1dFRYaGFSMVpvV2tSb2FVOUVhRzFaYlZwb1QxZEZNMDlFWjNsYVIwVjRUVlJhYTFwWFRtMU9hbU13V1ZSUmVVMUNNRWREYVhOSFFWRlJRZ3BuTnpoM1FWRnpSVVIzZDA1YU1td3dZVWhXYVV4WGFIWmpNMUpzV2tSQ1pVSm5iM0pDWjBWRlFWbFBMMDFCUlUxQ1JrRk5WRzFvTUdSSVFucFBhVGgyQ2xveWJEQmhTRlpwVEcxT2RtSlRPWHBoVjJSNlpFYzVlVnBUTVdwaU1qVnRZak5LZEZsWE5XcGFVemxzWlVoU2VWcFhNV3hpU0d0MFdrZEdkVm95Vm5rS1lqTldla3hZUWpGWmJYaHdXWGt4ZG1GWFVtcE1WMHBzV1ZkT2RtSnFRVFJDWjI5eVFtZEZSVUZaVHk5TlFVVk9Ra052VFV0RVl6Vk9WR2N5V1hwR2F3cGFWMFpyVDBkSk5FOUhXbWxhYlVVMVdWUmpORTlFU210WlZFVjRUbTFTYkZreVdUSk9lbEpvVGtSSmQwaDNXVXRMZDFsQ1FrRkhSSFo2UVVKRVoxRlNDa1JCT1hsYVYxcDZUREpvYkZsWFVucE1NakZvWVZjMGQwZFJXVXRMZDFsQ1FrRkhSSFo2UVVKRWQxRk1SRUZyTWsxNlNURlBWRmswVDFSamQwNTNXVXNLUzNkWlFrSkJSMFIyZWtGQ1JVRlJjRVJEWkc5a1NGSjNZM3B2ZGt3eVpIQmtSMmd4V1drMWFtSXlNSFpqTW14dVl6TlNkbU50VlhSWk1qbDFXbTA1ZVFwaVYwWjFXVEpWZDBkUldVdExkMWxDUWtGSFJIWjZRVUpGVVZGTVJFRnJlRTE2UlRSTlJGRXhUbXBOZDJkaFdVZERhWE5IUVZGUlFtYzNPSGRCVWtsRkNtZGFZMDFuV2xKdlpFaFNkMk42YjNaTU1tUndaRWRvTVZscE5XcGlNakIyWXpKc2JtTXpVblpqYlZWMFdUSTVkVnB0T1hsaVYwWjFXVEpWZGxwWWFEQUtZMjFXZEZwWGVEVk1WMUpvWW0xa2JHTnRPVEZqZVRGM1pGZEtjMkZYVFhSaU1teHJXWGt4YVZwWFJtcGlNalIyVEcxa2NHUkhhREZaYVRrellqTktjZ3BhYlhoMlpETk5kbHBZYURCamJWWjBXbGQ0TlV4WFVtaGliV1JzWTIwNU1XTjVNWFpoVjFKcVRGZEtiRmxYVG5aaWFUVTFZbGQ0UVdOdFZtMWplVGx2Q2xwWFJtdGplVGwwV1Zkc2RVMUVaMGREYVhOSFFWRlJRbWMzT0hkQlVrMUZTMmQzYjA1NmF6RlBSRnBxVFZkU2JGbFhVVFJaYW1jMFdtMUtiVmxVYkdnS1RucG5ORTF0VW1oTlZFVXlXa2RXYWxwcVdUTk9SMFV3VFdwQmFFSm5iM0pDWjBWRlFWbFBMMDFCUlZWQ1FrMU5SVmhrZG1OdGRHMWlSemt6V0RKU2NBcGpNMEpvWkVkT2IwMUpSME5DWjI5eVFtZEZSVUZaVHk5TlFVVldRa2hSVFdOdGFEQmtTRUo2VDJrNGRsb3liREJoU0ZacFRHMU9kbUpUT1hwaFYyUjZDbVJIT1hsYVV6RnFZakkxYldJelNuUlpWelZxV2xNNWJHVklVbmxhVnpGc1lraHJkRnBIUm5WYU1sWjVZak5XZWt4WVFqRlpiWGh3V1hreGRtRlhVbW9LVEZkS2JGbFhUblppYVRsb1dUTlNjR0l5TlhwTU0wb3hZbTVOZGsxVWF6Vk9SRTEzVFhwQmVFOVVhM1paV0ZJd1dsY3hkMlJJVFhaTlZFRlhRbWR2Y2dwQ1owVkZRVmxQTDAxQlJWZENRV2ROUW01Q01WbHRlSEJaZWtOQ2FXZFpTMHQzV1VKQ1FVaFhaVkZKUlVGblVqaENTRzlCWlVGQ01rRkRjM2QyVG5odkNtbE5ibWswWkdkdFMxWTFNRWd3WnpWTldsbERPSEIzZW5reE5VUlJVRFo1Y2tsYU5rRkJRVUp0ZFhOU1NERjNRVUZCVVVSQlJXTjNVbEZKWjAxcWNrSUtNVEJGZDAxVVMwRlhiV3BVVFdGaU1rRllNVmxOWnpGc1YwcHdOM2hXTTNsb1FuZzNSM2xaUTBsUlF6VjZjalEwV25wVlUxQnVTak5IZEcwMmF6aE5NUXBEUW05SmVrUlpWM3AzUWtsdlVrRmthRFZPUlROVVFVdENaMmR4YUd0cVQxQlJVVVJCZDA1d1FVUkNiVUZxUlVGbmVXWm9VMUZ1Ynl0b00xVjFaMUF3Q2tFMlZqQkJPR0lySzNFeFNWWTBhRmx0TkdSV1ptazJjMnRhUzJ0RldVMUdZbk13YjJOTlYzRlhiRXBuT0ZCaFJrRnFSVUYwTnl0SVJHbFhUMlpoTTAwS2VFeFFia2xrZW1WRlVIbzBhMkpuV0ZweFMxRkVUVWhaTlcweFdrYzVOelppYmtwQ2QzUjBUVUZpUVVWWWFFVk1abmxJYkFvdExTMHRMVVZPUkNCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2c9PSJ9XX19"}]},"envelope":{"statement":"eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjEiLCJzdWJqZWN0IjpbeyJuYW1lIjoic2hlbGYtcmVhZGVyLTAuMS50YXIuZ3oiLCJkaWdlc3QiOnsic2hhMjU2IjoiMDRjZmQ4YmI0Zjg0M2UzNWQ1MWJmZGVmMjAzNTEwOWJkZWE4MzFiNTVhNTdjM2U2YTE1NGQxNGJlMTE2Mzk4YyJ9fV0sInByZWRpY2F0ZVR5cGUiOiJodHRwczovL2RvY3MucHlwaS5vcmcvYXR0ZXN0YXRpb25zL3B1Ymxpc2gvdjEiLCJwcmVkaWNhdGUiOm51bGx9","signature":"MEYCIQChRPcu7l9ApHm016Q7nzhozqhy/auAWSbYg91JqC9nbQIhANtkEWMaWdGKGTduMen2CO5x8OcStQ+rk9gYQVx95aOU"}}
@@ -1 +0,0 @@
1
- {"version":1,"verification_material":{"certificate":"MIIIMzCCB7igAwIBAgIUKrdo9OfFJy6MuUewIeE/ILWw/tswCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjUxMjA0MjAzMjM5WhcNMjUxMjA0MjA0MjM5WjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEleubASHneG8xQmJ/HacfPp63RpBRb71lTUW3uqc/dxFttAkIu11LtR5Y1aRa7h/uFP6e9B/3WAV11xiu29vxRqOCBtcwggbTMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUcDHutpRx316lThqpRMpz2kw+/f4wHwYDVR0jBBgwFoAUcYYwphR8Ym/599b0BRp/X//rb6wwgaUGA1UdEQEB/wSBmjCBl4aBlGh0dHBzOi8vZ2l0aHViLmNvbS9zaWdzdG9yZS1jb25mb3JtYW5jZS9leHRyZW1lbHktZGFuZ2Vyb3VzLXB1YmxpYy1vaWRjLWJlYWNvbi8uZ2l0aHViL3dvcmtmbG93cy9leHRyZW1lbHktZGFuZ2Vyb3VzLW9pZGMtYmVhY29uLnltbEByZWZzL2hlYWRzL21haW4wOQYKKwYBBAGDvzABAQQraHR0cHM6Ly90b2tlbi5hY3Rpb25zLmdpdGh1YnVzZXJjb250ZW50LmNvbTAfBgorBgEEAYO/MAECBBF3b3JrZmxvd19kaXNwYXRjaDA2BgorBgEEAYO/MAEDBCg3OTU4NmMxZGVhZDhiODhmYmZhOWE3ODgyZGExMTZkZWNmNjc0YTQyMC0GCisGAQQBg78wAQQEH0V4dHJlbWVseSBkYW5nZXJvdXMgT0lEQyBiZWFjb24wSQYKKwYBBAGDvzABBQQ7c2lnc3RvcmUtY29uZm9ybWFuY2UvZXh0cmVtZWx5LWRhbmdlcm91cy1wdWJsaWMtb2lkYy1iZWFjb24wHQYKKwYBBAGDvzABBgQPcmVmcy9oZWFkcy9tYWluMDsGCisGAQQBg78wAQgELQwraHR0cHM6Ly90b2tlbi5hY3Rpb25zLmdpdGh1YnVzZXJjb250ZW50LmNvbTCBpgYKKwYBBAGDvzABCQSBlwyBlGh0dHBzOi8vZ2l0aHViLmNvbS9zaWdzdG9yZS1jb25mb3JtYW5jZS9leHRyZW1lbHktZGFuZ2Vyb3VzLXB1YmxpYy1vaWRjLWJlYWNvbi8uZ2l0aHViL3dvcmtmbG93cy9leHRyZW1lbHktZGFuZ2Vyb3VzLW9pZGMtYmVhY29uLnltbEByZWZzL2hlYWRzL21haW4wOAYKKwYBBAGDvzABCgQqDCg3OTU4NmMxZGVhZDhiODhmYmZhOWE3ODgyZGExMTZkZWNmNjc0YTQyMB0GCisGAQQBg78wAQsEDwwNZ2l0aHViLWhvc3RlZDBeBgorBgEEAYO/MAEMBFAMTmh0dHBzOi8vZ2l0aHViLmNvbS9zaWdzdG9yZS1jb25mb3JtYW5jZS9leHRyZW1lbHktZGFuZ2Vyb3VzLXB1YmxpYy1vaWRjLWJlYWNvbjA4BgorBgEEAYO/MAENBCoMKDc5NTg2YzFkZWFkOGI4OGZiZmE5YTc4ODJkYTExNmRlY2Y2NzRhNDIwHwYKKwYBBAGDvzABDgQRDA9yZWZzL2hlYWRzL21haW4wGQYKKwYBBAGDvzABDwQLDAk2MzI1OTY4OTcwNwYKKwYBBAGDvzABEAQpDCdodHRwczovL2dpdGh1Yi5jb20vc2lnc3RvcmUtY29uZm9ybWFuY2UwGQYKKwYBBAGDvzABEQQLDAkxMzE4MDQ1NjMwgaYGCisGAQQBg78wARIEgZcMgZRodHRwczovL2dpdGh1Yi5jb20vc2lnc3RvcmUtY29uZm9ybWFuY2UvZXh0cmVtZWx5LWRhbmdlcm91cy1wdWJsaWMtb2lkYy1iZWFjb24vLmdpdGh1Yi93b3JrZmxvd3MvZXh0cmVtZWx5LWRhbmdlcm91cy1vaWRjLWJlYWNvbi55bWxAcmVmcy9oZWFkcy9tYWluMDgGCisGAQQBg78wARMEKgwoNzk1ODZjMWRlYWQ4Yjg4ZmJmYTlhNzg4MmRhMTE2ZGVjZjY3NGE0MjAhBgorBgEEAYO/MAEUBBMMEXdvcmtmbG93X2Rpc3BhdGNoMIGCBgorBgEEAYO/MAEVBHQMcmh0dHBzOi8vZ2l0aHViLmNvbS9zaWdzdG9yZS1jb25mb3JtYW5jZS9leHRyZW1lbHktZGFuZ2Vyb3VzLXB1YmxpYy1vaWRjLWJlYWNvbi9hY3Rpb25zL3J1bnMvMTk5NDMwMzAxOTkvYXR0ZW1wdHMvMTAWBgorBgEEAYO/MAEWBAgMBnB1YmxpYzCBigYKKwYBBAHWeQIEAgR8BHoAeAB2ACswvNxoiMni4dgmKV50H0g5MZYC8pwzy15DQP6yrIZ6AAABmusRH1wAAAQDAEcwRQIgMjrB10EwMTKAWmjTMab2AX1YMg1lWJp7xV3yhBx7GyYCIQC5zr44ZzUSPnJ3Gtm6k8M1CBoIzDYWzwBIoRAdh5NE3TAKBggqhkjOPQQDAwNpADBmAjEAgyfhSQno+h3UugP0A6V0A8b++q1IV4hYm4dVfi6skZKkEYMFbs0ocMWqWlJg8PaFAjEAt7+HDiWOfa3MxLPnIdzeEPz4kbgXZqKQDMHY5m1ZG976bnJBwttMAbAEXhELfyHl","transparency_entries":[{"logIndex":"51125015","logId":{"keyId":"0y8wo8MtY5wrdiIFohx7sHeI5oKDpK5vQhGHI6G+pJY="},"kindVersion":{"kind":"dsse","version":"0.0.1"},"integratedTime":"1764880359","inclusionPromise":{"signedEntryTimestamp":"MEUCIQCiibbwwQHoLxvH9C1/P8Lve6IUoBU/6Rcs1ShGqGoyqQIgBngTOdjZiPEaBMzkNTGRDkGKDAO8FVlClua3dB+VczU="},"inclusionProof":{"logIndex":"19442603","rootHash":"WveYvRUsyPpMgj5BTpatQytFwmxXNIAtg3r3T0Erwzc=","treeSize":"19442604","hashes":["u9GSDHFTk49/HwIcxCnZ46wrLt8BhbE4ghHA15/zujs=","4+9oEq/UTGK6dNePTKcKp7D/uIuzi/1MCP3/QyYOtWg=","F8+CGCoMNj9Jb1Csuk4bxbAWW35iktydoLKPPLk6Hb8=","P6IFMwnZlp99wiunjusnNW+K5V06iOEtzfoD9MtHCSU=","V4//f/ISXnSeJjUckmcLLzwS38XjXwMjrMAw6B3hKfg=","baLnSFGPpXZDhE38YKkGPW9P35RXQTaZlgDJ2i/u5xA=","YPKEUUZB3AVufkBQm5r7wLJeJMECETlxWoHo3+sKnHE=","VEcYk6UKGgyx1fCjyU6cfCPViC8OZFBjvHz8fco4eGM=","tf738kZ3YKyYiskKppTF5etATmFZgyY6H1ktyC0leCA=","gXQKVsGeO2E9oDbviE7+SuHFG5g7UH35dYGHc9JSz8s=","6kC2DcsZfB5F/TmenKHUzDr2UH6XK//Ch6hC8PZWJ5c=","JA9P8Q8v916uA/xomSrsiXeVBiyxxQAD5Mer9MBIYzA=","BrjYsYvo65dTDWKO8aY0s+9WaWHlVdZuOEzsBHLHe8U="],"checkpoint":{"envelope":"rekor.sigstage.dev - 8202293616175992157\n19442604\nWveYvRUsyPpMgj5BTpatQytFwmxXNIAtg3r3T0Erwzc=\n\n— rekor.sigstage.dev 0y8wozBEAiBLrKviMibkIK4/qPxYL29tvR5IlL8BTQKpjRpzoORIEAIgaXw4XKDTCbaHka5VBOwwH6PuT70TIC2vxO6ukgQrVqI=\n"}},"canonicalizedBody":"eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiZHNzZSIsInNwZWMiOnsiZW52ZWxvcGVIYXNoIjp7ImFsZ29yaXRobSI6InNoYTI1NiIsInZhbHVlIjoiNjNhNzJhYjFkM2FhNWY5ZjlhMzUzMTQzNjE4NTBiZTRkMTg3NGI0OWZhODUwYmExYTY4OWM4MDIzY2UwYWFhZiJ9LCJwYXlsb2FkSGFzaCI6eyJhbGdvcml0aG0iOiJzaGEyNTYiLCJ2YWx1ZSI6ImJjNWM2OTczMDRhYTU0MmE0YTZlMjkyYmExYzg4OWRhMWVhZWE0NmJkYTlhN2JlMmI4MmY1NjIzNTUzMTNlN2UifSwic2lnbmF0dXJlcyI6W3sic2lnbmF0dXJlIjoiTUVRQ0lEekoyZWZRUy9xSG5Bd1B4KzVnV2NOSlhHNmtIbndJMmpvMXlycmxzUlhNQWlBNDg2QzBoK3pGOEY3aUNJbjAyTGJzSFpwSGdHZnhDWFkraGU2QU1aUU5IQT09IiwidmVyaWZpZXIiOiJMUzB0TFMxQ1JVZEpUaUJEUlZKVVNVWkpRMEZVUlMwdExTMHRDazFKU1VsTmVrTkRRamRwWjBGM1NVSkJaMGxWUzNKa2J6bFBaa1pLZVRaTmRWVmxkMGxsUlM5SlRGZDNMM1J6ZDBObldVbExiMXBKZW1vd1JVRjNUWGNLVG5wRlZrMUNUVWRCTVZWRlEyaE5UV015Ykc1ak0xSjJZMjFWZFZwSFZqSk5ValIzU0VGWlJGWlJVVVJGZUZaNllWZGtlbVJIT1hsYVV6RndZbTVTYkFwamJURnNXa2RzYUdSSFZYZElhR05PVFdwVmVFMXFRVEJOYWtGNlRXcE5OVmRvWTA1TmFsVjRUV3BCTUUxcVFUQk5hazAxVjJwQlFVMUdhM2RGZDFsSUNrdHZXa2w2YWpCRFFWRlpTVXR2V2tsNmFqQkVRVkZqUkZGblFVVnNaWFZpUVZOSWJtVkhPSGhSYlVvdlNHRmpabEJ3TmpOU2NFSlNZamN4YkZSVlZ6TUtkWEZqTDJSNFJuUjBRV3RKZFRFeFRIUlNOVmt4WVZKaE4yZ3ZkVVpRTm1VNVFpOHpWMEZXTVRGNGFYVXlPWFo0VW5GUFEwSjBZM2RuWjJKVVRVRTBSd3BCTVZWa1JIZEZRaTkzVVVWQmQwbElaMFJCVkVKblRsWklVMVZGUkVSQlMwSm5aM0pDWjBWR1FsRmpSRUY2UVdSQ1owNVdTRkUwUlVablVWVmpSRWgxQ25Sd1VuZ3pNVFpzVkdoeGNGSk5jSG95YTNjckwyWTBkMGgzV1VSV1VqQnFRa0puZDBadlFWVmpXVmwzY0doU09GbHRMelU1T1dJd1FsSndMMWd2TDNJS1lqWjNkMmRoVlVkQk1WVmtSVkZGUWk5M1UwSnRha05DYkRSaFFteEhhREJrU0VKNlQyazRkbG95YkRCaFNGWnBURzFPZG1KVE9YcGhWMlI2WkVjNWVRcGFVekZxWWpJMWJXSXpTblJaVnpWcVdsTTViR1ZJVW5sYVZ6RnNZa2hyZEZwSFJuVmFNbFo1WWpOV2VreFlRakZaYlhod1dYa3hkbUZYVW1wTVYwcHNDbGxYVG5aaWFUaDFXakpzTUdGSVZtbE1NMlIyWTIxMGJXSkhPVE5qZVRsc1pVaFNlVnBYTVd4aVNHdDBXa2RHZFZveVZubGlNMVo2VEZjNWNGcEhUWFFLV1cxV2FGa3lPWFZNYm14MFlrVkNlVnBYV25wTU1taHNXVmRTZWt3eU1XaGhWelIzVDFGWlMwdDNXVUpDUVVkRWRucEJRa0ZSVVhKaFNGSXdZMGhOTmdwTWVUa3dZakowYkdKcE5XaFpNMUp3WWpJMWVreHRaSEJrUjJneFdXNVdlbHBZU21waU1qVXdXbGMxTUV4dFRuWmlWRUZtUW1kdmNrSm5SVVZCV1U4dkNrMUJSVU5DUWtZellqTktjbHB0ZUhaa01UbHJZVmhPZDFsWVVtcGhSRUV5UW1kdmNrSm5SVVZCV1U4dlRVRkZSRUpEWnpOUFZGVTBUbTFOZUZwSFZtZ0tXa1JvYVU5RWFHMVpiVnBvVDFkRk0wOUVaM2xhUjBWNFRWUmFhMXBYVG0xT2FtTXdXVlJSZVUxRE1FZERhWE5IUVZGUlFtYzNPSGRCVVZGRlNEQldOQXBrU0Vwc1lsZFdjMlZUUW10WlZ6VnVXbGhLZG1SWVRXZFVNR3hGVVhsQ2FWcFhSbXBpTWpSM1UxRlpTMHQzV1VKQ1FVZEVkbnBCUWtKUlVUZGpNbXh1Q21NelVuWmpiVlYwV1RJNWRWcHRPWGxpVjBaMVdUSlZkbHBZYURCamJWWjBXbGQ0TlV4WFVtaGliV1JzWTIwNU1XTjVNWGRrVjBwellWZE5kR0l5YkdzS1dYa3hhVnBYUm1waU1qUjNTRkZaUzB0M1dVSkNRVWRFZG5wQlFrSm5VVkJqYlZadFkzazViMXBYUm10amVUbDBXVmRzZFUxRWMwZERhWE5IUVZGUlFncG5OemgzUVZGblJVeFJkM0poU0ZJd1kwaE5Oa3g1T1RCaU1uUnNZbWsxYUZrelVuQmlNalY2VEcxa2NHUkhhREZaYmxaNldsaEthbUl5TlRCYVZ6VXdDa3h0VG5aaVZFTkNjR2RaUzB0M1dVSkNRVWRFZG5wQlFrTlJVMEpzZDNsQ2JFZG9NR1JJUW5wUGFUaDJXakpzTUdGSVZtbE1iVTUyWWxNNWVtRlhaSG9LWkVjNWVWcFRNV3BpTWpWdFlqTktkRmxYTldwYVV6bHNaVWhTZVZwWE1XeGlTR3QwV2tkR2RWb3lWbmxpTTFaNlRGaENNVmx0ZUhCWmVURjJZVmRTYWdwTVYwcHNXVmRPZG1KcE9IVmFNbXd3WVVoV2FVd3paSFpqYlhSdFlrYzVNMk41T1d4bFNGSjVXbGN4YkdKSWEzUmFSMFoxV2pKV2VXSXpWbnBNVnpsd0NscEhUWFJaYlZab1dUSTVkVXh1YkhSaVJVSjVXbGRhZWt3eWFHeFpWMUo2VERJeGFHRlhOSGRQUVZsTFMzZFpRa0pCUjBSMmVrRkNRMmRSY1VSRFp6TUtUMVJWTkU1dFRYaGFSMVpvV2tSb2FVOUVhRzFaYlZwb1QxZEZNMDlFWjNsYVIwVjRUVlJhYTFwWFRtMU9hbU13V1ZSUmVVMUNNRWREYVhOSFFWRlJRZ3BuTnpoM1FWRnpSVVIzZDA1YU1td3dZVWhXYVV4WGFIWmpNMUpzV2tSQ1pVSm5iM0pDWjBWRlFWbFBMMDFCUlUxQ1JrRk5WRzFvTUdSSVFucFBhVGgyQ2xveWJEQmhTRlpwVEcxT2RtSlRPWHBoVjJSNlpFYzVlVnBUTVdwaU1qVnRZak5LZEZsWE5XcGFVemxzWlVoU2VWcFhNV3hpU0d0MFdrZEdkVm95Vm5rS1lqTldla3hZUWpGWmJYaHdXWGt4ZG1GWFVtcE1WMHBzV1ZkT2RtSnFRVFJDWjI5eVFtZEZSVUZaVHk5TlFVVk9Ra052VFV0RVl6Vk9WR2N5V1hwR2F3cGFWMFpyVDBkSk5FOUhXbWxhYlVVMVdWUmpORTlFU210WlZFVjRUbTFTYkZreVdUSk9lbEpvVGtSSmQwaDNXVXRMZDFsQ1FrRkhSSFo2UVVKRVoxRlNDa1JCT1hsYVYxcDZUREpvYkZsWFVucE1NakZvWVZjMGQwZFJXVXRMZDFsQ1FrRkhSSFo2UVVKRWQxRk1SRUZyTWsxNlNURlBWRmswVDFSamQwNTNXVXNLUzNkWlFrSkJSMFIyZWtGQ1JVRlJjRVJEWkc5a1NGSjNZM3B2ZGt3eVpIQmtSMmd4V1drMWFtSXlNSFpqTW14dVl6TlNkbU50VlhSWk1qbDFXbTA1ZVFwaVYwWjFXVEpWZDBkUldVdExkMWxDUWtGSFJIWjZRVUpGVVZGTVJFRnJlRTE2UlRSTlJGRXhUbXBOZDJkaFdVZERhWE5IUVZGUlFtYzNPSGRCVWtsRkNtZGFZMDFuV2xKdlpFaFNkMk42YjNaTU1tUndaRWRvTVZscE5XcGlNakIyWXpKc2JtTXpVblpqYlZWMFdUSTVkVnB0T1hsaVYwWjFXVEpWZGxwWWFEQUtZMjFXZEZwWGVEVk1WMUpvWW0xa2JHTnRPVEZqZVRGM1pGZEtjMkZYVFhSaU1teHJXWGt4YVZwWFJtcGlNalIyVEcxa2NHUkhhREZaYVRrellqTktjZ3BhYlhoMlpETk5kbHBZYURCamJWWjBXbGQ0TlV4WFVtaGliV1JzWTIwNU1XTjVNWFpoVjFKcVRGZEtiRmxYVG5aaWFUVTFZbGQ0UVdOdFZtMWplVGx2Q2xwWFJtdGplVGwwV1Zkc2RVMUVaMGREYVhOSFFWRlJRbWMzT0hkQlVrMUZTMmQzYjA1NmF6RlBSRnBxVFZkU2JGbFhVVFJaYW1jMFdtMUtiVmxVYkdnS1RucG5ORTF0VW1oTlZFVXlXa2RXYWxwcVdUTk9SMFV3VFdwQmFFSm5iM0pDWjBWRlFWbFBMMDFCUlZWQ1FrMU5SVmhrZG1OdGRHMWlSemt6V0RKU2NBcGpNMEpvWkVkT2IwMUpSME5DWjI5eVFtZEZSVUZaVHk5TlFVVldRa2hSVFdOdGFEQmtTRUo2VDJrNGRsb3liREJoU0ZacFRHMU9kbUpUT1hwaFYyUjZDbVJIT1hsYVV6RnFZakkxYldJelNuUlpWelZxV2xNNWJHVklVbmxhVnpGc1lraHJkRnBIUm5WYU1sWjVZak5XZWt4WVFqRlpiWGh3V1hreGRtRlhVbW9LVEZkS2JGbFhUblppYVRsb1dUTlNjR0l5TlhwTU0wb3hZbTVOZGsxVWF6Vk9SRTEzVFhwQmVFOVVhM1paV0ZJd1dsY3hkMlJJVFhaTlZFRlhRbWR2Y2dwQ1owVkZRVmxQTDAxQlJWZENRV2ROUW01Q01WbHRlSEJaZWtOQ2FXZFpTMHQzV1VKQ1FVaFhaVkZKUlVGblVqaENTRzlCWlVGQ01rRkRjM2QyVG5odkNtbE5ibWswWkdkdFMxWTFNRWd3WnpWTldsbERPSEIzZW5reE5VUlJVRFo1Y2tsYU5rRkJRVUp0ZFhOU1NERjNRVUZCVVVSQlJXTjNVbEZKWjAxcWNrSUtNVEJGZDAxVVMwRlhiV3BVVFdGaU1rRllNVmxOWnpGc1YwcHdOM2hXTTNsb1FuZzNSM2xaUTBsUlF6VjZjalEwV25wVlUxQnVTak5IZEcwMmF6aE5NUXBEUW05SmVrUlpWM3AzUWtsdlVrRmthRFZPUlROVVFVdENaMmR4YUd0cVQxQlJVVVJCZDA1d1FVUkNiVUZxUlVGbmVXWm9VMUZ1Ynl0b00xVjFaMUF3Q2tFMlZqQkJPR0lySzNFeFNWWTBhRmx0TkdSV1ptazJjMnRhUzJ0RldVMUdZbk13YjJOTlYzRlhiRXBuT0ZCaFJrRnFSVUYwTnl0SVJHbFhUMlpoTTAwS2VFeFFia2xrZW1WRlVIbzBhMkpuV0ZweFMxRkVUVWhaTlcweFdrYzVOelppYmtwQ2QzUjBUVUZpUVVWWWFFVk1abmxJYkFvdExTMHRMVVZPUkNCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2c9PSJ9XX19"}]},"envelope":{"statement":"eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjEiLCJzdWJqZWN0IjpbeyJuYW1lIjoic2hlbGZfcmVhZGVyLTAuMS1weTItbm9uZS1hbnkud2hsIiwiZGlnZXN0Ijp7InNoYTI1NiI6IjJlY2ViMTY0M2MxMGM1ZTRhNjU5NzBiYWY2M2JkZTQzYjc5Y2JkYWM3ZGU4MWRhZTg1M2NlNDdhYjA1MTk3ZTkifX1dLCJwcmVkaWNhdGVUeXBlIjoiaHR0cHM6Ly9kb2NzLnB5cGkub3JnL2F0dGVzdGF0aW9ucy9wdWJsaXNoL3YxIiwicHJlZGljYXRlIjpudWxsfQ==","signature":"MEQCIDzJ2efQS/qHnAwPx+5gWcNJXG6kHnwI2jo1yrrlsRXMAiA486C0h+zF8F7iCIn02LbsHZpHgGfxCXY+he6AMZQNHA=="}}
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes