v6.8.6: desktop 1.0.4 downloads, and a roadmap without status labels
This commit is contained in:
@@ -1,5 +1,12 @@
|
||||
# Changelog
|
||||
|
||||
## v6.8.6 — Desktop 1.0.4 downloads, and a simpler roadmap
|
||||
|
||||
The download buttons now give you desktop version 1.0.4, which fetches its relay
|
||||
password from the site like the web app does. The roadmap no longer puts a label
|
||||
such as "Released" or "Planned" on each step; the timeline shows where each one
|
||||
stands on its own.
|
||||
|
||||
## v6.8.5 — The relay password is no longer built into the app
|
||||
|
||||
When two people cannot connect directly, calls and chats go through our relay
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
No accounts. No servers storing your messages. No installation required.
|
||||
|
||||
[](LICENSE)
|
||||
[](CHANGELOG.md)
|
||||
[](CHANGELOG.md)
|
||||
[](https://snapcraft.io/securebit-chat)
|
||||
[](#install-as-an-app)
|
||||
[](#security-model)
|
||||
|
||||
+19
-19
@@ -30,18 +30,18 @@
|
||||
|
||||
<!-- PWA Manifest -->
|
||||
<link rel="manifest" href="/ar/manifest.json">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790208243441">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790219928897">
|
||||
|
||||
<!-- Blocking, and above the stylesheet on purpose: this stamps data-theme on <html>
|
||||
from localStorage while the parser is still in <head>, so the page paints in the
|
||||
chosen theme on the first frame instead of flashing dark and correcting itself.
|
||||
Cannot be inline (CSP is script-src 'self') and cannot be a module (deferred). -->
|
||||
<script src="/src/scripts/theme-boot.js?v=1790208243441"></script>
|
||||
<script src="/src/scripts/theme-boot.js?v=1790219928897"></script>
|
||||
|
||||
<!-- Blocking, and in <head> on purpose: beforeinstallprompt fires once and is
|
||||
not replayed, so the listener has to exist before Chrome decides the page
|
||||
is installable. Deferred/module scripts are already too late. -->
|
||||
<script src="/src/scripts/pwa-install-capture.js?v=1790208243441"></script>
|
||||
<script src="/src/scripts/pwa-install-capture.js?v=1790219928897"></script>
|
||||
|
||||
<!-- PWA Meta Tags -->
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
@@ -116,7 +116,7 @@
|
||||
<link rel="apple-touch-startup-image" media="screen and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/logo/splash/splash_screens/8.3__iPad_Mini_portrait.png">
|
||||
|
||||
<!-- Apple Touch Icons -->
|
||||
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1790208243441">
|
||||
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1790219928897">
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="/logo/icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="/logo/icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="/logo/icon-72x72.png">
|
||||
@@ -125,7 +125,7 @@
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="/logo/icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="/logo/icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="/logo/icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1790208243441">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1790219928897">
|
||||
|
||||
<!-- Microsoft Tiles -->
|
||||
<meta name="msapplication-TileColor" content="#ff6b35">
|
||||
@@ -264,7 +264,7 @@
|
||||
<!-- Render-blocking JS is deferred: classic deferred scripts and module scripts
|
||||
both execute in document order after parsing, so React still runs before the
|
||||
app modules below, but the parser / first paint is no longer blocked. -->
|
||||
<script defer src="/config/ice-servers.js?v=1790208243441"></script>
|
||||
<script defer src="/config/ice-servers.js?v=1790219928897"></script>
|
||||
<script defer src="/libs/react/react.production.min.js"></script>
|
||||
<script defer src="/libs/react-dom/react-dom.production.min.js"></script>
|
||||
<!-- Prism syntax highlighting (vendored, offline). Tokenizes code as TEXT only —
|
||||
@@ -278,8 +278,8 @@
|
||||
the end of <body>: 21 KB of CSS in total, but eight round trips before the
|
||||
browser could paint, which GTmetrix measured at 441 ms on a throttled mobile
|
||||
connection. Bytes were never the problem; requests were. -->
|
||||
<link rel="stylesheet" href="/assets/app.css?v=1790208243441">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790208243441">
|
||||
<link rel="stylesheet" href="/assets/app.css?v=1790219928897">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790219928897">
|
||||
<!-- Preload only the fonts needed for first paint. Inter is one variable file that
|
||||
answers for every weight, so there is one to preload rather than the two of five
|
||||
copies this used to name. fa-solid covers the bulk of UI icons; fa-regular and
|
||||
@@ -287,19 +287,19 @@
|
||||
<link rel="preload" href="/assets/fontawesome/webfonts/fa-solid-900.subset.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<link rel="preload" href="/assets/fonts/inter/files/inter-latin.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<!-- Non-critical CSS (FontAwesome ~102KB, Prism) loaded async — no longer blocks paint. -->
|
||||
<script defer src="/src/scripts/load-async-css.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/load-async-css.js?v=1790219928897"></script>
|
||||
<noscript>
|
||||
<link rel="stylesheet" href="/libs/prism/prism.css">
|
||||
</noscript>
|
||||
<script defer src="/src/scripts/fa-check.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/fa-check.js?v=1790219928897"></script>
|
||||
<!-- This locale's dictionary, registered before anything can ask for a string.
|
||||
Only the default locale's is bundled (src/i18n/index.js imports it, because t()
|
||||
falls back to it); every other page loads its own here instead of all thirteen
|
||||
riding along inside dist/app.js. Absent on the default locale's own page. -->
|
||||
<script type="module" src="/src/i18n/dict/ar.js?v=1790208243441"></script>
|
||||
<script type="module" src="/src/i18n/dict/ar.js?v=1790219928897"></script>
|
||||
<!-- Update Manager - система принудительного обновления -->
|
||||
<script defer src="/src/utils/updateManager.js?v=1790208243441"></script>
|
||||
<script type="module" src="/src/components/UpdateChecker.jsx?v=1790208243441"></script>
|
||||
<script defer src="/src/utils/updateManager.js?v=1790219928897"></script>
|
||||
<script type="module" src="/src/components/UpdateChecker.jsx?v=1790219928897"></script>
|
||||
<!-- /dist/qr-local.js is deliberately absent: app-boot.js fetches it once the
|
||||
app has mounted and the browser is idle, so the 142 KB it weighs is off the
|
||||
first load. src/components/QRScanner.js used to be here too and registered
|
||||
@@ -487,12 +487,12 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="module" src="/dist/app-boot.js?v=1790208243441"></script>
|
||||
<script type="module" src="/dist/app.js?v=1790208243441"></script>
|
||||
<script type="module" src="/dist/app-boot.js?v=1790219928897"></script>
|
||||
<script type="module" src="/dist/app.js?v=1790219928897"></script>
|
||||
|
||||
<script defer src="/src/scripts/pwa-register.js?v=1790208243441"></script>
|
||||
<script src="/src/pwa/install-prompt.js?v=1790208243441" type="module"></script>
|
||||
<script src="/src/pwa/pwa-manager.js?v=1790208243441" type="module"></script>
|
||||
<script defer src="/src/scripts/pwa-offline-test.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/pwa-register.js?v=1790219928897"></script>
|
||||
<script src="/src/pwa/install-prompt.js?v=1790219928897" type="module"></script>
|
||||
<script src="/src/pwa/pwa-manager.js?v=1790219928897" type="module"></script>
|
||||
<script defer src="/src/scripts/pwa-offline-test.js?v=1790219928897"></script>
|
||||
</body>
|
||||
</html>
|
||||
+19
-19
@@ -30,18 +30,18 @@
|
||||
|
||||
<!-- PWA Manifest -->
|
||||
<link rel="manifest" href="/de/manifest.json">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790208243441">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790219928897">
|
||||
|
||||
<!-- Blocking, and above the stylesheet on purpose: this stamps data-theme on <html>
|
||||
from localStorage while the parser is still in <head>, so the page paints in the
|
||||
chosen theme on the first frame instead of flashing dark and correcting itself.
|
||||
Cannot be inline (CSP is script-src 'self') and cannot be a module (deferred). -->
|
||||
<script src="/src/scripts/theme-boot.js?v=1790208243441"></script>
|
||||
<script src="/src/scripts/theme-boot.js?v=1790219928897"></script>
|
||||
|
||||
<!-- Blocking, and in <head> on purpose: beforeinstallprompt fires once and is
|
||||
not replayed, so the listener has to exist before Chrome decides the page
|
||||
is installable. Deferred/module scripts are already too late. -->
|
||||
<script src="/src/scripts/pwa-install-capture.js?v=1790208243441"></script>
|
||||
<script src="/src/scripts/pwa-install-capture.js?v=1790219928897"></script>
|
||||
|
||||
<!-- PWA Meta Tags -->
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
@@ -116,7 +116,7 @@
|
||||
<link rel="apple-touch-startup-image" media="screen and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/logo/splash/splash_screens/8.3__iPad_Mini_portrait.png">
|
||||
|
||||
<!-- Apple Touch Icons -->
|
||||
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1790208243441">
|
||||
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1790219928897">
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="/logo/icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="/logo/icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="/logo/icon-72x72.png">
|
||||
@@ -125,7 +125,7 @@
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="/logo/icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="/logo/icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="/logo/icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1790208243441">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1790219928897">
|
||||
|
||||
<!-- Microsoft Tiles -->
|
||||
<meta name="msapplication-TileColor" content="#ff6b35">
|
||||
@@ -264,7 +264,7 @@
|
||||
<!-- Render-blocking JS is deferred: classic deferred scripts and module scripts
|
||||
both execute in document order after parsing, so React still runs before the
|
||||
app modules below, but the parser / first paint is no longer blocked. -->
|
||||
<script defer src="/config/ice-servers.js?v=1790208243441"></script>
|
||||
<script defer src="/config/ice-servers.js?v=1790219928897"></script>
|
||||
<script defer src="/libs/react/react.production.min.js"></script>
|
||||
<script defer src="/libs/react-dom/react-dom.production.min.js"></script>
|
||||
<!-- Prism syntax highlighting (vendored, offline). Tokenizes code as TEXT only —
|
||||
@@ -278,8 +278,8 @@
|
||||
the end of <body>: 21 KB of CSS in total, but eight round trips before the
|
||||
browser could paint, which GTmetrix measured at 441 ms on a throttled mobile
|
||||
connection. Bytes were never the problem; requests were. -->
|
||||
<link rel="stylesheet" href="/assets/app.css?v=1790208243441">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790208243441">
|
||||
<link rel="stylesheet" href="/assets/app.css?v=1790219928897">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790219928897">
|
||||
<!-- Preload only the fonts needed for first paint. Inter is one variable file that
|
||||
answers for every weight, so there is one to preload rather than the two of five
|
||||
copies this used to name. fa-solid covers the bulk of UI icons; fa-regular and
|
||||
@@ -287,19 +287,19 @@
|
||||
<link rel="preload" href="/assets/fontawesome/webfonts/fa-solid-900.subset.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<link rel="preload" href="/assets/fonts/inter/files/inter-latin.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<!-- Non-critical CSS (FontAwesome ~102KB, Prism) loaded async — no longer blocks paint. -->
|
||||
<script defer src="/src/scripts/load-async-css.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/load-async-css.js?v=1790219928897"></script>
|
||||
<noscript>
|
||||
<link rel="stylesheet" href="/libs/prism/prism.css">
|
||||
</noscript>
|
||||
<script defer src="/src/scripts/fa-check.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/fa-check.js?v=1790219928897"></script>
|
||||
<!-- This locale's dictionary, registered before anything can ask for a string.
|
||||
Only the default locale's is bundled (src/i18n/index.js imports it, because t()
|
||||
falls back to it); every other page loads its own here instead of all thirteen
|
||||
riding along inside dist/app.js. Absent on the default locale's own page. -->
|
||||
<script type="module" src="/src/i18n/dict/de.js?v=1790208243441"></script>
|
||||
<script type="module" src="/src/i18n/dict/de.js?v=1790219928897"></script>
|
||||
<!-- Update Manager - система принудительного обновления -->
|
||||
<script defer src="/src/utils/updateManager.js?v=1790208243441"></script>
|
||||
<script type="module" src="/src/components/UpdateChecker.jsx?v=1790208243441"></script>
|
||||
<script defer src="/src/utils/updateManager.js?v=1790219928897"></script>
|
||||
<script type="module" src="/src/components/UpdateChecker.jsx?v=1790219928897"></script>
|
||||
<!-- /dist/qr-local.js is deliberately absent: app-boot.js fetches it once the
|
||||
app has mounted and the browser is idle, so the 142 KB it weighs is off the
|
||||
first load. src/components/QRScanner.js used to be here too and registered
|
||||
@@ -487,12 +487,12 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="module" src="/dist/app-boot.js?v=1790208243441"></script>
|
||||
<script type="module" src="/dist/app.js?v=1790208243441"></script>
|
||||
<script type="module" src="/dist/app-boot.js?v=1790219928897"></script>
|
||||
<script type="module" src="/dist/app.js?v=1790219928897"></script>
|
||||
|
||||
<script defer src="/src/scripts/pwa-register.js?v=1790208243441"></script>
|
||||
<script src="/src/pwa/install-prompt.js?v=1790208243441" type="module"></script>
|
||||
<script src="/src/pwa/pwa-manager.js?v=1790208243441" type="module"></script>
|
||||
<script defer src="/src/scripts/pwa-offline-test.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/pwa-register.js?v=1790219928897"></script>
|
||||
<script src="/src/pwa/install-prompt.js?v=1790219928897" type="module"></script>
|
||||
<script src="/src/pwa/pwa-manager.js?v=1790219928897" type="module"></script>
|
||||
<script defer src="/src/scripts/pwa-offline-test.js?v=1790219928897"></script>
|
||||
</body>
|
||||
</html>
|
||||
Vendored
+38
-38
File diff suppressed because one or more lines are too long
Vendored
+3
-3
File diff suppressed because one or more lines are too long
Vendored
+2
-2
File diff suppressed because one or more lines are too long
Vendored
+2
-2
File diff suppressed because one or more lines are too long
+2
-2
@@ -7,7 +7,7 @@ this document describes.
|
||||
|
||||
| | |
|
||||
| --- | --- |
|
||||
| Release | v6.8.5 |
|
||||
| Release | v6.8.6 |
|
||||
| Protocol version | 4.1 |
|
||||
| Ratchet wire version | 1 |
|
||||
|
||||
@@ -347,5 +347,5 @@ no leg may stop a capture it borrowed.
|
||||
|
||||
## Scope
|
||||
|
||||
This describes the browser implementation as it stands in v6.8.5. It is not a
|
||||
This describes the browser implementation as it stands in v6.8.6. It is not a
|
||||
substitute for independent cryptographic review.
|
||||
|
||||
@@ -153,7 +153,7 @@
|
||||
</thead>
|
||||
<tbody><tr>
|
||||
<td>Release</td>
|
||||
<td>v6.8.5</td>
|
||||
<td>v6.8.6</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Protocol version</td>
|
||||
@@ -486,7 +486,7 @@
|
||||
shared across every leg, and stopped when the call, the group or the tab ends;
|
||||
no leg may stop a capture it borrowed.</p>
|
||||
<h2 id="scope">Scope</h2>
|
||||
<p>This describes the browser implementation as it stands in v6.8.5. It is not a
|
||||
<p>This describes the browser implementation as it stands in v6.8.6. It is not a
|
||||
substitute for independent cryptographic review.</p>
|
||||
|
||||
<nav class="more">
|
||||
|
||||
+19
-19
@@ -30,18 +30,18 @@
|
||||
|
||||
<!-- PWA Manifest -->
|
||||
<link rel="manifest" href="/es/manifest.json">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790208243441">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790219928897">
|
||||
|
||||
<!-- Blocking, and above the stylesheet on purpose: this stamps data-theme on <html>
|
||||
from localStorage while the parser is still in <head>, so the page paints in the
|
||||
chosen theme on the first frame instead of flashing dark and correcting itself.
|
||||
Cannot be inline (CSP is script-src 'self') and cannot be a module (deferred). -->
|
||||
<script src="/src/scripts/theme-boot.js?v=1790208243441"></script>
|
||||
<script src="/src/scripts/theme-boot.js?v=1790219928897"></script>
|
||||
|
||||
<!-- Blocking, and in <head> on purpose: beforeinstallprompt fires once and is
|
||||
not replayed, so the listener has to exist before Chrome decides the page
|
||||
is installable. Deferred/module scripts are already too late. -->
|
||||
<script src="/src/scripts/pwa-install-capture.js?v=1790208243441"></script>
|
||||
<script src="/src/scripts/pwa-install-capture.js?v=1790219928897"></script>
|
||||
|
||||
<!-- PWA Meta Tags -->
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
@@ -116,7 +116,7 @@
|
||||
<link rel="apple-touch-startup-image" media="screen and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/logo/splash/splash_screens/8.3__iPad_Mini_portrait.png">
|
||||
|
||||
<!-- Apple Touch Icons -->
|
||||
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1790208243441">
|
||||
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1790219928897">
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="/logo/icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="/logo/icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="/logo/icon-72x72.png">
|
||||
@@ -125,7 +125,7 @@
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="/logo/icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="/logo/icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="/logo/icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1790208243441">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1790219928897">
|
||||
|
||||
<!-- Microsoft Tiles -->
|
||||
<meta name="msapplication-TileColor" content="#ff6b35">
|
||||
@@ -264,7 +264,7 @@
|
||||
<!-- Render-blocking JS is deferred: classic deferred scripts and module scripts
|
||||
both execute in document order after parsing, so React still runs before the
|
||||
app modules below, but the parser / first paint is no longer blocked. -->
|
||||
<script defer src="/config/ice-servers.js?v=1790208243441"></script>
|
||||
<script defer src="/config/ice-servers.js?v=1790219928897"></script>
|
||||
<script defer src="/libs/react/react.production.min.js"></script>
|
||||
<script defer src="/libs/react-dom/react-dom.production.min.js"></script>
|
||||
<!-- Prism syntax highlighting (vendored, offline). Tokenizes code as TEXT only —
|
||||
@@ -278,8 +278,8 @@
|
||||
the end of <body>: 21 KB of CSS in total, but eight round trips before the
|
||||
browser could paint, which GTmetrix measured at 441 ms on a throttled mobile
|
||||
connection. Bytes were never the problem; requests were. -->
|
||||
<link rel="stylesheet" href="/assets/app.css?v=1790208243441">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790208243441">
|
||||
<link rel="stylesheet" href="/assets/app.css?v=1790219928897">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790219928897">
|
||||
<!-- Preload only the fonts needed for first paint. Inter is one variable file that
|
||||
answers for every weight, so there is one to preload rather than the two of five
|
||||
copies this used to name. fa-solid covers the bulk of UI icons; fa-regular and
|
||||
@@ -287,19 +287,19 @@
|
||||
<link rel="preload" href="/assets/fontawesome/webfonts/fa-solid-900.subset.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<link rel="preload" href="/assets/fonts/inter/files/inter-latin.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<!-- Non-critical CSS (FontAwesome ~102KB, Prism) loaded async — no longer blocks paint. -->
|
||||
<script defer src="/src/scripts/load-async-css.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/load-async-css.js?v=1790219928897"></script>
|
||||
<noscript>
|
||||
<link rel="stylesheet" href="/libs/prism/prism.css">
|
||||
</noscript>
|
||||
<script defer src="/src/scripts/fa-check.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/fa-check.js?v=1790219928897"></script>
|
||||
<!-- This locale's dictionary, registered before anything can ask for a string.
|
||||
Only the default locale's is bundled (src/i18n/index.js imports it, because t()
|
||||
falls back to it); every other page loads its own here instead of all thirteen
|
||||
riding along inside dist/app.js. Absent on the default locale's own page. -->
|
||||
<script type="module" src="/src/i18n/dict/es.js?v=1790208243441"></script>
|
||||
<script type="module" src="/src/i18n/dict/es.js?v=1790219928897"></script>
|
||||
<!-- Update Manager - система принудительного обновления -->
|
||||
<script defer src="/src/utils/updateManager.js?v=1790208243441"></script>
|
||||
<script type="module" src="/src/components/UpdateChecker.jsx?v=1790208243441"></script>
|
||||
<script defer src="/src/utils/updateManager.js?v=1790219928897"></script>
|
||||
<script type="module" src="/src/components/UpdateChecker.jsx?v=1790219928897"></script>
|
||||
<!-- /dist/qr-local.js is deliberately absent: app-boot.js fetches it once the
|
||||
app has mounted and the browser is idle, so the 142 KB it weighs is off the
|
||||
first load. src/components/QRScanner.js used to be here too and registered
|
||||
@@ -487,12 +487,12 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="module" src="/dist/app-boot.js?v=1790208243441"></script>
|
||||
<script type="module" src="/dist/app.js?v=1790208243441"></script>
|
||||
<script type="module" src="/dist/app-boot.js?v=1790219928897"></script>
|
||||
<script type="module" src="/dist/app.js?v=1790219928897"></script>
|
||||
|
||||
<script defer src="/src/scripts/pwa-register.js?v=1790208243441"></script>
|
||||
<script src="/src/pwa/install-prompt.js?v=1790208243441" type="module"></script>
|
||||
<script src="/src/pwa/pwa-manager.js?v=1790208243441" type="module"></script>
|
||||
<script defer src="/src/scripts/pwa-offline-test.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/pwa-register.js?v=1790219928897"></script>
|
||||
<script src="/src/pwa/install-prompt.js?v=1790219928897" type="module"></script>
|
||||
<script src="/src/pwa/pwa-manager.js?v=1790219928897" type="module"></script>
|
||||
<script defer src="/src/scripts/pwa-offline-test.js?v=1790219928897"></script>
|
||||
</body>
|
||||
</html>
|
||||
+19
-19
@@ -30,18 +30,18 @@
|
||||
|
||||
<!-- PWA Manifest -->
|
||||
<link rel="manifest" href="/fa/manifest.json">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790208243441">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790219928897">
|
||||
|
||||
<!-- Blocking, and above the stylesheet on purpose: this stamps data-theme on <html>
|
||||
from localStorage while the parser is still in <head>, so the page paints in the
|
||||
chosen theme on the first frame instead of flashing dark and correcting itself.
|
||||
Cannot be inline (CSP is script-src 'self') and cannot be a module (deferred). -->
|
||||
<script src="/src/scripts/theme-boot.js?v=1790208243441"></script>
|
||||
<script src="/src/scripts/theme-boot.js?v=1790219928897"></script>
|
||||
|
||||
<!-- Blocking, and in <head> on purpose: beforeinstallprompt fires once and is
|
||||
not replayed, so the listener has to exist before Chrome decides the page
|
||||
is installable. Deferred/module scripts are already too late. -->
|
||||
<script src="/src/scripts/pwa-install-capture.js?v=1790208243441"></script>
|
||||
<script src="/src/scripts/pwa-install-capture.js?v=1790219928897"></script>
|
||||
|
||||
<!-- PWA Meta Tags -->
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
@@ -116,7 +116,7 @@
|
||||
<link rel="apple-touch-startup-image" media="screen and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/logo/splash/splash_screens/8.3__iPad_Mini_portrait.png">
|
||||
|
||||
<!-- Apple Touch Icons -->
|
||||
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1790208243441">
|
||||
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1790219928897">
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="/logo/icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="/logo/icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="/logo/icon-72x72.png">
|
||||
@@ -125,7 +125,7 @@
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="/logo/icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="/logo/icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="/logo/icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1790208243441">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1790219928897">
|
||||
|
||||
<!-- Microsoft Tiles -->
|
||||
<meta name="msapplication-TileColor" content="#ff6b35">
|
||||
@@ -264,7 +264,7 @@
|
||||
<!-- Render-blocking JS is deferred: classic deferred scripts and module scripts
|
||||
both execute in document order after parsing, so React still runs before the
|
||||
app modules below, but the parser / first paint is no longer blocked. -->
|
||||
<script defer src="/config/ice-servers.js?v=1790208243441"></script>
|
||||
<script defer src="/config/ice-servers.js?v=1790219928897"></script>
|
||||
<script defer src="/libs/react/react.production.min.js"></script>
|
||||
<script defer src="/libs/react-dom/react-dom.production.min.js"></script>
|
||||
<!-- Prism syntax highlighting (vendored, offline). Tokenizes code as TEXT only —
|
||||
@@ -278,8 +278,8 @@
|
||||
the end of <body>: 21 KB of CSS in total, but eight round trips before the
|
||||
browser could paint, which GTmetrix measured at 441 ms on a throttled mobile
|
||||
connection. Bytes were never the problem; requests were. -->
|
||||
<link rel="stylesheet" href="/assets/app.css?v=1790208243441">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790208243441">
|
||||
<link rel="stylesheet" href="/assets/app.css?v=1790219928897">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790219928897">
|
||||
<!-- Preload only the fonts needed for first paint. Inter is one variable file that
|
||||
answers for every weight, so there is one to preload rather than the two of five
|
||||
copies this used to name. fa-solid covers the bulk of UI icons; fa-regular and
|
||||
@@ -287,19 +287,19 @@
|
||||
<link rel="preload" href="/assets/fontawesome/webfonts/fa-solid-900.subset.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<link rel="preload" href="/assets/fonts/inter/files/inter-latin.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<!-- Non-critical CSS (FontAwesome ~102KB, Prism) loaded async — no longer blocks paint. -->
|
||||
<script defer src="/src/scripts/load-async-css.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/load-async-css.js?v=1790219928897"></script>
|
||||
<noscript>
|
||||
<link rel="stylesheet" href="/libs/prism/prism.css">
|
||||
</noscript>
|
||||
<script defer src="/src/scripts/fa-check.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/fa-check.js?v=1790219928897"></script>
|
||||
<!-- This locale's dictionary, registered before anything can ask for a string.
|
||||
Only the default locale's is bundled (src/i18n/index.js imports it, because t()
|
||||
falls back to it); every other page loads its own here instead of all thirteen
|
||||
riding along inside dist/app.js. Absent on the default locale's own page. -->
|
||||
<script type="module" src="/src/i18n/dict/fa.js?v=1790208243441"></script>
|
||||
<script type="module" src="/src/i18n/dict/fa.js?v=1790219928897"></script>
|
||||
<!-- Update Manager - система принудительного обновления -->
|
||||
<script defer src="/src/utils/updateManager.js?v=1790208243441"></script>
|
||||
<script type="module" src="/src/components/UpdateChecker.jsx?v=1790208243441"></script>
|
||||
<script defer src="/src/utils/updateManager.js?v=1790219928897"></script>
|
||||
<script type="module" src="/src/components/UpdateChecker.jsx?v=1790219928897"></script>
|
||||
<!-- /dist/qr-local.js is deliberately absent: app-boot.js fetches it once the
|
||||
app has mounted and the browser is idle, so the 142 KB it weighs is off the
|
||||
first load. src/components/QRScanner.js used to be here too and registered
|
||||
@@ -487,12 +487,12 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="module" src="/dist/app-boot.js?v=1790208243441"></script>
|
||||
<script type="module" src="/dist/app.js?v=1790208243441"></script>
|
||||
<script type="module" src="/dist/app-boot.js?v=1790219928897"></script>
|
||||
<script type="module" src="/dist/app.js?v=1790219928897"></script>
|
||||
|
||||
<script defer src="/src/scripts/pwa-register.js?v=1790208243441"></script>
|
||||
<script src="/src/pwa/install-prompt.js?v=1790208243441" type="module"></script>
|
||||
<script src="/src/pwa/pwa-manager.js?v=1790208243441" type="module"></script>
|
||||
<script defer src="/src/scripts/pwa-offline-test.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/pwa-register.js?v=1790219928897"></script>
|
||||
<script src="/src/pwa/install-prompt.js?v=1790219928897" type="module"></script>
|
||||
<script src="/src/pwa/pwa-manager.js?v=1790219928897" type="module"></script>
|
||||
<script defer src="/src/scripts/pwa-offline-test.js?v=1790219928897"></script>
|
||||
</body>
|
||||
</html>
|
||||
+19
-19
@@ -30,18 +30,18 @@
|
||||
|
||||
<!-- PWA Manifest -->
|
||||
<link rel="manifest" href="/fr/manifest.json">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790208243441">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790219928897">
|
||||
|
||||
<!-- Blocking, and above the stylesheet on purpose: this stamps data-theme on <html>
|
||||
from localStorage while the parser is still in <head>, so the page paints in the
|
||||
chosen theme on the first frame instead of flashing dark and correcting itself.
|
||||
Cannot be inline (CSP is script-src 'self') and cannot be a module (deferred). -->
|
||||
<script src="/src/scripts/theme-boot.js?v=1790208243441"></script>
|
||||
<script src="/src/scripts/theme-boot.js?v=1790219928897"></script>
|
||||
|
||||
<!-- Blocking, and in <head> on purpose: beforeinstallprompt fires once and is
|
||||
not replayed, so the listener has to exist before Chrome decides the page
|
||||
is installable. Deferred/module scripts are already too late. -->
|
||||
<script src="/src/scripts/pwa-install-capture.js?v=1790208243441"></script>
|
||||
<script src="/src/scripts/pwa-install-capture.js?v=1790219928897"></script>
|
||||
|
||||
<!-- PWA Meta Tags -->
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
@@ -116,7 +116,7 @@
|
||||
<link rel="apple-touch-startup-image" media="screen and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/logo/splash/splash_screens/8.3__iPad_Mini_portrait.png">
|
||||
|
||||
<!-- Apple Touch Icons -->
|
||||
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1790208243441">
|
||||
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1790219928897">
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="/logo/icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="/logo/icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="/logo/icon-72x72.png">
|
||||
@@ -125,7 +125,7 @@
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="/logo/icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="/logo/icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="/logo/icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1790208243441">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1790219928897">
|
||||
|
||||
<!-- Microsoft Tiles -->
|
||||
<meta name="msapplication-TileColor" content="#ff6b35">
|
||||
@@ -264,7 +264,7 @@
|
||||
<!-- Render-blocking JS is deferred: classic deferred scripts and module scripts
|
||||
both execute in document order after parsing, so React still runs before the
|
||||
app modules below, but the parser / first paint is no longer blocked. -->
|
||||
<script defer src="/config/ice-servers.js?v=1790208243441"></script>
|
||||
<script defer src="/config/ice-servers.js?v=1790219928897"></script>
|
||||
<script defer src="/libs/react/react.production.min.js"></script>
|
||||
<script defer src="/libs/react-dom/react-dom.production.min.js"></script>
|
||||
<!-- Prism syntax highlighting (vendored, offline). Tokenizes code as TEXT only —
|
||||
@@ -278,8 +278,8 @@
|
||||
the end of <body>: 21 KB of CSS in total, but eight round trips before the
|
||||
browser could paint, which GTmetrix measured at 441 ms on a throttled mobile
|
||||
connection. Bytes were never the problem; requests were. -->
|
||||
<link rel="stylesheet" href="/assets/app.css?v=1790208243441">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790208243441">
|
||||
<link rel="stylesheet" href="/assets/app.css?v=1790219928897">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790219928897">
|
||||
<!-- Preload only the fonts needed for first paint. Inter is one variable file that
|
||||
answers for every weight, so there is one to preload rather than the two of five
|
||||
copies this used to name. fa-solid covers the bulk of UI icons; fa-regular and
|
||||
@@ -287,19 +287,19 @@
|
||||
<link rel="preload" href="/assets/fontawesome/webfonts/fa-solid-900.subset.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<link rel="preload" href="/assets/fonts/inter/files/inter-latin.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<!-- Non-critical CSS (FontAwesome ~102KB, Prism) loaded async — no longer blocks paint. -->
|
||||
<script defer src="/src/scripts/load-async-css.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/load-async-css.js?v=1790219928897"></script>
|
||||
<noscript>
|
||||
<link rel="stylesheet" href="/libs/prism/prism.css">
|
||||
</noscript>
|
||||
<script defer src="/src/scripts/fa-check.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/fa-check.js?v=1790219928897"></script>
|
||||
<!-- This locale's dictionary, registered before anything can ask for a string.
|
||||
Only the default locale's is bundled (src/i18n/index.js imports it, because t()
|
||||
falls back to it); every other page loads its own here instead of all thirteen
|
||||
riding along inside dist/app.js. Absent on the default locale's own page. -->
|
||||
<script type="module" src="/src/i18n/dict/fr.js?v=1790208243441"></script>
|
||||
<script type="module" src="/src/i18n/dict/fr.js?v=1790219928897"></script>
|
||||
<!-- Update Manager - система принудительного обновления -->
|
||||
<script defer src="/src/utils/updateManager.js?v=1790208243441"></script>
|
||||
<script type="module" src="/src/components/UpdateChecker.jsx?v=1790208243441"></script>
|
||||
<script defer src="/src/utils/updateManager.js?v=1790219928897"></script>
|
||||
<script type="module" src="/src/components/UpdateChecker.jsx?v=1790219928897"></script>
|
||||
<!-- /dist/qr-local.js is deliberately absent: app-boot.js fetches it once the
|
||||
app has mounted and the browser is idle, so the 142 KB it weighs is off the
|
||||
first load. src/components/QRScanner.js used to be here too and registered
|
||||
@@ -487,12 +487,12 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="module" src="/dist/app-boot.js?v=1790208243441"></script>
|
||||
<script type="module" src="/dist/app.js?v=1790208243441"></script>
|
||||
<script type="module" src="/dist/app-boot.js?v=1790219928897"></script>
|
||||
<script type="module" src="/dist/app.js?v=1790219928897"></script>
|
||||
|
||||
<script defer src="/src/scripts/pwa-register.js?v=1790208243441"></script>
|
||||
<script src="/src/pwa/install-prompt.js?v=1790208243441" type="module"></script>
|
||||
<script src="/src/pwa/pwa-manager.js?v=1790208243441" type="module"></script>
|
||||
<script defer src="/src/scripts/pwa-offline-test.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/pwa-register.js?v=1790219928897"></script>
|
||||
<script src="/src/pwa/install-prompt.js?v=1790219928897" type="module"></script>
|
||||
<script src="/src/pwa/pwa-manager.js?v=1790219928897" type="module"></script>
|
||||
<script defer src="/src/scripts/pwa-offline-test.js?v=1790219928897"></script>
|
||||
</body>
|
||||
</html>
|
||||
+19
-19
@@ -30,18 +30,18 @@
|
||||
|
||||
<!-- PWA Manifest -->
|
||||
<link rel="manifest" href="/he/manifest.json">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790208243441">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790219928897">
|
||||
|
||||
<!-- Blocking, and above the stylesheet on purpose: this stamps data-theme on <html>
|
||||
from localStorage while the parser is still in <head>, so the page paints in the
|
||||
chosen theme on the first frame instead of flashing dark and correcting itself.
|
||||
Cannot be inline (CSP is script-src 'self') and cannot be a module (deferred). -->
|
||||
<script src="/src/scripts/theme-boot.js?v=1790208243441"></script>
|
||||
<script src="/src/scripts/theme-boot.js?v=1790219928897"></script>
|
||||
|
||||
<!-- Blocking, and in <head> on purpose: beforeinstallprompt fires once and is
|
||||
not replayed, so the listener has to exist before Chrome decides the page
|
||||
is installable. Deferred/module scripts are already too late. -->
|
||||
<script src="/src/scripts/pwa-install-capture.js?v=1790208243441"></script>
|
||||
<script src="/src/scripts/pwa-install-capture.js?v=1790219928897"></script>
|
||||
|
||||
<!-- PWA Meta Tags -->
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
@@ -116,7 +116,7 @@
|
||||
<link rel="apple-touch-startup-image" media="screen and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/logo/splash/splash_screens/8.3__iPad_Mini_portrait.png">
|
||||
|
||||
<!-- Apple Touch Icons -->
|
||||
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1790208243441">
|
||||
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1790219928897">
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="/logo/icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="/logo/icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="/logo/icon-72x72.png">
|
||||
@@ -125,7 +125,7 @@
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="/logo/icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="/logo/icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="/logo/icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1790208243441">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1790219928897">
|
||||
|
||||
<!-- Microsoft Tiles -->
|
||||
<meta name="msapplication-TileColor" content="#ff6b35">
|
||||
@@ -264,7 +264,7 @@
|
||||
<!-- Render-blocking JS is deferred: classic deferred scripts and module scripts
|
||||
both execute in document order after parsing, so React still runs before the
|
||||
app modules below, but the parser / first paint is no longer blocked. -->
|
||||
<script defer src="/config/ice-servers.js?v=1790208243441"></script>
|
||||
<script defer src="/config/ice-servers.js?v=1790219928897"></script>
|
||||
<script defer src="/libs/react/react.production.min.js"></script>
|
||||
<script defer src="/libs/react-dom/react-dom.production.min.js"></script>
|
||||
<!-- Prism syntax highlighting (vendored, offline). Tokenizes code as TEXT only —
|
||||
@@ -278,8 +278,8 @@
|
||||
the end of <body>: 21 KB of CSS in total, but eight round trips before the
|
||||
browser could paint, which GTmetrix measured at 441 ms on a throttled mobile
|
||||
connection. Bytes were never the problem; requests were. -->
|
||||
<link rel="stylesheet" href="/assets/app.css?v=1790208243441">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790208243441">
|
||||
<link rel="stylesheet" href="/assets/app.css?v=1790219928897">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790219928897">
|
||||
<!-- Preload only the fonts needed for first paint. Inter is one variable file that
|
||||
answers for every weight, so there is one to preload rather than the two of five
|
||||
copies this used to name. fa-solid covers the bulk of UI icons; fa-regular and
|
||||
@@ -287,19 +287,19 @@
|
||||
<link rel="preload" href="/assets/fontawesome/webfonts/fa-solid-900.subset.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<link rel="preload" href="/assets/fonts/inter/files/inter-latin.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<!-- Non-critical CSS (FontAwesome ~102KB, Prism) loaded async — no longer blocks paint. -->
|
||||
<script defer src="/src/scripts/load-async-css.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/load-async-css.js?v=1790219928897"></script>
|
||||
<noscript>
|
||||
<link rel="stylesheet" href="/libs/prism/prism.css">
|
||||
</noscript>
|
||||
<script defer src="/src/scripts/fa-check.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/fa-check.js?v=1790219928897"></script>
|
||||
<!-- This locale's dictionary, registered before anything can ask for a string.
|
||||
Only the default locale's is bundled (src/i18n/index.js imports it, because t()
|
||||
falls back to it); every other page loads its own here instead of all thirteen
|
||||
riding along inside dist/app.js. Absent on the default locale's own page. -->
|
||||
<script type="module" src="/src/i18n/dict/he.js?v=1790208243441"></script>
|
||||
<script type="module" src="/src/i18n/dict/he.js?v=1790219928897"></script>
|
||||
<!-- Update Manager - система принудительного обновления -->
|
||||
<script defer src="/src/utils/updateManager.js?v=1790208243441"></script>
|
||||
<script type="module" src="/src/components/UpdateChecker.jsx?v=1790208243441"></script>
|
||||
<script defer src="/src/utils/updateManager.js?v=1790219928897"></script>
|
||||
<script type="module" src="/src/components/UpdateChecker.jsx?v=1790219928897"></script>
|
||||
<!-- /dist/qr-local.js is deliberately absent: app-boot.js fetches it once the
|
||||
app has mounted and the browser is idle, so the 142 KB it weighs is off the
|
||||
first load. src/components/QRScanner.js used to be here too and registered
|
||||
@@ -487,12 +487,12 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="module" src="/dist/app-boot.js?v=1790208243441"></script>
|
||||
<script type="module" src="/dist/app.js?v=1790208243441"></script>
|
||||
<script type="module" src="/dist/app-boot.js?v=1790219928897"></script>
|
||||
<script type="module" src="/dist/app.js?v=1790219928897"></script>
|
||||
|
||||
<script defer src="/src/scripts/pwa-register.js?v=1790208243441"></script>
|
||||
<script src="/src/pwa/install-prompt.js?v=1790208243441" type="module"></script>
|
||||
<script src="/src/pwa/pwa-manager.js?v=1790208243441" type="module"></script>
|
||||
<script defer src="/src/scripts/pwa-offline-test.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/pwa-register.js?v=1790219928897"></script>
|
||||
<script src="/src/pwa/install-prompt.js?v=1790219928897" type="module"></script>
|
||||
<script src="/src/pwa/pwa-manager.js?v=1790219928897" type="module"></script>
|
||||
<script defer src="/src/scripts/pwa-offline-test.js?v=1790219928897"></script>
|
||||
</body>
|
||||
</html>
|
||||
+19
-19
@@ -30,18 +30,18 @@
|
||||
|
||||
<!-- PWA Manifest -->
|
||||
<link rel="manifest" href="/hi/manifest.json">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790208243441">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790219928897">
|
||||
|
||||
<!-- Blocking, and above the stylesheet on purpose: this stamps data-theme on <html>
|
||||
from localStorage while the parser is still in <head>, so the page paints in the
|
||||
chosen theme on the first frame instead of flashing dark and correcting itself.
|
||||
Cannot be inline (CSP is script-src 'self') and cannot be a module (deferred). -->
|
||||
<script src="/src/scripts/theme-boot.js?v=1790208243441"></script>
|
||||
<script src="/src/scripts/theme-boot.js?v=1790219928897"></script>
|
||||
|
||||
<!-- Blocking, and in <head> on purpose: beforeinstallprompt fires once and is
|
||||
not replayed, so the listener has to exist before Chrome decides the page
|
||||
is installable. Deferred/module scripts are already too late. -->
|
||||
<script src="/src/scripts/pwa-install-capture.js?v=1790208243441"></script>
|
||||
<script src="/src/scripts/pwa-install-capture.js?v=1790219928897"></script>
|
||||
|
||||
<!-- PWA Meta Tags -->
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
@@ -116,7 +116,7 @@
|
||||
<link rel="apple-touch-startup-image" media="screen and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/logo/splash/splash_screens/8.3__iPad_Mini_portrait.png">
|
||||
|
||||
<!-- Apple Touch Icons -->
|
||||
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1790208243441">
|
||||
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1790219928897">
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="/logo/icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="/logo/icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="/logo/icon-72x72.png">
|
||||
@@ -125,7 +125,7 @@
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="/logo/icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="/logo/icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="/logo/icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1790208243441">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1790219928897">
|
||||
|
||||
<!-- Microsoft Tiles -->
|
||||
<meta name="msapplication-TileColor" content="#ff6b35">
|
||||
@@ -264,7 +264,7 @@
|
||||
<!-- Render-blocking JS is deferred: classic deferred scripts and module scripts
|
||||
both execute in document order after parsing, so React still runs before the
|
||||
app modules below, but the parser / first paint is no longer blocked. -->
|
||||
<script defer src="/config/ice-servers.js?v=1790208243441"></script>
|
||||
<script defer src="/config/ice-servers.js?v=1790219928897"></script>
|
||||
<script defer src="/libs/react/react.production.min.js"></script>
|
||||
<script defer src="/libs/react-dom/react-dom.production.min.js"></script>
|
||||
<!-- Prism syntax highlighting (vendored, offline). Tokenizes code as TEXT only —
|
||||
@@ -278,8 +278,8 @@
|
||||
the end of <body>: 21 KB of CSS in total, but eight round trips before the
|
||||
browser could paint, which GTmetrix measured at 441 ms on a throttled mobile
|
||||
connection. Bytes were never the problem; requests were. -->
|
||||
<link rel="stylesheet" href="/assets/app.css?v=1790208243441">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790208243441">
|
||||
<link rel="stylesheet" href="/assets/app.css?v=1790219928897">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790219928897">
|
||||
<!-- Preload only the fonts needed for first paint. Inter is one variable file that
|
||||
answers for every weight, so there is one to preload rather than the two of five
|
||||
copies this used to name. fa-solid covers the bulk of UI icons; fa-regular and
|
||||
@@ -287,19 +287,19 @@
|
||||
<link rel="preload" href="/assets/fontawesome/webfonts/fa-solid-900.subset.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<link rel="preload" href="/assets/fonts/inter/files/inter-latin.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<!-- Non-critical CSS (FontAwesome ~102KB, Prism) loaded async — no longer blocks paint. -->
|
||||
<script defer src="/src/scripts/load-async-css.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/load-async-css.js?v=1790219928897"></script>
|
||||
<noscript>
|
||||
<link rel="stylesheet" href="/libs/prism/prism.css">
|
||||
</noscript>
|
||||
<script defer src="/src/scripts/fa-check.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/fa-check.js?v=1790219928897"></script>
|
||||
<!-- This locale's dictionary, registered before anything can ask for a string.
|
||||
Only the default locale's is bundled (src/i18n/index.js imports it, because t()
|
||||
falls back to it); every other page loads its own here instead of all thirteen
|
||||
riding along inside dist/app.js. Absent on the default locale's own page. -->
|
||||
<script type="module" src="/src/i18n/dict/hi.js?v=1790208243441"></script>
|
||||
<script type="module" src="/src/i18n/dict/hi.js?v=1790219928897"></script>
|
||||
<!-- Update Manager - система принудительного обновления -->
|
||||
<script defer src="/src/utils/updateManager.js?v=1790208243441"></script>
|
||||
<script type="module" src="/src/components/UpdateChecker.jsx?v=1790208243441"></script>
|
||||
<script defer src="/src/utils/updateManager.js?v=1790219928897"></script>
|
||||
<script type="module" src="/src/components/UpdateChecker.jsx?v=1790219928897"></script>
|
||||
<!-- /dist/qr-local.js is deliberately absent: app-boot.js fetches it once the
|
||||
app has mounted and the browser is idle, so the 142 KB it weighs is off the
|
||||
first load. src/components/QRScanner.js used to be here too and registered
|
||||
@@ -487,12 +487,12 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="module" src="/dist/app-boot.js?v=1790208243441"></script>
|
||||
<script type="module" src="/dist/app.js?v=1790208243441"></script>
|
||||
<script type="module" src="/dist/app-boot.js?v=1790219928897"></script>
|
||||
<script type="module" src="/dist/app.js?v=1790219928897"></script>
|
||||
|
||||
<script defer src="/src/scripts/pwa-register.js?v=1790208243441"></script>
|
||||
<script src="/src/pwa/install-prompt.js?v=1790208243441" type="module"></script>
|
||||
<script src="/src/pwa/pwa-manager.js?v=1790208243441" type="module"></script>
|
||||
<script defer src="/src/scripts/pwa-offline-test.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/pwa-register.js?v=1790219928897"></script>
|
||||
<script src="/src/pwa/install-prompt.js?v=1790219928897" type="module"></script>
|
||||
<script src="/src/pwa/pwa-manager.js?v=1790219928897" type="module"></script>
|
||||
<script defer src="/src/scripts/pwa-offline-test.js?v=1790219928897"></script>
|
||||
</body>
|
||||
</html>
|
||||
+18
-18
@@ -30,18 +30,18 @@
|
||||
|
||||
<!-- PWA Manifest -->
|
||||
<link rel="manifest" href="/manifest.json">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790208243441">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790219928897">
|
||||
|
||||
<!-- Blocking, and above the stylesheet on purpose: this stamps data-theme on <html>
|
||||
from localStorage while the parser is still in <head>, so the page paints in the
|
||||
chosen theme on the first frame instead of flashing dark and correcting itself.
|
||||
Cannot be inline (CSP is script-src 'self') and cannot be a module (deferred). -->
|
||||
<script src="/src/scripts/theme-boot.js?v=1790208243441"></script>
|
||||
<script src="/src/scripts/theme-boot.js?v=1790219928897"></script>
|
||||
|
||||
<!-- Blocking, and in <head> on purpose: beforeinstallprompt fires once and is
|
||||
not replayed, so the listener has to exist before Chrome decides the page
|
||||
is installable. Deferred/module scripts are already too late. -->
|
||||
<script src="/src/scripts/pwa-install-capture.js?v=1790208243441"></script>
|
||||
<script src="/src/scripts/pwa-install-capture.js?v=1790219928897"></script>
|
||||
|
||||
<!-- PWA Meta Tags -->
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
@@ -116,7 +116,7 @@
|
||||
<link rel="apple-touch-startup-image" media="screen and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/logo/splash/splash_screens/8.3__iPad_Mini_portrait.png">
|
||||
|
||||
<!-- Apple Touch Icons -->
|
||||
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1790208243441">
|
||||
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1790219928897">
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="/logo/icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="/logo/icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="/logo/icon-72x72.png">
|
||||
@@ -125,7 +125,7 @@
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="/logo/icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="/logo/icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="/logo/icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1790208243441">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1790219928897">
|
||||
|
||||
<!-- Microsoft Tiles -->
|
||||
<meta name="msapplication-TileColor" content="#ff6b35">
|
||||
@@ -264,7 +264,7 @@
|
||||
<!-- Render-blocking JS is deferred: classic deferred scripts and module scripts
|
||||
both execute in document order after parsing, so React still runs before the
|
||||
app modules below, but the parser / first paint is no longer blocked. -->
|
||||
<script defer src="/config/ice-servers.js?v=1790208243441"></script>
|
||||
<script defer src="/config/ice-servers.js?v=1790219928897"></script>
|
||||
<script defer src="/libs/react/react.production.min.js"></script>
|
||||
<script defer src="/libs/react-dom/react-dom.production.min.js"></script>
|
||||
<!-- Prism syntax highlighting (vendored, offline). Tokenizes code as TEXT only —
|
||||
@@ -278,8 +278,8 @@
|
||||
the end of <body>: 21 KB of CSS in total, but eight round trips before the
|
||||
browser could paint, which GTmetrix measured at 441 ms on a throttled mobile
|
||||
connection. Bytes were never the problem; requests were. -->
|
||||
<link rel="stylesheet" href="/assets/app.css?v=1790208243441">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790208243441">
|
||||
<link rel="stylesheet" href="/assets/app.css?v=1790219928897">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790219928897">
|
||||
<!-- Preload only the fonts needed for first paint. Inter is one variable file that
|
||||
answers for every weight, so there is one to preload rather than the two of five
|
||||
copies this used to name. fa-solid covers the bulk of UI icons; fa-regular and
|
||||
@@ -287,18 +287,18 @@
|
||||
<link rel="preload" href="/assets/fontawesome/webfonts/fa-solid-900.subset.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<link rel="preload" href="/assets/fonts/inter/files/inter-latin.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<!-- Non-critical CSS (FontAwesome ~102KB, Prism) loaded async — no longer blocks paint. -->
|
||||
<script defer src="/src/scripts/load-async-css.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/load-async-css.js?v=1790219928897"></script>
|
||||
<noscript>
|
||||
<link rel="stylesheet" href="/libs/prism/prism.css">
|
||||
</noscript>
|
||||
<script defer src="/src/scripts/fa-check.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/fa-check.js?v=1790219928897"></script>
|
||||
<!-- This locale's dictionary, registered before anything can ask for a string.
|
||||
Only the default locale's is bundled (src/i18n/index.js imports it, because t()
|
||||
falls back to it); every other page loads its own here instead of all thirteen
|
||||
riding along inside dist/app.js. Absent on the default locale's own page. -->
|
||||
<!-- Update Manager - система принудительного обновления -->
|
||||
<script defer src="/src/utils/updateManager.js?v=1790208243441"></script>
|
||||
<script type="module" src="/src/components/UpdateChecker.jsx?v=1790208243441"></script>
|
||||
<script defer src="/src/utils/updateManager.js?v=1790219928897"></script>
|
||||
<script type="module" src="/src/components/UpdateChecker.jsx?v=1790219928897"></script>
|
||||
<!-- /dist/qr-local.js is deliberately absent: app-boot.js fetches it once the
|
||||
app has mounted and the browser is idle, so the 142 KB it weighs is off the
|
||||
first load. src/components/QRScanner.js used to be here too and registered
|
||||
@@ -486,12 +486,12 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="module" src="/dist/app-boot.js?v=1790208243441"></script>
|
||||
<script type="module" src="/dist/app.js?v=1790208243441"></script>
|
||||
<script type="module" src="/dist/app-boot.js?v=1790219928897"></script>
|
||||
<script type="module" src="/dist/app.js?v=1790219928897"></script>
|
||||
|
||||
<script defer src="/src/scripts/pwa-register.js?v=1790208243441"></script>
|
||||
<script src="/src/pwa/install-prompt.js?v=1790208243441" type="module"></script>
|
||||
<script src="/src/pwa/pwa-manager.js?v=1790208243441" type="module"></script>
|
||||
<script defer src="/src/scripts/pwa-offline-test.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/pwa-register.js?v=1790219928897"></script>
|
||||
<script src="/src/pwa/install-prompt.js?v=1790219928897" type="module"></script>
|
||||
<script src="/src/pwa/pwa-manager.js?v=1790219928897" type="module"></script>
|
||||
<script defer src="/src/scripts/pwa-offline-test.js?v=1790219928897"></script>
|
||||
</body>
|
||||
</html>
|
||||
+19
-19
@@ -30,18 +30,18 @@
|
||||
|
||||
<!-- PWA Manifest -->
|
||||
<link rel="manifest" href="/ko/manifest.json">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790208243441">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790219928897">
|
||||
|
||||
<!-- Blocking, and above the stylesheet on purpose: this stamps data-theme on <html>
|
||||
from localStorage while the parser is still in <head>, so the page paints in the
|
||||
chosen theme on the first frame instead of flashing dark and correcting itself.
|
||||
Cannot be inline (CSP is script-src 'self') and cannot be a module (deferred). -->
|
||||
<script src="/src/scripts/theme-boot.js?v=1790208243441"></script>
|
||||
<script src="/src/scripts/theme-boot.js?v=1790219928897"></script>
|
||||
|
||||
<!-- Blocking, and in <head> on purpose: beforeinstallprompt fires once and is
|
||||
not replayed, so the listener has to exist before Chrome decides the page
|
||||
is installable. Deferred/module scripts are already too late. -->
|
||||
<script src="/src/scripts/pwa-install-capture.js?v=1790208243441"></script>
|
||||
<script src="/src/scripts/pwa-install-capture.js?v=1790219928897"></script>
|
||||
|
||||
<!-- PWA Meta Tags -->
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
@@ -116,7 +116,7 @@
|
||||
<link rel="apple-touch-startup-image" media="screen and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/logo/splash/splash_screens/8.3__iPad_Mini_portrait.png">
|
||||
|
||||
<!-- Apple Touch Icons -->
|
||||
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1790208243441">
|
||||
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1790219928897">
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="/logo/icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="/logo/icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="/logo/icon-72x72.png">
|
||||
@@ -125,7 +125,7 @@
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="/logo/icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="/logo/icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="/logo/icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1790208243441">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1790219928897">
|
||||
|
||||
<!-- Microsoft Tiles -->
|
||||
<meta name="msapplication-TileColor" content="#ff6b35">
|
||||
@@ -264,7 +264,7 @@
|
||||
<!-- Render-blocking JS is deferred: classic deferred scripts and module scripts
|
||||
both execute in document order after parsing, so React still runs before the
|
||||
app modules below, but the parser / first paint is no longer blocked. -->
|
||||
<script defer src="/config/ice-servers.js?v=1790208243441"></script>
|
||||
<script defer src="/config/ice-servers.js?v=1790219928897"></script>
|
||||
<script defer src="/libs/react/react.production.min.js"></script>
|
||||
<script defer src="/libs/react-dom/react-dom.production.min.js"></script>
|
||||
<!-- Prism syntax highlighting (vendored, offline). Tokenizes code as TEXT only —
|
||||
@@ -278,8 +278,8 @@
|
||||
the end of <body>: 21 KB of CSS in total, but eight round trips before the
|
||||
browser could paint, which GTmetrix measured at 441 ms on a throttled mobile
|
||||
connection. Bytes were never the problem; requests were. -->
|
||||
<link rel="stylesheet" href="/assets/app.css?v=1790208243441">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790208243441">
|
||||
<link rel="stylesheet" href="/assets/app.css?v=1790219928897">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790219928897">
|
||||
<!-- Preload only the fonts needed for first paint. Inter is one variable file that
|
||||
answers for every weight, so there is one to preload rather than the two of five
|
||||
copies this used to name. fa-solid covers the bulk of UI icons; fa-regular and
|
||||
@@ -287,19 +287,19 @@
|
||||
<link rel="preload" href="/assets/fontawesome/webfonts/fa-solid-900.subset.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<link rel="preload" href="/assets/fonts/inter/files/inter-latin.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<!-- Non-critical CSS (FontAwesome ~102KB, Prism) loaded async — no longer blocks paint. -->
|
||||
<script defer src="/src/scripts/load-async-css.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/load-async-css.js?v=1790219928897"></script>
|
||||
<noscript>
|
||||
<link rel="stylesheet" href="/libs/prism/prism.css">
|
||||
</noscript>
|
||||
<script defer src="/src/scripts/fa-check.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/fa-check.js?v=1790219928897"></script>
|
||||
<!-- This locale's dictionary, registered before anything can ask for a string.
|
||||
Only the default locale's is bundled (src/i18n/index.js imports it, because t()
|
||||
falls back to it); every other page loads its own here instead of all thirteen
|
||||
riding along inside dist/app.js. Absent on the default locale's own page. -->
|
||||
<script type="module" src="/src/i18n/dict/ko.js?v=1790208243441"></script>
|
||||
<script type="module" src="/src/i18n/dict/ko.js?v=1790219928897"></script>
|
||||
<!-- Update Manager - система принудительного обновления -->
|
||||
<script defer src="/src/utils/updateManager.js?v=1790208243441"></script>
|
||||
<script type="module" src="/src/components/UpdateChecker.jsx?v=1790208243441"></script>
|
||||
<script defer src="/src/utils/updateManager.js?v=1790219928897"></script>
|
||||
<script type="module" src="/src/components/UpdateChecker.jsx?v=1790219928897"></script>
|
||||
<!-- /dist/qr-local.js is deliberately absent: app-boot.js fetches it once the
|
||||
app has mounted and the browser is idle, so the 142 KB it weighs is off the
|
||||
first load. src/components/QRScanner.js used to be here too and registered
|
||||
@@ -487,12 +487,12 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="module" src="/dist/app-boot.js?v=1790208243441"></script>
|
||||
<script type="module" src="/dist/app.js?v=1790208243441"></script>
|
||||
<script type="module" src="/dist/app-boot.js?v=1790219928897"></script>
|
||||
<script type="module" src="/dist/app.js?v=1790219928897"></script>
|
||||
|
||||
<script defer src="/src/scripts/pwa-register.js?v=1790208243441"></script>
|
||||
<script src="/src/pwa/install-prompt.js?v=1790208243441" type="module"></script>
|
||||
<script src="/src/pwa/pwa-manager.js?v=1790208243441" type="module"></script>
|
||||
<script defer src="/src/scripts/pwa-offline-test.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/pwa-register.js?v=1790219928897"></script>
|
||||
<script src="/src/pwa/install-prompt.js?v=1790219928897" type="module"></script>
|
||||
<script src="/src/pwa/pwa-manager.js?v=1790219928897" type="module"></script>
|
||||
<script defer src="/src/scripts/pwa-offline-test.js?v=1790219928897"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -105,11 +105,6 @@
|
||||
"roadmap.progress": "أُنجزت {shipped} من أصل {total} محطّة",
|
||||
"roadmap.upcoming": "{upcoming} في الطريق",
|
||||
"roadmap.keyFeatures": "أبرز المزايا",
|
||||
"roadmap.status.released": "صدرت",
|
||||
"roadmap.status.current": "الحالية",
|
||||
"roadmap.status.dev": "قيد التطوير",
|
||||
"roadmap.status.planned": "مُخطّطة",
|
||||
"roadmap.status.research": "قيد البحث",
|
||||
"hero.headlineTop": "خطٌّ مباشر",
|
||||
"hero.headlineBottom": "لا يقرأه إلّا أنتما.",
|
||||
"hero.subheading": "تُولَّد المفاتيح على جهازك وتُتبادَل ندّاً لندّ. بلا حسابات وبلا خوادم تحفظ رسائلك.",
|
||||
|
||||
@@ -105,11 +105,6 @@
|
||||
"roadmap.progress": "{shipped} von {total} Meilensteinen erreicht",
|
||||
"roadmap.upcoming": "{upcoming} in Arbeit",
|
||||
"roadmap.keyFeatures": "Kernfunktionen",
|
||||
"roadmap.status.released": "Veröffentlicht",
|
||||
"roadmap.status.current": "Aktuell",
|
||||
"roadmap.status.dev": "In Entwicklung",
|
||||
"roadmap.status.planned": "Geplant",
|
||||
"roadmap.status.research": "Forschung",
|
||||
"hero.headlineTop": "Eine direkte Leitung,",
|
||||
"hero.headlineBottom": "die nur Sie beide lesen können.",
|
||||
"hero.subheading": "Die Schlüssel entstehen auf Ihrem Gerät und werden direkt zwischen den Geräten ausgetauscht. Keine Konten, keine Server, die Ihre Nachrichten speichern.",
|
||||
|
||||
@@ -100,11 +100,6 @@
|
||||
"roadmap.progress": "{shipped} of {total} milestones shipped",
|
||||
"roadmap.upcoming": "{upcoming} on the way",
|
||||
"roadmap.keyFeatures": "Key features",
|
||||
"roadmap.status.released": "Released",
|
||||
"roadmap.status.current": "Current",
|
||||
"roadmap.status.dev": "In development",
|
||||
"roadmap.status.planned": "Planned",
|
||||
"roadmap.status.research": "Research",
|
||||
"hero.headlineTop": "A direct line",
|
||||
"hero.headlineBottom": "only you two can read.",
|
||||
"hero.subheading": "Keys are generated on your device and exchanged peer-to-peer. No accounts, no servers storing your messages.",
|
||||
|
||||
@@ -105,11 +105,6 @@
|
||||
"roadmap.progress": "{shipped} de {total} hitos completados",
|
||||
"roadmap.upcoming": "{upcoming} en camino",
|
||||
"roadmap.keyFeatures": "Funciones clave",
|
||||
"roadmap.status.released": "Publicado",
|
||||
"roadmap.status.current": "Actual",
|
||||
"roadmap.status.dev": "En desarrollo",
|
||||
"roadmap.status.planned": "Planificado",
|
||||
"roadmap.status.research": "Investigación",
|
||||
"hero.headlineTop": "Una línea directa",
|
||||
"hero.headlineBottom": "que solo leéis vosotros dos.",
|
||||
"hero.subheading": "Las claves se generan en tu dispositivo y se intercambian directamente entre pares. Sin cuentas y sin servidores que guarden tus mensajes.",
|
||||
|
||||
@@ -105,11 +105,6 @@
|
||||
"roadmap.progress": "{shipped} از {total} نقطهٔ عطف انجام شد",
|
||||
"roadmap.upcoming": "{upcoming} در راه است",
|
||||
"roadmap.keyFeatures": "ویژگیهای کلیدی",
|
||||
"roadmap.status.released": "منتشر شد",
|
||||
"roadmap.status.current": "کنونی",
|
||||
"roadmap.status.dev": "در دست توسعه",
|
||||
"roadmap.status.planned": "برنامهریزیشده",
|
||||
"roadmap.status.research": "پژوهش",
|
||||
"hero.headlineTop": "خطی مستقیم",
|
||||
"hero.headlineBottom": "که فقط شما دو نفر میخوانید.",
|
||||
"hero.subheading": "کلیدها روی دستگاه شما ساخته و همتابههمتا مبادله میشوند. بدون حساب، بدون سروری که پیامهایتان را نگه دارد.",
|
||||
|
||||
@@ -100,11 +100,6 @@
|
||||
"roadmap.progress": "{shipped} jalons sur {total} atteints",
|
||||
"roadmap.upcoming": "{upcoming} à venir",
|
||||
"roadmap.keyFeatures": "Fonctions clés",
|
||||
"roadmap.status.released": "Publié",
|
||||
"roadmap.status.current": "En cours",
|
||||
"roadmap.status.dev": "En développement",
|
||||
"roadmap.status.planned": "Planifié",
|
||||
"roadmap.status.research": "Recherche",
|
||||
"hero.headlineTop": "Une ligne directe",
|
||||
"hero.headlineBottom": "que vous seuls pouvez lire.",
|
||||
"hero.subheading": "Les clés sont créées sur votre appareil et échangées directement entre pairs. Aucun compte, aucun serveur ne conserve vos messages.",
|
||||
|
||||
@@ -105,11 +105,6 @@
|
||||
"roadmap.progress": "{shipped} מתוך {total} אבני דרך הושלמו",
|
||||
"roadmap.upcoming": "{upcoming} בדרך",
|
||||
"roadmap.keyFeatures": "יכולות מרכזיות",
|
||||
"roadmap.status.released": "שוחרר",
|
||||
"roadmap.status.current": "נוכחי",
|
||||
"roadmap.status.dev": "בפיתוח",
|
||||
"roadmap.status.planned": "מתוכנן",
|
||||
"roadmap.status.research": "מחקר",
|
||||
"hero.headlineTop": "קו ישיר",
|
||||
"hero.headlineBottom": "שרק שניכם יכולים לקרוא.",
|
||||
"hero.subheading": "המפתחות נוצרים במכשיר שלכם ומוחלפים עמית־לעמית. בלי חשבונות, בלי שרתים ששומרים את ההודעות.",
|
||||
|
||||
@@ -100,11 +100,6 @@
|
||||
"roadmap.progress": "{total} में से {shipped} पड़ाव पूरे",
|
||||
"roadmap.upcoming": "{upcoming} बाक़ी",
|
||||
"roadmap.keyFeatures": "मुख्य विशेषताएँ",
|
||||
"roadmap.status.released": "जारी",
|
||||
"roadmap.status.current": "अभी चालू",
|
||||
"roadmap.status.dev": "विकास में",
|
||||
"roadmap.status.planned": "नियोजित",
|
||||
"roadmap.status.research": "शोध",
|
||||
"hero.headlineTop": "एक सीधी लाइन,",
|
||||
"hero.headlineBottom": "जिसे सिर्फ़ आप दोनों पढ़ सकें।",
|
||||
"hero.subheading": "कुंजियाँ आपके उपकरण पर बनती हैं और सीधे दोनों पक्षों के बीच बदली जाती हैं। न कोई खाता, न कोई सर्वर जो आपके संदेश रखे।",
|
||||
|
||||
@@ -100,11 +100,6 @@
|
||||
"roadmap.progress": "{total}개 중 {shipped}개 완료",
|
||||
"roadmap.upcoming": "{upcoming}개 남음",
|
||||
"roadmap.keyFeatures": "주요 기능",
|
||||
"roadmap.status.released": "출시됨",
|
||||
"roadmap.status.current": "진행 중",
|
||||
"roadmap.status.dev": "개발 중",
|
||||
"roadmap.status.planned": "예정",
|
||||
"roadmap.status.research": "연구",
|
||||
"hero.headlineTop": "두 사람만 읽을 수 있는",
|
||||
"hero.headlineBottom": "직통 회선.",
|
||||
"hero.subheading": "키는 여러분의 기기에서 만들어지고 두 기기 사이에서 곧바로 교환됩니다. 계정도 없고 메시지를 보관하는 서버도 없습니다.",
|
||||
|
||||
@@ -105,11 +105,6 @@
|
||||
"roadmap.progress": "Пройдено {shipped} из {total} этапов",
|
||||
"roadmap.upcoming": "{upcoming} впереди",
|
||||
"roadmap.keyFeatures": "Ключевые возможности",
|
||||
"roadmap.status.released": "Выпущено",
|
||||
"roadmap.status.current": "Текущий",
|
||||
"roadmap.status.dev": "В разработке",
|
||||
"roadmap.status.planned": "Запланировано",
|
||||
"roadmap.status.research": "Исследование",
|
||||
"hero.headlineTop": "Прямая линия,",
|
||||
"hero.headlineBottom": "которую прочитаете только вы двое.",
|
||||
"hero.subheading": "Ключи создаются на вашем устройстве и передаются напрямую между участниками. Без учётных записей и без серверов, хранящих ваши сообщения.",
|
||||
|
||||
@@ -105,11 +105,6 @@
|
||||
"roadmap.progress": "Пройдено {shipped} з {total} етапів",
|
||||
"roadmap.upcoming": "{upcoming} попереду",
|
||||
"roadmap.keyFeatures": "Ключові можливості",
|
||||
"roadmap.status.released": "Випущено",
|
||||
"roadmap.status.current": "Поточний",
|
||||
"roadmap.status.dev": "У розробці",
|
||||
"roadmap.status.planned": "Заплановано",
|
||||
"roadmap.status.research": "Дослідження",
|
||||
"hero.headlineTop": "Пряма лінія,",
|
||||
"hero.headlineBottom": "яку прочитаєте лише ви двоє.",
|
||||
"hero.subheading": "Ключі створюються на вашому пристрої й передаються напряму між учасниками. Без облікових записів і без серверів, що зберігають ваші повідомлення.",
|
||||
|
||||
@@ -105,11 +105,6 @@
|
||||
"roadmap.progress": "{total} میں سے {shipped} سنگِ میل مکمل",
|
||||
"roadmap.upcoming": "{upcoming} راستے میں",
|
||||
"roadmap.keyFeatures": "نمایاں خصوصیات",
|
||||
"roadmap.status.released": "جاری ہوا",
|
||||
"roadmap.status.current": "موجودہ",
|
||||
"roadmap.status.dev": "زیرِ تعمیر",
|
||||
"roadmap.status.planned": "منصوبہ بند",
|
||||
"roadmap.status.research": "تحقیق",
|
||||
"hero.headlineTop": "ایک سیدھی لکیر",
|
||||
"hero.headlineBottom": "جسے صرف آپ دونوں پڑھ سکتے ہیں۔",
|
||||
"hero.subheading": "کلیدیں آپ کے آلے پر بنتی ہیں اور ہمسطح تبادلہ ہوتا ہے۔ نہ اکاؤنٹ، نہ کوئی سرور جو آپ کے پیغام محفوظ کرے۔",
|
||||
|
||||
@@ -100,11 +100,6 @@
|
||||
"roadmap.progress": "已完成 {total} 个里程碑中的 {shipped} 个",
|
||||
"roadmap.upcoming": "还有 {upcoming} 个",
|
||||
"roadmap.keyFeatures": "核心功能",
|
||||
"roadmap.status.released": "已发布",
|
||||
"roadmap.status.current": "进行中",
|
||||
"roadmap.status.dev": "开发中",
|
||||
"roadmap.status.planned": "已规划",
|
||||
"roadmap.status.research": "研究中",
|
||||
"hero.headlineTop": "一条只有你们两人",
|
||||
"hero.headlineBottom": "才能读懂的直连线路。",
|
||||
"hero.subheading": "密钥在你的设备上生成,并在两端之间直接交换。无需账号,没有服务器保存你的消息。",
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"version": "1790208243441",
|
||||
"buildVersion": "1790208243441",
|
||||
"appVersion": "6.8.5",
|
||||
"buildTime": "2026-09-24T00:04:03.480Z",
|
||||
"buildId": "1790208243441-f39e902",
|
||||
"gitHash": "f39e902",
|
||||
"version": "1790219928897",
|
||||
"buildVersion": "1790219928897",
|
||||
"appVersion": "6.8.6",
|
||||
"buildTime": "2026-09-24T03:18:48.935Z",
|
||||
"buildId": "1790219928897-02380a7",
|
||||
"gitHash": "02380a7",
|
||||
"generated": true,
|
||||
"generatedAt": "2026-09-24T00:04:03.481Z"
|
||||
"generatedAt": "2026-09-24T03:18:48.936Z"
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "securebit-chat",
|
||||
"version": "6.8.5",
|
||||
"version": "6.8.6",
|
||||
"description": "Secure P2P Communication Application with End-to-End Encryption",
|
||||
"main": "index.html",
|
||||
"scripts": {
|
||||
|
||||
+19
-19
@@ -30,18 +30,18 @@
|
||||
|
||||
<!-- PWA Manifest -->
|
||||
<link rel="manifest" href="/ru/manifest.json">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790208243441">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790219928897">
|
||||
|
||||
<!-- Blocking, and above the stylesheet on purpose: this stamps data-theme on <html>
|
||||
from localStorage while the parser is still in <head>, so the page paints in the
|
||||
chosen theme on the first frame instead of flashing dark and correcting itself.
|
||||
Cannot be inline (CSP is script-src 'self') and cannot be a module (deferred). -->
|
||||
<script src="/src/scripts/theme-boot.js?v=1790208243441"></script>
|
||||
<script src="/src/scripts/theme-boot.js?v=1790219928897"></script>
|
||||
|
||||
<!-- Blocking, and in <head> on purpose: beforeinstallprompt fires once and is
|
||||
not replayed, so the listener has to exist before Chrome decides the page
|
||||
is installable. Deferred/module scripts are already too late. -->
|
||||
<script src="/src/scripts/pwa-install-capture.js?v=1790208243441"></script>
|
||||
<script src="/src/scripts/pwa-install-capture.js?v=1790219928897"></script>
|
||||
|
||||
<!-- PWA Meta Tags -->
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
@@ -116,7 +116,7 @@
|
||||
<link rel="apple-touch-startup-image" media="screen and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/logo/splash/splash_screens/8.3__iPad_Mini_portrait.png">
|
||||
|
||||
<!-- Apple Touch Icons -->
|
||||
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1790208243441">
|
||||
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1790219928897">
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="/logo/icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="/logo/icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="/logo/icon-72x72.png">
|
||||
@@ -125,7 +125,7 @@
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="/logo/icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="/logo/icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="/logo/icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1790208243441">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1790219928897">
|
||||
|
||||
<!-- Microsoft Tiles -->
|
||||
<meta name="msapplication-TileColor" content="#ff6b35">
|
||||
@@ -264,7 +264,7 @@
|
||||
<!-- Render-blocking JS is deferred: classic deferred scripts and module scripts
|
||||
both execute in document order after parsing, so React still runs before the
|
||||
app modules below, but the parser / first paint is no longer blocked. -->
|
||||
<script defer src="/config/ice-servers.js?v=1790208243441"></script>
|
||||
<script defer src="/config/ice-servers.js?v=1790219928897"></script>
|
||||
<script defer src="/libs/react/react.production.min.js"></script>
|
||||
<script defer src="/libs/react-dom/react-dom.production.min.js"></script>
|
||||
<!-- Prism syntax highlighting (vendored, offline). Tokenizes code as TEXT only —
|
||||
@@ -278,8 +278,8 @@
|
||||
the end of <body>: 21 KB of CSS in total, but eight round trips before the
|
||||
browser could paint, which GTmetrix measured at 441 ms on a throttled mobile
|
||||
connection. Bytes were never the problem; requests were. -->
|
||||
<link rel="stylesheet" href="/assets/app.css?v=1790208243441">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790208243441">
|
||||
<link rel="stylesheet" href="/assets/app.css?v=1790219928897">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790219928897">
|
||||
<!-- Preload only the fonts needed for first paint. Inter is one variable file that
|
||||
answers for every weight, so there is one to preload rather than the two of five
|
||||
copies this used to name. fa-solid covers the bulk of UI icons; fa-regular and
|
||||
@@ -287,19 +287,19 @@
|
||||
<link rel="preload" href="/assets/fontawesome/webfonts/fa-solid-900.subset.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<link rel="preload" href="/assets/fonts/inter/files/inter-latin.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<!-- Non-critical CSS (FontAwesome ~102KB, Prism) loaded async — no longer blocks paint. -->
|
||||
<script defer src="/src/scripts/load-async-css.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/load-async-css.js?v=1790219928897"></script>
|
||||
<noscript>
|
||||
<link rel="stylesheet" href="/libs/prism/prism.css">
|
||||
</noscript>
|
||||
<script defer src="/src/scripts/fa-check.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/fa-check.js?v=1790219928897"></script>
|
||||
<!-- This locale's dictionary, registered before anything can ask for a string.
|
||||
Only the default locale's is bundled (src/i18n/index.js imports it, because t()
|
||||
falls back to it); every other page loads its own here instead of all thirteen
|
||||
riding along inside dist/app.js. Absent on the default locale's own page. -->
|
||||
<script type="module" src="/src/i18n/dict/ru.js?v=1790208243441"></script>
|
||||
<script type="module" src="/src/i18n/dict/ru.js?v=1790219928897"></script>
|
||||
<!-- Update Manager - система принудительного обновления -->
|
||||
<script defer src="/src/utils/updateManager.js?v=1790208243441"></script>
|
||||
<script type="module" src="/src/components/UpdateChecker.jsx?v=1790208243441"></script>
|
||||
<script defer src="/src/utils/updateManager.js?v=1790219928897"></script>
|
||||
<script type="module" src="/src/components/UpdateChecker.jsx?v=1790219928897"></script>
|
||||
<!-- /dist/qr-local.js is deliberately absent: app-boot.js fetches it once the
|
||||
app has mounted and the browser is idle, so the 142 KB it weighs is off the
|
||||
first load. src/components/QRScanner.js used to be here too and registered
|
||||
@@ -487,12 +487,12 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="module" src="/dist/app-boot.js?v=1790208243441"></script>
|
||||
<script type="module" src="/dist/app.js?v=1790208243441"></script>
|
||||
<script type="module" src="/dist/app-boot.js?v=1790219928897"></script>
|
||||
<script type="module" src="/dist/app.js?v=1790219928897"></script>
|
||||
|
||||
<script defer src="/src/scripts/pwa-register.js?v=1790208243441"></script>
|
||||
<script src="/src/pwa/install-prompt.js?v=1790208243441" type="module"></script>
|
||||
<script src="/src/pwa/pwa-manager.js?v=1790208243441" type="module"></script>
|
||||
<script defer src="/src/scripts/pwa-offline-test.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/pwa-register.js?v=1790219928897"></script>
|
||||
<script src="/src/pwa/install-prompt.js?v=1790219928897" type="module"></script>
|
||||
<script src="/src/pwa/pwa-manager.js?v=1790219928897" type="module"></script>
|
||||
<script defer src="/src/scripts/pwa-offline-test.js?v=1790219928897"></script>
|
||||
</body>
|
||||
</html>
|
||||
+1
-1
@@ -1696,7 +1696,7 @@ import { GroupCallMedia, mediaErrorCode } from './group/groupCallMedia.js';
|
||||
// /download/v0.3.0/SecureBit.Chat_0.1.0_x64-setup.exe, a file that never
|
||||
// existed, and the download 404s. A pinned tag keeps serving a real
|
||||
// installer instead.
|
||||
const SB_DESKTOP_VERSION = '1.0.3';
|
||||
const SB_DESKTOP_VERSION = '1.0.4';
|
||||
const SB_DESKTOP_RELEASE = `https://github.com/SecureBitChat/securebit-desktop/releases/download/v${SB_DESKTOP_VERSION}`;
|
||||
const DOWNLOADS = {
|
||||
mac: { name: 'macOS', format: '.dmg · Apple Silicon & Intel', icon: 'fab fa-apple', url: `${SB_DESKTOP_RELEASE}/SecureBit.Chat_${SB_DESKTOP_VERSION}_x64.dmg` },
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
// The tag is pinned rather than using /releases/latest/download/: the filenames
|
||||
// carry the version, so a `latest` link 404s the moment a newer release exists,
|
||||
// whereas a pinned tag keeps serving a working (if older) installer.
|
||||
const DESKTOP_VERSION = '1.0.3';
|
||||
const DESKTOP_VERSION = '1.0.4';
|
||||
const DESKTOP_RELEASE = `https://github.com/SecureBitChat/securebit-desktop/releases/download/v${DESKTOP_VERSION}`;
|
||||
|
||||
const DownloadApps = () => {
|
||||
|
||||
@@ -44,33 +44,21 @@ function Roadmap() {
|
||||
features: tList(`roadmap.${d.k}.features`)
|
||||
}));
|
||||
|
||||
// `rgb` is the same colour as `color`, published as bare channels. The pill draws
|
||||
// its fill and border from it at low alpha, and there is no way to add an alpha to
|
||||
// a colour that a custom property has already resolved — hence the pair, which has
|
||||
// to be kept in step.
|
||||
// Three forms of the same status colour, because they are used three ways and only
|
||||
// one of them is text. `color` is the word — it darkens in the light theme so it can
|
||||
// be read on white. `solid` is the dot, which is a mark rather than a label and
|
||||
// stays the brand colour in both themes. `rgb` is the channels, for the pill's fill
|
||||
// and border at low alpha. The three have to be kept in step.
|
||||
// The status of a milestone is shown by its marker on the timeline and the colour of
|
||||
// its bullets, not by a word: the labels (Released, In development, ...) were taken
|
||||
// out. `solid` is the dot colour, `line` the spine below it.
|
||||
const META = {
|
||||
released: { word: t('roadmap.status.released'), color: "var(--sb-green)", solid: "var(--sb-green-solid)", rgb: "var(--sb-green-rgb)", line: "rgba(var(--sb-green-rgb), 0.32)" },
|
||||
current: { word: t('roadmap.status.current'), color: "var(--sb-orange)", solid: "var(--sb-orange-solid)", rgb: "var(--sb-orange-rgb)", line: "rgba(var(--sb-orange-rgb), 0.32)" },
|
||||
dev: { word: t('roadmap.status.dev'), color: "var(--sb-yellow-2)", solid: "var(--sb-yellow-2-solid)", rgb: "var(--sb-yellow-2-rgb)", line: "rgba(var(--sb-ink), 0.08)" },
|
||||
planned: { word: t('roadmap.status.planned'), color: "var(--sb-text-7)", solid: "var(--sb-text-7)", rgb: "var(--sb-text-7-rgb)", line: "rgba(var(--sb-ink), 0.08)" },
|
||||
research: { word: t('roadmap.status.research'), color: "var(--sb-text-9)", solid: "var(--sb-text-9)", rgb: "var(--sb-text-9-rgb)", line: "rgba(var(--sb-ink), 0.08)" }
|
||||
released: { solid: "var(--sb-green-solid)", line: "rgba(var(--sb-green-rgb), 0.32)" },
|
||||
current: { solid: "var(--sb-orange-solid)", line: "rgba(var(--sb-orange-rgb), 0.32)" },
|
||||
dev: { solid: "var(--sb-yellow-2-solid)", line: "rgba(var(--sb-ink), 0.08)" },
|
||||
planned: { solid: "var(--sb-text-7)", line: "rgba(var(--sb-ink), 0.08)" },
|
||||
research: { solid: "var(--sb-text-9)", line: "rgba(var(--sb-ink), 0.08)" }
|
||||
};
|
||||
|
||||
const [open, setOpen] = React.useState({});
|
||||
const isOpen = (i) => (open[i] === undefined ? DATA[i].status === 'current' : open[i]);
|
||||
const toggle = (i) => setOpen((s) => ({ ...s, [i]: !isOpen(i) }));
|
||||
|
||||
// Was hexA(), which took the literal hex out of META and split it into channels by
|
||||
// hand. Those literals are custom properties now, so there is nothing to parse at
|
||||
// runtime — the browser does the substitution instead, and it does it again when
|
||||
// the theme changes, which the old version could not.
|
||||
const tint = (channels, a) => `rgba(${channels}, ${a})`;
|
||||
|
||||
const total = DATA.length;
|
||||
const shipped = DATA.filter((d) => d.status === 'released' || d.status === 'current').length;
|
||||
const upcoming = total - shipped;
|
||||
@@ -162,18 +150,6 @@ function Roadmap() {
|
||||
{!isMobile && <div style={{ marginTop: '3px', fontSize: '13.5px', color: 'var(--sb-text-6)' }}>{d.sub}</div>}
|
||||
</div>
|
||||
<div style={{ flex: 'none', display: 'flex', alignItems: 'center', gap: isMobile ? '8px' : '14px' }}>
|
||||
{/* The status pill is desktop-only. On a phone its
|
||||
word does not fit, and what was left — a bordered
|
||||
box around a single coloured dot — said nothing the
|
||||
marker on the timeline was not already saying in
|
||||
the same colour, while taking room from the title.
|
||||
So the whole pill goes, not just its label. */}
|
||||
{!isMobile && (
|
||||
<span style={{ display: 'inline-flex', alignItems: 'center', gap: '7px', padding: '6px 11px', borderRadius: '8px', background: tint(meta.rgb, 0.1), border: `1px solid ${tint(meta.rgb, 0.22)}`, fontFamily: MONO, fontSize: '10.5px', fontWeight: 600, color: meta.color, textTransform: 'uppercase', letterSpacing: '0.8px', whiteSpace: 'nowrap' }}>
|
||||
<span style={{ width: '6px', height: '6px', borderRadius: '50%', background: meta.solid }} />
|
||||
{meta.word}
|
||||
</span>
|
||||
)}
|
||||
{!isMobile && <span style={{ fontFamily: MONO, fontSize: '12px', fontWeight: 500, color: 'var(--sb-text-7)', whiteSpace: 'nowrap', minWidth: '74px', textAlign: 'end' }}>{d.date}</span>}
|
||||
<span style={{ color: 'var(--sb-text-9)', display: 'inline-flex', transition: 'transform .22s cubic-bezier(.2,.7,.3,1)', transform: opened ? 'rotate(180deg)' : 'rotate(0deg)' }}>
|
||||
<svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.1" strokeLinecap="round" strokeLinejoin="round"><path d="M6 9l6 6 6-6" /></svg>
|
||||
|
||||
@@ -73,11 +73,6 @@ export const DICTIONARY = {
|
||||
"roadmap.progress": "أُنجزت {shipped} من أصل {total} محطّة",
|
||||
"roadmap.upcoming": "{upcoming} في الطريق",
|
||||
"roadmap.keyFeatures": "أبرز المزايا",
|
||||
"roadmap.status.released": "صدرت",
|
||||
"roadmap.status.current": "الحالية",
|
||||
"roadmap.status.dev": "قيد التطوير",
|
||||
"roadmap.status.planned": "مُخطّطة",
|
||||
"roadmap.status.research": "قيد البحث",
|
||||
"hero.headlineTop": "خطٌّ مباشر",
|
||||
"hero.headlineBottom": "لا يقرأه إلّا أنتما.",
|
||||
"hero.subheading": "تُولَّد المفاتيح على جهازك وتُتبادَل ندّاً لندّ. بلا حسابات وبلا خوادم تحفظ رسائلك.",
|
||||
|
||||
@@ -73,11 +73,6 @@ export const DICTIONARY = {
|
||||
"roadmap.progress": "{shipped} von {total} Meilensteinen erreicht",
|
||||
"roadmap.upcoming": "{upcoming} in Arbeit",
|
||||
"roadmap.keyFeatures": "Kernfunktionen",
|
||||
"roadmap.status.released": "Veröffentlicht",
|
||||
"roadmap.status.current": "Aktuell",
|
||||
"roadmap.status.dev": "In Entwicklung",
|
||||
"roadmap.status.planned": "Geplant",
|
||||
"roadmap.status.research": "Forschung",
|
||||
"hero.headlineTop": "Eine direkte Leitung,",
|
||||
"hero.headlineBottom": "die nur Sie beide lesen können.",
|
||||
"hero.subheading": "Die Schlüssel entstehen auf Ihrem Gerät und werden direkt zwischen den Geräten ausgetauscht. Keine Konten, keine Server, die Ihre Nachrichten speichern.",
|
||||
|
||||
@@ -73,11 +73,6 @@ export const DICTIONARY = {
|
||||
"roadmap.progress": "{shipped} of {total} milestones shipped",
|
||||
"roadmap.upcoming": "{upcoming} on the way",
|
||||
"roadmap.keyFeatures": "Key features",
|
||||
"roadmap.status.released": "Released",
|
||||
"roadmap.status.current": "Current",
|
||||
"roadmap.status.dev": "In development",
|
||||
"roadmap.status.planned": "Planned",
|
||||
"roadmap.status.research": "Research",
|
||||
"hero.headlineTop": "A direct line",
|
||||
"hero.headlineBottom": "only you two can read.",
|
||||
"hero.subheading": "Keys are generated on your device and exchanged peer-to-peer. No accounts, no servers storing your messages.",
|
||||
|
||||
@@ -73,11 +73,6 @@ export const DICTIONARY = {
|
||||
"roadmap.progress": "{shipped} de {total} hitos completados",
|
||||
"roadmap.upcoming": "{upcoming} en camino",
|
||||
"roadmap.keyFeatures": "Funciones clave",
|
||||
"roadmap.status.released": "Publicado",
|
||||
"roadmap.status.current": "Actual",
|
||||
"roadmap.status.dev": "En desarrollo",
|
||||
"roadmap.status.planned": "Planificado",
|
||||
"roadmap.status.research": "Investigación",
|
||||
"hero.headlineTop": "Una línea directa",
|
||||
"hero.headlineBottom": "que solo leéis vosotros dos.",
|
||||
"hero.subheading": "Las claves se generan en tu dispositivo y se intercambian directamente entre pares. Sin cuentas y sin servidores que guarden tus mensajes.",
|
||||
|
||||
@@ -73,11 +73,6 @@ export const DICTIONARY = {
|
||||
"roadmap.progress": "{shipped} از {total} نقطهٔ عطف انجام شد",
|
||||
"roadmap.upcoming": "{upcoming} در راه است",
|
||||
"roadmap.keyFeatures": "ویژگیهای کلیدی",
|
||||
"roadmap.status.released": "منتشر شد",
|
||||
"roadmap.status.current": "کنونی",
|
||||
"roadmap.status.dev": "در دست توسعه",
|
||||
"roadmap.status.planned": "برنامهریزیشده",
|
||||
"roadmap.status.research": "پژوهش",
|
||||
"hero.headlineTop": "خطی مستقیم",
|
||||
"hero.headlineBottom": "که فقط شما دو نفر میخوانید.",
|
||||
"hero.subheading": "کلیدها روی دستگاه شما ساخته و همتابههمتا مبادله میشوند. بدون حساب، بدون سروری که پیامهایتان را نگه دارد.",
|
||||
|
||||
@@ -73,11 +73,6 @@ export const DICTIONARY = {
|
||||
"roadmap.progress": "{shipped} jalons sur {total} atteints",
|
||||
"roadmap.upcoming": "{upcoming} à venir",
|
||||
"roadmap.keyFeatures": "Fonctions clés",
|
||||
"roadmap.status.released": "Publié",
|
||||
"roadmap.status.current": "En cours",
|
||||
"roadmap.status.dev": "En développement",
|
||||
"roadmap.status.planned": "Planifié",
|
||||
"roadmap.status.research": "Recherche",
|
||||
"hero.headlineTop": "Une ligne directe",
|
||||
"hero.headlineBottom": "que vous seuls pouvez lire.",
|
||||
"hero.subheading": "Les clés sont créées sur votre appareil et échangées directement entre pairs. Aucun compte, aucun serveur ne conserve vos messages.",
|
||||
|
||||
@@ -73,11 +73,6 @@ export const DICTIONARY = {
|
||||
"roadmap.progress": "{shipped} מתוך {total} אבני דרך הושלמו",
|
||||
"roadmap.upcoming": "{upcoming} בדרך",
|
||||
"roadmap.keyFeatures": "יכולות מרכזיות",
|
||||
"roadmap.status.released": "שוחרר",
|
||||
"roadmap.status.current": "נוכחי",
|
||||
"roadmap.status.dev": "בפיתוח",
|
||||
"roadmap.status.planned": "מתוכנן",
|
||||
"roadmap.status.research": "מחקר",
|
||||
"hero.headlineTop": "קו ישיר",
|
||||
"hero.headlineBottom": "שרק שניכם יכולים לקרוא.",
|
||||
"hero.subheading": "המפתחות נוצרים במכשיר שלכם ומוחלפים עמית־לעמית. בלי חשבונות, בלי שרתים ששומרים את ההודעות.",
|
||||
|
||||
@@ -73,11 +73,6 @@ export const DICTIONARY = {
|
||||
"roadmap.progress": "{total} में से {shipped} पड़ाव पूरे",
|
||||
"roadmap.upcoming": "{upcoming} बाक़ी",
|
||||
"roadmap.keyFeatures": "मुख्य विशेषताएँ",
|
||||
"roadmap.status.released": "जारी",
|
||||
"roadmap.status.current": "अभी चालू",
|
||||
"roadmap.status.dev": "विकास में",
|
||||
"roadmap.status.planned": "नियोजित",
|
||||
"roadmap.status.research": "शोध",
|
||||
"hero.headlineTop": "एक सीधी लाइन,",
|
||||
"hero.headlineBottom": "जिसे सिर्फ़ आप दोनों पढ़ सकें।",
|
||||
"hero.subheading": "कुंजियाँ आपके उपकरण पर बनती हैं और सीधे दोनों पक्षों के बीच बदली जाती हैं। न कोई खाता, न कोई सर्वर जो आपके संदेश रखे।",
|
||||
|
||||
@@ -73,11 +73,6 @@ export const DICTIONARY = {
|
||||
"roadmap.progress": "{total}개 중 {shipped}개 완료",
|
||||
"roadmap.upcoming": "{upcoming}개 남음",
|
||||
"roadmap.keyFeatures": "주요 기능",
|
||||
"roadmap.status.released": "출시됨",
|
||||
"roadmap.status.current": "진행 중",
|
||||
"roadmap.status.dev": "개발 중",
|
||||
"roadmap.status.planned": "예정",
|
||||
"roadmap.status.research": "연구",
|
||||
"hero.headlineTop": "두 사람만 읽을 수 있는",
|
||||
"hero.headlineBottom": "직통 회선.",
|
||||
"hero.subheading": "키는 여러분의 기기에서 만들어지고 두 기기 사이에서 곧바로 교환됩니다. 계정도 없고 메시지를 보관하는 서버도 없습니다.",
|
||||
|
||||
@@ -73,11 +73,6 @@ export const DICTIONARY = {
|
||||
"roadmap.progress": "Пройдено {shipped} из {total} этапов",
|
||||
"roadmap.upcoming": "{upcoming} впереди",
|
||||
"roadmap.keyFeatures": "Ключевые возможности",
|
||||
"roadmap.status.released": "Выпущено",
|
||||
"roadmap.status.current": "Текущий",
|
||||
"roadmap.status.dev": "В разработке",
|
||||
"roadmap.status.planned": "Запланировано",
|
||||
"roadmap.status.research": "Исследование",
|
||||
"hero.headlineTop": "Прямая линия,",
|
||||
"hero.headlineBottom": "которую прочитаете только вы двое.",
|
||||
"hero.subheading": "Ключи создаются на вашем устройстве и передаются напрямую между участниками. Без учётных записей и без серверов, хранящих ваши сообщения.",
|
||||
|
||||
@@ -73,11 +73,6 @@ export const DICTIONARY = {
|
||||
"roadmap.progress": "Пройдено {shipped} з {total} етапів",
|
||||
"roadmap.upcoming": "{upcoming} попереду",
|
||||
"roadmap.keyFeatures": "Ключові можливості",
|
||||
"roadmap.status.released": "Випущено",
|
||||
"roadmap.status.current": "Поточний",
|
||||
"roadmap.status.dev": "У розробці",
|
||||
"roadmap.status.planned": "Заплановано",
|
||||
"roadmap.status.research": "Дослідження",
|
||||
"hero.headlineTop": "Пряма лінія,",
|
||||
"hero.headlineBottom": "яку прочитаєте лише ви двоє.",
|
||||
"hero.subheading": "Ключі створюються на вашому пристрої й передаються напряму між учасниками. Без облікових записів і без серверів, що зберігають ваші повідомлення.",
|
||||
|
||||
@@ -73,11 +73,6 @@ export const DICTIONARY = {
|
||||
"roadmap.progress": "{total} میں سے {shipped} سنگِ میل مکمل",
|
||||
"roadmap.upcoming": "{upcoming} راستے میں",
|
||||
"roadmap.keyFeatures": "نمایاں خصوصیات",
|
||||
"roadmap.status.released": "جاری ہوا",
|
||||
"roadmap.status.current": "موجودہ",
|
||||
"roadmap.status.dev": "زیرِ تعمیر",
|
||||
"roadmap.status.planned": "منصوبہ بند",
|
||||
"roadmap.status.research": "تحقیق",
|
||||
"hero.headlineTop": "ایک سیدھی لکیر",
|
||||
"hero.headlineBottom": "جسے صرف آپ دونوں پڑھ سکتے ہیں۔",
|
||||
"hero.subheading": "کلیدیں آپ کے آلے پر بنتی ہیں اور ہمسطح تبادلہ ہوتا ہے۔ نہ اکاؤنٹ، نہ کوئی سرور جو آپ کے پیغام محفوظ کرے۔",
|
||||
|
||||
@@ -73,11 +73,6 @@ export const DICTIONARY = {
|
||||
"roadmap.progress": "已完成 {total} 个里程碑中的 {shipped} 个",
|
||||
"roadmap.upcoming": "还有 {upcoming} 个",
|
||||
"roadmap.keyFeatures": "核心功能",
|
||||
"roadmap.status.released": "已发布",
|
||||
"roadmap.status.current": "进行中",
|
||||
"roadmap.status.dev": "开发中",
|
||||
"roadmap.status.planned": "已规划",
|
||||
"roadmap.status.research": "研究中",
|
||||
"hero.headlineTop": "一条只有你们两人",
|
||||
"hero.headlineBottom": "才能读懂的直连线路。",
|
||||
"hero.subheading": "密钥在你的设备上生成,并在两端之间直接交换。无需账号,没有服务器保存你的消息。",
|
||||
|
||||
@@ -11,7 +11,7 @@ let DYNAMIC_CACHE = 'securebit-pwa-dynamic-v4.7.56';
|
||||
// Build stamp — rewritten by scripts/post-build.js on every release so this file's
|
||||
// bytes change each deploy. That is what makes the browser detect a new Service Worker,
|
||||
// reinstall it, drop stale caches and (via controllerchange) prompt the page to update.
|
||||
const SW_BUILD_VERSION = '1790208243441';
|
||||
const SW_BUILD_VERSION = '1790219928897';
|
||||
|
||||
// Locale subdirectories, rewritten by scripts/build-i18n.js. Each localized page is a
|
||||
// separate document at its own URL, so the shell has to be cached and served per
|
||||
|
||||
@@ -384,13 +384,19 @@ const template = read('templates/index.template.html');
|
||||
const roadmap = read('src/components/ui/Roadmap.jsx');
|
||||
assert.equal(/parseInt\([^)]*\.slice\(1\)/.test(roadmap), false,
|
||||
'a var() reference cannot be split into channels by hand; publish the channels instead');
|
||||
assert.match(roadmap, /rgb: "var\(--sb-[a-z0-9-]+-rgb\)"/,
|
||||
'the status table must carry the channels alongside the colour');
|
||||
|
||||
// The status pill is desktop-only: on a phone the word does not fit, and a bordered
|
||||
// box around one dot repeats what the timeline marker already shows.
|
||||
assert.match(roadmap, /\{!isMobile && \(\s*\n\s*<span style=\{\{ display: 'inline-flex'/,
|
||||
'the whole status pill must be hidden on mobile, not only its label');
|
||||
// The status pills (Released, In development, ...) were removed on every screen: the
|
||||
// timeline marker already says where a milestone stands. Neither the component nor
|
||||
// any language may bring the words back half-way.
|
||||
assert.equal(/roadmap\.status\./.test(roadmap), false,
|
||||
'the roadmap must not render a status label');
|
||||
const localeFiles = readdirSync(new URL('../locales', import.meta.url))
|
||||
.filter((f) => /^[a-z]{2}\.json$/.test(f));
|
||||
assert.ok(localeFiles.length >= 13, 'every language file is checked');
|
||||
for (const file of localeFiles) {
|
||||
const raw = read(`locales/${file}`);
|
||||
assert.equal(/"roadmap\.status\./.test(raw), false, `${file} still carries roadmap status labels`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('✅ theme switching');
|
||||
|
||||
+19
-19
@@ -30,18 +30,18 @@
|
||||
|
||||
<!-- PWA Manifest -->
|
||||
<link rel="manifest" href="/uk/manifest.json">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790208243441">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790219928897">
|
||||
|
||||
<!-- Blocking, and above the stylesheet on purpose: this stamps data-theme on <html>
|
||||
from localStorage while the parser is still in <head>, so the page paints in the
|
||||
chosen theme on the first frame instead of flashing dark and correcting itself.
|
||||
Cannot be inline (CSP is script-src 'self') and cannot be a module (deferred). -->
|
||||
<script src="/src/scripts/theme-boot.js?v=1790208243441"></script>
|
||||
<script src="/src/scripts/theme-boot.js?v=1790219928897"></script>
|
||||
|
||||
<!-- Blocking, and in <head> on purpose: beforeinstallprompt fires once and is
|
||||
not replayed, so the listener has to exist before Chrome decides the page
|
||||
is installable. Deferred/module scripts are already too late. -->
|
||||
<script src="/src/scripts/pwa-install-capture.js?v=1790208243441"></script>
|
||||
<script src="/src/scripts/pwa-install-capture.js?v=1790219928897"></script>
|
||||
|
||||
<!-- PWA Meta Tags -->
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
@@ -116,7 +116,7 @@
|
||||
<link rel="apple-touch-startup-image" media="screen and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/logo/splash/splash_screens/8.3__iPad_Mini_portrait.png">
|
||||
|
||||
<!-- Apple Touch Icons -->
|
||||
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1790208243441">
|
||||
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1790219928897">
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="/logo/icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="/logo/icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="/logo/icon-72x72.png">
|
||||
@@ -125,7 +125,7 @@
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="/logo/icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="/logo/icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="/logo/icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1790208243441">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1790219928897">
|
||||
|
||||
<!-- Microsoft Tiles -->
|
||||
<meta name="msapplication-TileColor" content="#ff6b35">
|
||||
@@ -264,7 +264,7 @@
|
||||
<!-- Render-blocking JS is deferred: classic deferred scripts and module scripts
|
||||
both execute in document order after parsing, so React still runs before the
|
||||
app modules below, but the parser / first paint is no longer blocked. -->
|
||||
<script defer src="/config/ice-servers.js?v=1790208243441"></script>
|
||||
<script defer src="/config/ice-servers.js?v=1790219928897"></script>
|
||||
<script defer src="/libs/react/react.production.min.js"></script>
|
||||
<script defer src="/libs/react-dom/react-dom.production.min.js"></script>
|
||||
<!-- Prism syntax highlighting (vendored, offline). Tokenizes code as TEXT only —
|
||||
@@ -278,8 +278,8 @@
|
||||
the end of <body>: 21 KB of CSS in total, but eight round trips before the
|
||||
browser could paint, which GTmetrix measured at 441 ms on a throttled mobile
|
||||
connection. Bytes were never the problem; requests were. -->
|
||||
<link rel="stylesheet" href="/assets/app.css?v=1790208243441">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790208243441">
|
||||
<link rel="stylesheet" href="/assets/app.css?v=1790219928897">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790219928897">
|
||||
<!-- Preload only the fonts needed for first paint. Inter is one variable file that
|
||||
answers for every weight, so there is one to preload rather than the two of five
|
||||
copies this used to name. fa-solid covers the bulk of UI icons; fa-regular and
|
||||
@@ -287,19 +287,19 @@
|
||||
<link rel="preload" href="/assets/fontawesome/webfonts/fa-solid-900.subset.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<link rel="preload" href="/assets/fonts/inter/files/inter-latin.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<!-- Non-critical CSS (FontAwesome ~102KB, Prism) loaded async — no longer blocks paint. -->
|
||||
<script defer src="/src/scripts/load-async-css.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/load-async-css.js?v=1790219928897"></script>
|
||||
<noscript>
|
||||
<link rel="stylesheet" href="/libs/prism/prism.css">
|
||||
</noscript>
|
||||
<script defer src="/src/scripts/fa-check.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/fa-check.js?v=1790219928897"></script>
|
||||
<!-- This locale's dictionary, registered before anything can ask for a string.
|
||||
Only the default locale's is bundled (src/i18n/index.js imports it, because t()
|
||||
falls back to it); every other page loads its own here instead of all thirteen
|
||||
riding along inside dist/app.js. Absent on the default locale's own page. -->
|
||||
<script type="module" src="/src/i18n/dict/uk.js?v=1790208243441"></script>
|
||||
<script type="module" src="/src/i18n/dict/uk.js?v=1790219928897"></script>
|
||||
<!-- Update Manager - система принудительного обновления -->
|
||||
<script defer src="/src/utils/updateManager.js?v=1790208243441"></script>
|
||||
<script type="module" src="/src/components/UpdateChecker.jsx?v=1790208243441"></script>
|
||||
<script defer src="/src/utils/updateManager.js?v=1790219928897"></script>
|
||||
<script type="module" src="/src/components/UpdateChecker.jsx?v=1790219928897"></script>
|
||||
<!-- /dist/qr-local.js is deliberately absent: app-boot.js fetches it once the
|
||||
app has mounted and the browser is idle, so the 142 KB it weighs is off the
|
||||
first load. src/components/QRScanner.js used to be here too and registered
|
||||
@@ -487,12 +487,12 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="module" src="/dist/app-boot.js?v=1790208243441"></script>
|
||||
<script type="module" src="/dist/app.js?v=1790208243441"></script>
|
||||
<script type="module" src="/dist/app-boot.js?v=1790219928897"></script>
|
||||
<script type="module" src="/dist/app.js?v=1790219928897"></script>
|
||||
|
||||
<script defer src="/src/scripts/pwa-register.js?v=1790208243441"></script>
|
||||
<script src="/src/pwa/install-prompt.js?v=1790208243441" type="module"></script>
|
||||
<script src="/src/pwa/pwa-manager.js?v=1790208243441" type="module"></script>
|
||||
<script defer src="/src/scripts/pwa-offline-test.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/pwa-register.js?v=1790219928897"></script>
|
||||
<script src="/src/pwa/install-prompt.js?v=1790219928897" type="module"></script>
|
||||
<script src="/src/pwa/pwa-manager.js?v=1790219928897" type="module"></script>
|
||||
<script defer src="/src/scripts/pwa-offline-test.js?v=1790219928897"></script>
|
||||
</body>
|
||||
</html>
|
||||
+19
-19
@@ -30,18 +30,18 @@
|
||||
|
||||
<!-- PWA Manifest -->
|
||||
<link rel="manifest" href="/ur/manifest.json">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790208243441">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790219928897">
|
||||
|
||||
<!-- Blocking, and above the stylesheet on purpose: this stamps data-theme on <html>
|
||||
from localStorage while the parser is still in <head>, so the page paints in the
|
||||
chosen theme on the first frame instead of flashing dark and correcting itself.
|
||||
Cannot be inline (CSP is script-src 'self') and cannot be a module (deferred). -->
|
||||
<script src="/src/scripts/theme-boot.js?v=1790208243441"></script>
|
||||
<script src="/src/scripts/theme-boot.js?v=1790219928897"></script>
|
||||
|
||||
<!-- Blocking, and in <head> on purpose: beforeinstallprompt fires once and is
|
||||
not replayed, so the listener has to exist before Chrome decides the page
|
||||
is installable. Deferred/module scripts are already too late. -->
|
||||
<script src="/src/scripts/pwa-install-capture.js?v=1790208243441"></script>
|
||||
<script src="/src/scripts/pwa-install-capture.js?v=1790219928897"></script>
|
||||
|
||||
<!-- PWA Meta Tags -->
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
@@ -116,7 +116,7 @@
|
||||
<link rel="apple-touch-startup-image" media="screen and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/logo/splash/splash_screens/8.3__iPad_Mini_portrait.png">
|
||||
|
||||
<!-- Apple Touch Icons -->
|
||||
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1790208243441">
|
||||
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1790219928897">
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="/logo/icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="/logo/icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="/logo/icon-72x72.png">
|
||||
@@ -125,7 +125,7 @@
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="/logo/icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="/logo/icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="/logo/icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1790208243441">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1790219928897">
|
||||
|
||||
<!-- Microsoft Tiles -->
|
||||
<meta name="msapplication-TileColor" content="#ff6b35">
|
||||
@@ -264,7 +264,7 @@
|
||||
<!-- Render-blocking JS is deferred: classic deferred scripts and module scripts
|
||||
both execute in document order after parsing, so React still runs before the
|
||||
app modules below, but the parser / first paint is no longer blocked. -->
|
||||
<script defer src="/config/ice-servers.js?v=1790208243441"></script>
|
||||
<script defer src="/config/ice-servers.js?v=1790219928897"></script>
|
||||
<script defer src="/libs/react/react.production.min.js"></script>
|
||||
<script defer src="/libs/react-dom/react-dom.production.min.js"></script>
|
||||
<!-- Prism syntax highlighting (vendored, offline). Tokenizes code as TEXT only —
|
||||
@@ -278,8 +278,8 @@
|
||||
the end of <body>: 21 KB of CSS in total, but eight round trips before the
|
||||
browser could paint, which GTmetrix measured at 441 ms on a throttled mobile
|
||||
connection. Bytes were never the problem; requests were. -->
|
||||
<link rel="stylesheet" href="/assets/app.css?v=1790208243441">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790208243441">
|
||||
<link rel="stylesheet" href="/assets/app.css?v=1790219928897">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790219928897">
|
||||
<!-- Preload only the fonts needed for first paint. Inter is one variable file that
|
||||
answers for every weight, so there is one to preload rather than the two of five
|
||||
copies this used to name. fa-solid covers the bulk of UI icons; fa-regular and
|
||||
@@ -287,19 +287,19 @@
|
||||
<link rel="preload" href="/assets/fontawesome/webfonts/fa-solid-900.subset.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<link rel="preload" href="/assets/fonts/inter/files/inter-latin.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<!-- Non-critical CSS (FontAwesome ~102KB, Prism) loaded async — no longer blocks paint. -->
|
||||
<script defer src="/src/scripts/load-async-css.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/load-async-css.js?v=1790219928897"></script>
|
||||
<noscript>
|
||||
<link rel="stylesheet" href="/libs/prism/prism.css">
|
||||
</noscript>
|
||||
<script defer src="/src/scripts/fa-check.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/fa-check.js?v=1790219928897"></script>
|
||||
<!-- This locale's dictionary, registered before anything can ask for a string.
|
||||
Only the default locale's is bundled (src/i18n/index.js imports it, because t()
|
||||
falls back to it); every other page loads its own here instead of all thirteen
|
||||
riding along inside dist/app.js. Absent on the default locale's own page. -->
|
||||
<script type="module" src="/src/i18n/dict/ur.js?v=1790208243441"></script>
|
||||
<script type="module" src="/src/i18n/dict/ur.js?v=1790219928897"></script>
|
||||
<!-- Update Manager - система принудительного обновления -->
|
||||
<script defer src="/src/utils/updateManager.js?v=1790208243441"></script>
|
||||
<script type="module" src="/src/components/UpdateChecker.jsx?v=1790208243441"></script>
|
||||
<script defer src="/src/utils/updateManager.js?v=1790219928897"></script>
|
||||
<script type="module" src="/src/components/UpdateChecker.jsx?v=1790219928897"></script>
|
||||
<!-- /dist/qr-local.js is deliberately absent: app-boot.js fetches it once the
|
||||
app has mounted and the browser is idle, so the 142 KB it weighs is off the
|
||||
first load. src/components/QRScanner.js used to be here too and registered
|
||||
@@ -487,12 +487,12 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="module" src="/dist/app-boot.js?v=1790208243441"></script>
|
||||
<script type="module" src="/dist/app.js?v=1790208243441"></script>
|
||||
<script type="module" src="/dist/app-boot.js?v=1790219928897"></script>
|
||||
<script type="module" src="/dist/app.js?v=1790219928897"></script>
|
||||
|
||||
<script defer src="/src/scripts/pwa-register.js?v=1790208243441"></script>
|
||||
<script src="/src/pwa/install-prompt.js?v=1790208243441" type="module"></script>
|
||||
<script src="/src/pwa/pwa-manager.js?v=1790208243441" type="module"></script>
|
||||
<script defer src="/src/scripts/pwa-offline-test.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/pwa-register.js?v=1790219928897"></script>
|
||||
<script src="/src/pwa/install-prompt.js?v=1790219928897" type="module"></script>
|
||||
<script src="/src/pwa/pwa-manager.js?v=1790219928897" type="module"></script>
|
||||
<script defer src="/src/scripts/pwa-offline-test.js?v=1790219928897"></script>
|
||||
</body>
|
||||
</html>
|
||||
+19
-19
@@ -30,18 +30,18 @@
|
||||
|
||||
<!-- PWA Manifest -->
|
||||
<link rel="manifest" href="/zh/manifest.json">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790208243441">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790219928897">
|
||||
|
||||
<!-- Blocking, and above the stylesheet on purpose: this stamps data-theme on <html>
|
||||
from localStorage while the parser is still in <head>, so the page paints in the
|
||||
chosen theme on the first frame instead of flashing dark and correcting itself.
|
||||
Cannot be inline (CSP is script-src 'self') and cannot be a module (deferred). -->
|
||||
<script src="/src/scripts/theme-boot.js?v=1790208243441"></script>
|
||||
<script src="/src/scripts/theme-boot.js?v=1790219928897"></script>
|
||||
|
||||
<!-- Blocking, and in <head> on purpose: beforeinstallprompt fires once and is
|
||||
not replayed, so the listener has to exist before Chrome decides the page
|
||||
is installable. Deferred/module scripts are already too late. -->
|
||||
<script src="/src/scripts/pwa-install-capture.js?v=1790208243441"></script>
|
||||
<script src="/src/scripts/pwa-install-capture.js?v=1790219928897"></script>
|
||||
|
||||
<!-- PWA Meta Tags -->
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
@@ -116,7 +116,7 @@
|
||||
<link rel="apple-touch-startup-image" media="screen and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/logo/splash/splash_screens/8.3__iPad_Mini_portrait.png">
|
||||
|
||||
<!-- Apple Touch Icons -->
|
||||
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1790208243441">
|
||||
<link rel="apple-touch-icon" href="/logo/icon-180x180.png?v=1790219928897">
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="/logo/icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="/logo/icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="/logo/icon-72x72.png">
|
||||
@@ -125,7 +125,7 @@
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="/logo/icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="/logo/icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="/logo/icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1790208243441">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/logo/icon-180x180.png?v=1790219928897">
|
||||
|
||||
<!-- Microsoft Tiles -->
|
||||
<meta name="msapplication-TileColor" content="#ff6b35">
|
||||
@@ -264,7 +264,7 @@
|
||||
<!-- Render-blocking JS is deferred: classic deferred scripts and module scripts
|
||||
both execute in document order after parsing, so React still runs before the
|
||||
app modules below, but the parser / first paint is no longer blocked. -->
|
||||
<script defer src="/config/ice-servers.js?v=1790208243441"></script>
|
||||
<script defer src="/config/ice-servers.js?v=1790219928897"></script>
|
||||
<script defer src="/libs/react/react.production.min.js"></script>
|
||||
<script defer src="/libs/react-dom/react-dom.production.min.js"></script>
|
||||
<!-- Prism syntax highlighting (vendored, offline). Tokenizes code as TEXT only —
|
||||
@@ -278,8 +278,8 @@
|
||||
the end of <body>: 21 KB of CSS in total, but eight round trips before the
|
||||
browser could paint, which GTmetrix measured at 441 ms on a throttled mobile
|
||||
connection. Bytes were never the problem; requests were. -->
|
||||
<link rel="stylesheet" href="/assets/app.css?v=1790208243441">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790208243441">
|
||||
<link rel="stylesheet" href="/assets/app.css?v=1790219928897">
|
||||
<link rel="icon" type="image/x-icon" href="/logo/favicon.ico?v=1790219928897">
|
||||
<!-- Preload only the fonts needed for first paint. Inter is one variable file that
|
||||
answers for every weight, so there is one to preload rather than the two of five
|
||||
copies this used to name. fa-solid covers the bulk of UI icons; fa-regular and
|
||||
@@ -287,19 +287,19 @@
|
||||
<link rel="preload" href="/assets/fontawesome/webfonts/fa-solid-900.subset.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<link rel="preload" href="/assets/fonts/inter/files/inter-latin.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<!-- Non-critical CSS (FontAwesome ~102KB, Prism) loaded async — no longer blocks paint. -->
|
||||
<script defer src="/src/scripts/load-async-css.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/load-async-css.js?v=1790219928897"></script>
|
||||
<noscript>
|
||||
<link rel="stylesheet" href="/libs/prism/prism.css">
|
||||
</noscript>
|
||||
<script defer src="/src/scripts/fa-check.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/fa-check.js?v=1790219928897"></script>
|
||||
<!-- This locale's dictionary, registered before anything can ask for a string.
|
||||
Only the default locale's is bundled (src/i18n/index.js imports it, because t()
|
||||
falls back to it); every other page loads its own here instead of all thirteen
|
||||
riding along inside dist/app.js. Absent on the default locale's own page. -->
|
||||
<script type="module" src="/src/i18n/dict/zh.js?v=1790208243441"></script>
|
||||
<script type="module" src="/src/i18n/dict/zh.js?v=1790219928897"></script>
|
||||
<!-- Update Manager - система принудительного обновления -->
|
||||
<script defer src="/src/utils/updateManager.js?v=1790208243441"></script>
|
||||
<script type="module" src="/src/components/UpdateChecker.jsx?v=1790208243441"></script>
|
||||
<script defer src="/src/utils/updateManager.js?v=1790219928897"></script>
|
||||
<script type="module" src="/src/components/UpdateChecker.jsx?v=1790219928897"></script>
|
||||
<!-- /dist/qr-local.js is deliberately absent: app-boot.js fetches it once the
|
||||
app has mounted and the browser is idle, so the 142 KB it weighs is off the
|
||||
first load. src/components/QRScanner.js used to be here too and registered
|
||||
@@ -487,12 +487,12 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="module" src="/dist/app-boot.js?v=1790208243441"></script>
|
||||
<script type="module" src="/dist/app.js?v=1790208243441"></script>
|
||||
<script type="module" src="/dist/app-boot.js?v=1790219928897"></script>
|
||||
<script type="module" src="/dist/app.js?v=1790219928897"></script>
|
||||
|
||||
<script defer src="/src/scripts/pwa-register.js?v=1790208243441"></script>
|
||||
<script src="/src/pwa/install-prompt.js?v=1790208243441" type="module"></script>
|
||||
<script src="/src/pwa/pwa-manager.js?v=1790208243441" type="module"></script>
|
||||
<script defer src="/src/scripts/pwa-offline-test.js?v=1790208243441"></script>
|
||||
<script defer src="/src/scripts/pwa-register.js?v=1790219928897"></script>
|
||||
<script src="/src/pwa/install-prompt.js?v=1790219928897" type="module"></script>
|
||||
<script src="/src/pwa/pwa-manager.js?v=1790219928897" type="module"></script>
|
||||
<script defer src="/src/scripts/pwa-offline-test.js?v=1790219928897"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user