quasarr 2.4.6__tar.gz → 2.4.8__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.

Potentially problematic release.


This version of quasarr might be problematic. Click here for more details.

Files changed (95) hide show
  1. {quasarr-2.4.6 → quasarr-2.4.8}/.github/workflows/Beta.yml +45 -1
  2. {quasarr-2.4.6 → quasarr-2.4.8}/.github/workflows/Release.yml +22 -4
  3. {quasarr-2.4.6 → quasarr-2.4.8}/PKG-INFO +3 -3
  4. {quasarr-2.4.6 → quasarr-2.4.8}/README.md +2 -2
  5. {quasarr-2.4.6 → quasarr-2.4.8}/pyproject.toml +1 -0
  6. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/__init__.py +1 -1
  7. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/api/__init__.py +5 -5
  8. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/providers/auth.py +2 -2
  9. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/providers/shared_state.py +1 -1
  10. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/providers/version.py +1 -1
  11. quasarr-2.4.6/.github/Changelog.md +0 -5
  12. {quasarr-2.4.6 → quasarr-2.4.8}/.github/FUNDING.yml +0 -0
  13. {quasarr-2.4.6 → quasarr-2.4.8}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  14. {quasarr-2.4.6 → quasarr-2.4.8}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  15. {quasarr-2.4.6 → quasarr-2.4.8}/.github/workflows/HostnameRedaction.yml +0 -0
  16. {quasarr-2.4.6 → quasarr-2.4.8}/.github/workflows/PrVersionBumpCheck.yml +0 -0
  17. {quasarr-2.4.6 → quasarr-2.4.8}/.gitignore +0 -0
  18. {quasarr-2.4.6 → quasarr-2.4.8}/LICENSE +0 -0
  19. {quasarr-2.4.6 → quasarr-2.4.8}/Quasarr.png +0 -0
  20. {quasarr-2.4.6 → quasarr-2.4.8}/Quasarr.py +0 -0
  21. {quasarr-2.4.6 → quasarr-2.4.8}/docker/Dockerfile +0 -0
  22. {quasarr-2.4.6 → quasarr-2.4.8}/docker/dev-services-compose.yml +0 -0
  23. {quasarr-2.4.6 → quasarr-2.4.8}/docker/dev-setup.md +0 -0
  24. {quasarr-2.4.6 → quasarr-2.4.8}/docker/docker-compose.yml +0 -0
  25. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/api/arr/__init__.py +0 -0
  26. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/api/captcha/__init__.py +0 -0
  27. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/api/config/__init__.py +0 -0
  28. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/api/packages/__init__.py +0 -0
  29. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/api/sponsors_helper/__init__.py +0 -0
  30. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/api/statistics/__init__.py +0 -0
  31. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/downloads/__init__.py +0 -0
  32. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/downloads/linkcrypters/__init__.py +0 -0
  33. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/downloads/linkcrypters/al.py +0 -0
  34. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/downloads/linkcrypters/filecrypt.py +0 -0
  35. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/downloads/linkcrypters/hide.py +0 -0
  36. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/downloads/packages/__init__.py +0 -0
  37. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/downloads/sources/__init__.py +0 -0
  38. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/downloads/sources/al.py +0 -0
  39. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/downloads/sources/by.py +0 -0
  40. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/downloads/sources/dd.py +0 -0
  41. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/downloads/sources/dj.py +0 -0
  42. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/downloads/sources/dl.py +0 -0
  43. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/downloads/sources/dt.py +0 -0
  44. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/downloads/sources/dw.py +0 -0
  45. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/downloads/sources/he.py +0 -0
  46. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/downloads/sources/mb.py +0 -0
  47. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/downloads/sources/nk.py +0 -0
  48. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/downloads/sources/nx.py +0 -0
  49. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/downloads/sources/sf.py +0 -0
  50. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/downloads/sources/sj.py +0 -0
  51. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/downloads/sources/sl.py +0 -0
  52. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/downloads/sources/wd.py +0 -0
  53. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/downloads/sources/wx.py +0 -0
  54. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/providers/__init__.py +0 -0
  55. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/providers/cloudflare.py +0 -0
  56. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/providers/hostname_issues.py +0 -0
  57. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/providers/html_images.py +0 -0
  58. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/providers/html_templates.py +0 -0
  59. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/providers/imdb_metadata.py +0 -0
  60. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/providers/jd_cache.py +0 -0
  61. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/providers/log.py +0 -0
  62. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/providers/myjd_api.py +0 -0
  63. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/providers/notifications.py +0 -0
  64. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/providers/obfuscated.py +0 -0
  65. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/providers/sessions/__init__.py +0 -0
  66. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/providers/sessions/al.py +0 -0
  67. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/providers/sessions/dd.py +0 -0
  68. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/providers/sessions/dl.py +0 -0
  69. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/providers/sessions/nx.py +0 -0
  70. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/providers/statistics.py +0 -0
  71. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/providers/utils.py +0 -0
  72. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/providers/web_server.py +0 -0
  73. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/search/__init__.py +0 -0
  74. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/search/sources/__init__.py +0 -0
  75. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/search/sources/al.py +0 -0
  76. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/search/sources/by.py +0 -0
  77. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/search/sources/dd.py +0 -0
  78. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/search/sources/dj.py +0 -0
  79. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/search/sources/dl.py +0 -0
  80. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/search/sources/dt.py +0 -0
  81. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/search/sources/dw.py +0 -0
  82. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/search/sources/fx.py +0 -0
  83. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/search/sources/he.py +0 -0
  84. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/search/sources/mb.py +0 -0
  85. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/search/sources/nk.py +0 -0
  86. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/search/sources/nx.py +0 -0
  87. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/search/sources/sf.py +0 -0
  88. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/search/sources/sj.py +0 -0
  89. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/search/sources/sl.py +0 -0
  90. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/search/sources/wd.py +0 -0
  91. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/search/sources/wx.py +0 -0
  92. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/storage/__init__.py +0 -0
  93. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/storage/config.py +0 -0
  94. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/storage/setup.py +0 -0
  95. {quasarr-2.4.6 → quasarr-2.4.8}/quasarr/storage/sqlite_database.py +0 -0
@@ -92,14 +92,58 @@ jobs:
92
92
 
93
93
  - name: Build exe
94
94
  run: |
95
+ uv run python -c "from PIL import Image; Image.open('Quasarr.png').save('Quasarr.ico')"
95
96
  uv run python quasarr/providers/version.py --create-version-file
96
- uv run pyinstaller --clean --onefile -y --version-file "file_version_info.txt" "Quasarr.py" -n "quasarr-${{ needs.version.outputs.version }}-standalone-win64"
97
+ uv run pyinstaller --clean --onefile -y --version-file "file_version_info.txt" --icon "Quasarr.ico" "Quasarr.py" -n "quasarr-${{ needs.version.outputs.version }}-standalone-win64"
97
98
 
98
99
  - uses: actions/upload-artifact@v4
99
100
  with:
100
101
  name: exe-amd64
101
102
  path: ./dist/*.exe
102
103
 
104
+ upload-exe-beta:
105
+ name: Upload Exe Beta
106
+ runs-on: ubuntu-latest
107
+ needs: [ version, build-exe ]
108
+ permissions:
109
+ contents: write
110
+ steps:
111
+ - uses: actions/checkout@v6
112
+ with:
113
+ fetch-depth: 0
114
+ - uses: actions/download-artifact@v4
115
+ with:
116
+ name: exe-amd64
117
+ path: ./exe-amd64
118
+ - name: Generate changelog
119
+ id: changelog
120
+ uses: metcalfc/changelog-generator@v4.6.2
121
+ with:
122
+ myToken: ${{ secrets.GITHUB_TOKEN }}
123
+ - name: Create Release Body
124
+ run: |
125
+ echo "### Install / Update:" > release_body.md
126
+ echo "" >> release_body.md
127
+ echo "\`uv tool upgrade quasarr\`" >> release_body.md
128
+ echo "" >> release_body.md
129
+ echo "### Changelog:" >> release_body.md
130
+ echo "" >> release_body.md
131
+ echo "${{ steps.changelog.outputs.changelog }}" >> release_body.md
132
+ echo "" >> release_body.md
133
+ echo "\`docker pull ${{ env.GHCR_ENDPOINT }}:beta\`" >> release_body.md
134
+ - name: Upload to Release
135
+ uses: ncipollo/release-action@v1
136
+ with:
137
+ artifacts: "./exe-amd64/*.exe"
138
+ allowUpdates: true
139
+ removeArtifacts: true
140
+ replacesArtifacts: true
141
+ tag: beta
142
+ name: Beta Build
143
+ bodyFile: "release_body.md"
144
+ prerelease: true
145
+ token: ${{ secrets.GITHUB_TOKEN }}
146
+
103
147
  build-docker-amd64:
104
148
  name: Build Docker (AMD64) :beta
105
149
  runs-on: ubuntu-latest
@@ -43,6 +43,8 @@ jobs:
43
43
  build-wheel:
44
44
  name: Build Wheel
45
45
  runs-on: ubuntu-latest
46
+ outputs:
47
+ attestation-id: ${{ steps.attest.outputs.attestation-id }}
46
48
  permissions:
47
49
  contents: read
48
50
  id-token: write
@@ -60,6 +62,7 @@ jobs:
60
62
  - name: Build wheel
61
63
  run: uv build
62
64
  - name: Generate artifact attestation
65
+ id: attest
63
66
  uses: actions/attest-build-provenance@v2
64
67
  with:
65
68
  subject-path: "dist/*.whl"
@@ -99,8 +102,9 @@ jobs:
99
102
 
100
103
  - name: Build exe
101
104
  run: |
105
+ uv run python -c "from PIL import Image; Image.open('Quasarr.png').save('Quasarr.ico')"
102
106
  uv run python quasarr/providers/version.py --create-version-file
103
- uv run pyinstaller --clean --onefile -y --version-file "file_version_info.txt" "Quasarr.py" -n "quasarr-${{ needs.version.outputs.version }}-standalone-win64"
107
+ uv run pyinstaller --clean --onefile -y --version-file "file_version_info.txt" --icon "Quasarr.ico" "Quasarr.py" -n "quasarr-${{ needs.version.outputs.version }}-standalone-win64"
104
108
 
105
109
  - uses: actions/upload-artifact@v4
106
110
  with:
@@ -246,6 +250,9 @@ jobs:
246
250
 
247
251
  - name: Install uv
248
252
  uses: astral-sh/setup-uv@v5
253
+ with:
254
+ enable-cache: true
255
+ cache-dependency-glob: "pyproject.toml"
249
256
 
250
257
  - name: Publish to PyPI
251
258
  if: ${{ !inputs.skip_pypi }}
@@ -264,13 +271,24 @@ jobs:
264
271
  if [ -n "$PR_BODY" ]; then
265
272
  echo -e "\n$PR_BODY" >> .github/Changelog.md
266
273
  fi
267
- - name: Append changelog
268
- run: echo -e "\n${{ steps.changelog.outputs.changelog }}" >> .github/Changelog.md
274
+ - name: Create Release Body
275
+ run: |
276
+ echo "### Install / Update:" > release_body.md
277
+ echo "" >> release_body.md
278
+ echo "\`uv tool upgrade quasarr\`" >> release_body.md
279
+ echo "" >> release_body.md
280
+ echo "### Changelog:" >> release_body.md
281
+ echo "" >> release_body.md
282
+ echo "${{ steps.changelog.outputs.changelog }}" >> release_body.md
283
+ echo "" >> release_body.md
284
+ echo "[Attestation](https://github.com/${{ github.repository }}/attestations/${{ needs.build-wheel.outputs.attestation-id }})" >> release_body.md
285
+ echo "" >> release_body.md
286
+ echo "\`docker pull ${{ env.GHCR_ENDPOINT }}:latest\`" >> release_body.md
269
287
 
270
288
  - name: Create Release
271
289
  uses: ncipollo/release-action@v1
272
290
  with:
273
291
  artifacts: "./wheel/*.whl,./exe-amd64/*.exe"
274
292
  artifactErrorsFailBuild: true
275
- bodyFile: ".github/Changelog.md"
293
+ bodyFile: "release_body.md"
276
294
  tag: v.${{ needs.version.outputs.version }}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: quasarr
3
- Version: 2.4.6
3
+ Version: 2.4.8
4
4
  Summary: Quasarr connects JDownloader with Radarr, Sonarr and LazyLibrarian. It also decrypts links protected by CAPTCHAs.
5
5
  Author-email: rix1337 <rix1337@users.noreply.github.com>
6
6
  License-File: LICENSE
@@ -281,7 +281,7 @@ Image access is limited to [active monthly GitHub sponsors](https://github.com/u
281
281
  3. Copy the **API Key** value
282
282
  4. Use this value for the `QUASARR_API_KEY` environment variable
283
283
 
284
- > **Note:** The API key is required for SponsorsHelper to communicate securely with Quasarr. Without it, all requests
284
+ > **Note:** The API Key is required for SponsorsHelper to communicate securely with Quasarr. Without it, all requests
285
285
  > will be rejected with a 401/403 error.
286
286
 
287
287
  ---
@@ -320,7 +320,7 @@ docker run -d \
320
320
  | Parameter | Description |
321
321
  |---------------------------------|---------------------------------------------------------------------------------------|
322
322
  | `QUASARR_URL` | Local URL of Quasarr (e.g., `http://192.168.0.1:8080`) |
323
- | `QUASARR_API_KEY` | Your Quasarr API key (found in Quasarr web UI under "API Settings") |
323
+ | `QUASARR_API_KEY` | Your Quasarr API Key (found in Quasarr web UI under "API Settings") |
324
324
  | `DEATHBYCAPTCHA_TOKEN` | [DeathByCaptcha](https://deathbycaptcha.com/register?refid=6184288242b) account token |
325
325
  | `GITHUB_TOKEN` | Classic GitHub PAT with the scopes listed above |
326
326
  | `FLARESOLVERR_URL` | Local URL of [FlareSolverr](https://github.com/FlareSolverr/FlareSolverr) |
@@ -263,7 +263,7 @@ Image access is limited to [active monthly GitHub sponsors](https://github.com/u
263
263
  3. Copy the **API Key** value
264
264
  4. Use this value for the `QUASARR_API_KEY` environment variable
265
265
 
266
- > **Note:** The API key is required for SponsorsHelper to communicate securely with Quasarr. Without it, all requests
266
+ > **Note:** The API Key is required for SponsorsHelper to communicate securely with Quasarr. Without it, all requests
267
267
  > will be rejected with a 401/403 error.
268
268
 
269
269
  ---
@@ -302,7 +302,7 @@ docker run -d \
302
302
  | Parameter | Description |
303
303
  |---------------------------------|---------------------------------------------------------------------------------------|
304
304
  | `QUASARR_URL` | Local URL of Quasarr (e.g., `http://192.168.0.1:8080`) |
305
- | `QUASARR_API_KEY` | Your Quasarr API key (found in Quasarr web UI under "API Settings") |
305
+ | `QUASARR_API_KEY` | Your Quasarr API Key (found in Quasarr web UI under "API Settings") |
306
306
  | `DEATHBYCAPTCHA_TOKEN` | [DeathByCaptcha](https://deathbycaptcha.com/register?refid=6184288242b) account token |
307
307
  | `GITHUB_TOKEN` | Classic GitHub PAT with the scopes listed above |
308
308
  | `FLARESOLVERR_URL` | Local URL of [FlareSolverr](https://github.com/FlareSolverr/FlareSolverr) |
@@ -37,4 +37,5 @@ packages = ["quasarr"]
37
37
  [dependency-groups]
38
38
  build = [
39
39
  "pyinstaller>=6.0.0",
40
+ "pillow>=12.0.0",
40
41
  ]
@@ -212,7 +212,7 @@ def run():
212
212
 
213
213
  print('Setup instructions: "https://github.com/rix1337/Quasarr?tab=readme-ov-file#instructions"')
214
214
  print(f'URL: "{shared_state.values['internal_address']}"')
215
- print(f'API key: "{api_key}" (without quotes)')
215
+ print(f'API Key: "{api_key}" (without quotes)')
216
216
 
217
217
  if external_address != internal_address:
218
218
  print(f'External URL: "{shared_state.values["external_address"]}"')
@@ -175,7 +175,7 @@ def get_api(shared_state_dict, shared_state_lock):
175
175
  </div>
176
176
 
177
177
  <p style="margin-top: 15px;">
178
- {render_button("Regenerate API key", "secondary", {"onclick": "confirmRegenerateApiKey()"})}
178
+ {render_button("Regenerate API Key", "secondary", {"onclick": "confirmRegenerateApiKey()"})}
179
179
  </p>
180
180
  </div>
181
181
  </details>
@@ -440,7 +440,7 @@ def get_api(shared_state_dict, shared_state_lock):
440
440
  if (copyKeyBtn) {{
441
441
  copyKeyBtn.onclick = function() {{
442
442
  copyToClipboard(apiInput.value, copyKeyBtn, function() {{
443
- // Re-hide the API key after copying
443
+ // Re-hide the API Key after copying
444
444
  apiInput.type = 'password';
445
445
  toggleBtn.innerText = 'Show';
446
446
  }});
@@ -462,8 +462,8 @@ def get_api(shared_state_dict, shared_state_lock):
462
462
 
463
463
  function confirmRegenerateApiKey() {{
464
464
  showModal(
465
- 'Regenerate API key?',
466
- 'Are you sure you want to regenerate the API key? This will invalidate the current key.',
465
+ 'Regenerate API Key?',
466
+ 'Are you sure you want to regenerate the API Key? This will invalidate the current key.',
467
467
  `<button class="btn-secondary" onclick="closeModal()">Cancel</button>
468
468
  <button class="btn-primary" onclick="location.href='/regenerate-api-key'">Regenerate</button>`
469
469
  );
@@ -477,6 +477,6 @@ def get_api(shared_state_dict, shared_state_lock):
477
477
  @app.get('/regenerate-api-key')
478
478
  def regenerate_api_key():
479
479
  shared_state.generate_api_key()
480
- return render_success(f'API key replaced!', 5)
480
+ return render_success(f'API Key replaced!', 5)
481
481
 
482
482
  Server(app, listen='0.0.0.0', port=shared_state.values["port"]).serve_forever()
@@ -319,9 +319,9 @@ def require_api_key(func):
319
319
  def decorated(*args, **kwargs):
320
320
  api_key = Config('API').get('key')
321
321
  if not request.query.apikey:
322
- return abort(401, "Missing API key")
322
+ return abort(401, "Missing API Key")
323
323
  if request.query.apikey != api_key:
324
- return abort(403, "Invalid API key")
324
+ return abort(403, "Invalid API Key")
325
325
  return func(*args, **kwargs)
326
326
 
327
327
  return decorated
@@ -75,7 +75,7 @@ def set_files(config_path):
75
75
  def generate_api_key():
76
76
  api_key = os.urandom(32).hex()
77
77
  Config('API').save("key", api_key)
78
- info(f'API key replaced with: "{api_key}!"')
78
+ info(f'API Key replaced with: "{api_key}!"')
79
79
  return api_key
80
80
 
81
81
 
@@ -5,7 +5,7 @@
5
5
  import re
6
6
  import sys
7
7
 
8
- __version__ = "2.4.6"
8
+ __version__ = "2.4.8"
9
9
 
10
10
 
11
11
  def get_version():
@@ -1,5 +0,0 @@
1
- ### Install / Update:
2
-
3
- `uv tool upgrade quasarr`
4
-
5
- ### Changelog:
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes