@networkpro/web 1.12.8 → 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/CHANGELOG.md +64 -1
  2. package/README.md +8 -8
  3. package/cspell.json +1 -0
  4. package/eslint.config.mjs +48 -48
  5. package/jsconfig.template.jsonc +3 -1
  6. package/netlify/edge-functions/csp-report.js +31 -31
  7. package/package.json +6 -6
  8. package/playwright.config.js +14 -14
  9. package/postcss.config.mjs +1 -1
  10. package/scripts/auditScripts.js +16 -16
  11. package/scripts/bundleCss.js +5 -5
  12. package/scripts/checkEnv.js +6 -6
  13. package/scripts/checkNode.js +10 -10
  14. package/scripts/checkVersions.js +6 -6
  15. package/scripts/flattenHeaders.js +13 -13
  16. package/scripts/generateTest.js +5 -5
  17. package/scripts/openReport.js +3 -3
  18. package/scripts/validateHeaders.js +13 -13
  19. package/src/hooks.client.ts +1 -1
  20. package/src/hooks.server.js +31 -31
  21. package/src/lib/components/Badges.svelte +9 -9
  22. package/src/lib/components/CodeBlock.svelte +13 -0
  23. package/src/lib/components/ContainerSection.svelte +1 -1
  24. package/src/lib/components/FullWidthSection.svelte +3 -3
  25. package/src/lib/components/LegalNav.svelte +6 -6
  26. package/src/lib/components/Logo.svelte +9 -9
  27. package/src/lib/components/MetaTags.svelte +3 -3
  28. package/src/lib/components/PWAInstallButton.svelte +4 -4
  29. package/src/lib/components/RedirectPage.svelte +4 -4
  30. package/src/lib/components/SocialMedia.svelte +16 -16
  31. package/src/lib/components/foss/FossItemContent.svelte +18 -18
  32. package/src/lib/components/layout/Footer.svelte +17 -17
  33. package/src/lib/components/layout/HeaderDefault.svelte +16 -16
  34. package/src/lib/components/layout/HeaderHome.svelte +14 -14
  35. package/src/lib/images.js +34 -34
  36. package/src/lib/index.js +15 -15
  37. package/src/lib/meta.js +29 -29
  38. package/src/lib/pages/AboutContent.svelte +24 -24
  39. package/src/lib/pages/FossContent.svelte +12 -12
  40. package/src/lib/pages/HomeContent.svelte +6 -6
  41. package/src/lib/pages/LicenseContent.svelte +38 -38
  42. package/src/lib/pages/PGPContent.svelte +61 -29
  43. package/src/lib/pages/PrivacyContent.svelte +39 -39
  44. package/src/lib/pages/PrivacyDashboard.svelte +12 -12
  45. package/src/lib/pages/TermsConditionsContent.svelte +28 -28
  46. package/src/lib/pages/TermsUseContent.svelte +26 -26
  47. package/src/lib/registerServiceWorker.js +25 -25
  48. package/src/lib/stores/posthog.js +13 -13
  49. package/src/lib/stores/trackingPreferences.js +19 -19
  50. package/src/lib/styles/css/default.css +5 -1
  51. package/src/lib/styles/global.min.css +1 -1
  52. package/src/lib/unregisterServiceWorker.js +1 -1
  53. package/src/lib/utils/purify.js +4 -4
  54. package/src/lib/utils/utm.js +2 -2
  55. package/src/routes/+error.svelte +4 -4
  56. package/src/routes/+layout.js +6 -6
  57. package/src/routes/+layout.svelte +29 -29
  58. package/src/routes/+page.server.js +2 -2
  59. package/src/routes/+page.svelte +9 -9
  60. package/src/routes/about/+page.server.js +2 -2
  61. package/src/routes/about/+page.svelte +7 -7
  62. package/src/routes/api/mock-csp/+server.js +3 -3
  63. package/src/routes/consultation/+page.svelte +5 -5
  64. package/src/routes/contact/+page.svelte +5 -5
  65. package/src/routes/foss-spotlight/+page.server.js +2 -2
  66. package/src/routes/foss-spotlight/+page.svelte +7 -7
  67. package/src/routes/license/+page.server.js +2 -2
  68. package/src/routes/license/+page.svelte +7 -7
  69. package/src/routes/pgp/+page.server.js +2 -2
  70. package/src/routes/pgp/+page.svelte +7 -7
  71. package/src/routes/pgp/[key]/+server.js +9 -9
  72. package/src/routes/privacy/+page.server.js +2 -2
  73. package/src/routes/privacy/+page.svelte +7 -7
  74. package/src/routes/privacy-dashboard/+page.server.js +2 -2
  75. package/src/routes/privacy-dashboard/+page.svelte +8 -8
  76. package/src/routes/privacy-rights/+page.svelte +5 -5
  77. package/src/routes/status/+page.server.js +2 -2
  78. package/src/routes/terms-conditions/+page.server.js +2 -2
  79. package/src/routes/terms-conditions/+page.svelte +7 -7
  80. package/src/routes/terms-of-use/+page.server.js +2 -2
  81. package/src/routes/terms-of-use/+page.svelte +7 -7
  82. package/src/service-worker.js +86 -85
  83. package/static/disableSw.js +2 -2
  84. package/static/img/powered-by-proton.svg +1 -0
  85. package/static/offline.html +7 -7
  86. package/static/sitemap.xml +64 -4
  87. package/stylelint.config.js +56 -56
  88. package/svelte.config.js +6 -6
  89. package/tests/e2e/app.spec.js +25 -25
  90. package/tests/e2e/mobile.spec.js +18 -18
  91. package/tests/e2e/shared/helpers.js +4 -4
  92. package/tests/internal/auditCoverage.test.js +24 -24
  93. package/tests/unit/checkEnv.test.js +10 -10
  94. package/tests/unit/checkVersions.test.js +4 -4
  95. package/tests/unit/csp-report.test.js +24 -24
  96. package/tests/unit/demo.test.js +3 -3
  97. package/tests/unit/lib/utils/purify.test.js +12 -12
  98. package/tests/unit/routes/page.svelte.test.js +10 -10
  99. package/tests/unit/unregisterServiceWorker.test.js +5 -5
  100. package/tests/unit/utm.test.js +13 -13
  101. package/vite.config.js +5 -5
  102. package/vitest-setup-client.js +4 -4
  103. package/vitest.config.client.js +15 -15
  104. package/vitest.config.server.js +13 -13
@@ -13,13 +13,13 @@ const sw = /** @type {ServiceWorkerGlobalScope} */ (
13
13
 
14
14
  /// <reference types="vite/client" />
15
15
 
16
- const isDev = location.hostname === "localhost";
16
+ const isDev = location.hostname === 'localhost';
17
17
  const disallowedHosts = [
18
- "us.i.posthog.com", // Add PostHog to disallowed hosts
19
- "posthog.com", // Add PostHog to disallowed hosts
18
+ 'us.i.posthog.com', // Add PostHog to disallowed hosts
19
+ 'posthog.com', // Add PostHog to disallowed hosts
20
20
  ];
21
21
 
22
- import { build, files, version } from "$service-worker";
22
+ import { build, files, version } from '$service-worker';
23
23
 
24
24
  /** @type {string} */
25
25
  const CACHE = `cache-${version}`;
@@ -28,37 +28,38 @@ const CACHE = `cache-${version}`;
28
28
  const excludedAssets = [];
29
29
 
30
30
  const IGNORE_PATHS = new Set([
31
- "/img/banner-1280x640.png",
32
- "/img/logo-transparent.png",
33
- "/img/logo.png",
34
- "/img/svelte.png",
35
- "/pgp/pgp-github.png",
36
- "/pgp/pgp-github.webp",
37
- "/pgp/contact@s.neteng.pro.asc",
38
- "/pgp/github@sl.neteng.cc.asc",
39
- "/pgp/security@s.neteng.pro.asc",
40
- "/pgp/support@neteng.pro.asc",
41
- "/pgp/vcard.png",
42
- "/pgp/vcard.webp",
43
- "/screenshots/desktop-foss.png",
44
- "/webfonts/fa-brands-400.ttf",
45
- "/webfonts/fa-solid-900.ttf",
46
- "/robots.txt",
47
- "/sitemap.xml",
48
- "/CNAME",
31
+ '/.well-known/security.txt.asc',
32
+ '/img/banner-1280x640.png',
33
+ '/img/logo-transparent.png',
34
+ '/img/logo.png',
35
+ '/img/svelte.png',
36
+ '/pgp/pgp-github.png',
37
+ '/pgp/pgp-github.webp',
38
+ '/pgp/contact@s.neteng.pro.asc',
39
+ '/pgp/github@sl.neteng.cc.asc',
40
+ '/pgp/security@s.neteng.pro.asc',
41
+ '/pgp/support@neteng.pro.asc',
42
+ '/pgp/vcard.png',
43
+ '/pgp/vcard.webp',
44
+ '/screenshots/desktop-foss.png',
45
+ '/webfonts/fa-brands-400.ttf',
46
+ '/webfonts/fa-solid-900.ttf',
47
+ '/robots.txt',
48
+ '/sitemap.xml',
49
+ '/CNAME',
49
50
  ]);
50
51
 
51
52
  /** @type {string[]} */
52
53
  const ASSETS = [
53
54
  ...new Set(
54
- [...build, ...files, "/offline.html"].filter((path) => {
55
+ [...build, ...files, '/offline.html'].filter((path) => {
55
56
  try {
56
57
  const url = new URL(path, location.origin);
57
58
  const hostname = url.hostname;
58
59
 
59
60
  const shouldExclude =
60
- path.startsWith("http") ||
61
- path.startsWith("/bin/") ||
61
+ path.startsWith('http') ||
62
+ path.startsWith('/bin/') ||
62
63
  disallowedHosts.some(
63
64
  (host) => hostname === host || hostname.endsWith(`.${host}`),
64
65
  ) ||
@@ -68,7 +69,7 @@ const ASSETS = [
68
69
  return !shouldExclude;
69
70
  } catch (err) {
70
71
  if (isDev)
71
- console.warn("[SW] URL parse failed, skipping path:", path, err);
72
+ console.warn('[SW] URL parse failed, skipping path:', path, err);
72
73
  excludedAssets.push(path);
73
74
  return true;
74
75
  }
@@ -80,41 +81,41 @@ const uniqueExcludedAssets = [...new Set(excludedAssets)].sort();
80
81
 
81
82
  /** @type {string[]} */
82
83
  const REQUIRED_ASSETS = [
83
- "/disableSw.js",
84
- "/favicon.ico",
85
- "/icon-192x192.png",
86
- "/icon-512x512-maskable.png",
87
- "/icon-512x512.png",
88
- "/icon-contact.png",
89
- "/icon-services.png",
90
- "/icon-splash.png",
91
- "/img/banner-og-1200x630.png",
92
- "/pgp/pgp-contact.png",
93
- "/pgp/pgp-contact.webp",
94
- "/pgp/pgp-security.png",
95
- "/pgp/pgp-security.webp",
96
- "/pgp/pgp-support.png",
97
- "/pgp/pgp-support.webp",
98
- "/manifest.json",
99
- "/offline.html",
100
- "/offline.min.css",
101
- "/screenshots/desktop-about.png",
102
- "/screenshots/desktop-home.png",
103
- "/screenshots/mobile-foss.png",
104
- "/screenshots/mobile-home.png",
105
- "/styles/brands.min.css",
106
- "/styles/fontawesome.min.css",
107
- "/styles/global.min.css",
108
- "/styles/solid.min.css",
109
- "/webfonts/fa-brands-400.woff2",
110
- "/webfonts/fa-solid-900.woff2",
111
- "/.well-known/dnt-policy-1.0.txt",
112
- "/.well-known/gpc.json",
84
+ '/disableSw.js',
85
+ '/favicon.ico',
86
+ '/icon-192x192.png',
87
+ '/icon-512x512-maskable.png',
88
+ '/icon-512x512.png',
89
+ '/icon-contact.png',
90
+ '/icon-services.png',
91
+ '/icon-splash.png',
92
+ '/img/banner-og-1200x630.png',
93
+ '/pgp/pgp-contact.png',
94
+ '/pgp/pgp-contact.webp',
95
+ '/pgp/pgp-security.png',
96
+ '/pgp/pgp-security.webp',
97
+ '/pgp/pgp-support.png',
98
+ '/pgp/pgp-support.webp',
99
+ '/manifest.json',
100
+ '/offline.html',
101
+ '/offline.min.css',
102
+ '/screenshots/desktop-about.png',
103
+ '/screenshots/desktop-home.png',
104
+ '/screenshots/mobile-foss.png',
105
+ '/screenshots/mobile-home.png',
106
+ '/styles/brands.min.css',
107
+ '/styles/fontawesome.min.css',
108
+ '/styles/global.min.css',
109
+ '/styles/solid.min.css',
110
+ '/webfonts/fa-brands-400.woff2',
111
+ '/webfonts/fa-solid-900.woff2',
112
+ '/.well-known/dnt-policy.txt',
113
+ '/.well-known/gpc.json',
113
114
  ];
114
115
 
115
116
  if (isDev) {
116
- console.log("[SW] Assets to precache:", ASSETS);
117
- console.log("[SW] Excluded assets:", uniqueExcludedAssets);
117
+ console.log('[SW] Assets to precache:', ASSETS);
118
+ console.log('[SW] Excluded assets:', uniqueExcludedAssets);
118
119
  }
119
120
 
120
121
  /**
@@ -151,7 +152,7 @@ async function cacheAssetsSafely(cache, assets, required = []) {
151
152
 
152
153
  const missing = required.filter((req) => !cachedPaths.includes(req));
153
154
  if (missing.length > 0) {
154
- const errorMsg = `[SW] ⚠️ Missing required assets: ${missing.join(", ")}`;
155
+ const errorMsg = `[SW] ⚠️ Missing required assets: ${missing.join(', ')}`;
155
156
  if (isDev) throw new Error(errorMsg);
156
157
  console.error(errorMsg);
157
158
  }
@@ -160,8 +161,8 @@ async function cacheAssetsSafely(cache, assets, required = []) {
160
161
  }
161
162
 
162
163
  // 🔹 Install event
163
- sw.addEventListener("install", (event) => {
164
- if (isDev) console.log("[SW] Install event");
164
+ sw.addEventListener('install', (event) => {
165
+ if (isDev) console.log('[SW] Install event');
165
166
 
166
167
  event.waitUntil(
167
168
  (async () => {
@@ -171,29 +172,29 @@ sw.addEventListener("install", (event) => {
171
172
  try {
172
173
  cachedPaths = await cacheAssetsSafely(cache, ASSETS, REQUIRED_ASSETS);
173
174
  if (isDev) {
174
- console.log("[SW] Cached assets:", cachedPaths);
175
+ console.log('[SW] Cached assets:', cachedPaths);
175
176
  }
176
177
  } catch (err) {
177
178
  if (isDev) throw err;
178
- console.warn("[SW] Error while precaching (non-fatal in prod):", err);
179
+ console.warn('[SW] Error while precaching (non-fatal in prod):', err);
179
180
  }
180
181
 
181
182
  await sw.skipWaiting();
182
- if (isDev) console.log("[SW] skipWaiting() called");
183
+ if (isDev) console.log('[SW] skipWaiting() called');
183
184
  })(),
184
185
  );
185
186
  });
186
187
 
187
188
  // 🔹 Activate event
188
- sw.addEventListener("activate", (event) => {
189
- if (isDev) console.log("[SW] Activate event");
189
+ sw.addEventListener('activate', (event) => {
190
+ if (isDev) console.log('[SW] Activate event');
190
191
  event.waitUntil(
191
192
  (async () => {
192
193
  const tasks = [];
193
194
 
194
195
  if (sw.registration.navigationPreload) {
195
196
  tasks.push(sw.registration.navigationPreload.enable());
196
- if (isDev) console.log("[SW] Navigation preload enabled");
197
+ if (isDev) console.log('[SW] Navigation preload enabled');
197
198
  }
198
199
 
199
200
  tasks.push(
@@ -202,7 +203,7 @@ sw.addEventListener("activate", (event) => {
202
203
  keys
203
204
  .filter((key) => key !== CACHE)
204
205
  .map((key) => {
205
- if (isDev) console.log("[SW] Deleting old cache:", key);
206
+ if (isDev) console.log('[SW] Deleting old cache:', key);
206
207
  return caches.delete(key);
207
208
  }),
208
209
  ),
@@ -212,8 +213,8 @@ sw.addEventListener("activate", (event) => {
212
213
  await Promise.all(tasks);
213
214
  await sw.clients.claim();
214
215
  if (isDev) {
215
- console.log("[SW] clients.claim() called");
216
- console.log("[SW] Scope:", sw.registration.scope);
216
+ console.log('[SW] clients.claim() called');
217
+ console.log('[SW] Scope:', sw.registration.scope);
217
218
  }
218
219
  })(),
219
220
  );
@@ -231,16 +232,16 @@ function shouldSkipDevModule(url) {
231
232
  if (!isDev) return false;
232
233
 
233
234
  return (
234
- url.pathname.startsWith("/@fs") ||
235
- url.pathname.startsWith("/node_modules") ||
236
- url.pathname.includes(".vite") ||
237
- url.pathname.includes(".svelte-kit") ||
235
+ url.pathname.startsWith('/@fs') ||
236
+ url.pathname.startsWith('/node_modules') ||
237
+ url.pathname.includes('.vite') ||
238
+ url.pathname.includes('.svelte-kit') ||
238
239
  !!url.pathname.match(/\.(js|ts|svelte)$/)
239
240
  );
240
241
  }
241
242
 
242
243
  // 🔹 Fetch event
243
- sw.addEventListener("fetch", (event) => {
244
+ sw.addEventListener('fetch', (event) => {
244
245
  const requestUrl = new URL(event.request.url);
245
246
 
246
247
  // ✅ Skip cross-origin requests
@@ -249,23 +250,23 @@ sw.addEventListener("fetch", (event) => {
249
250
  // ✅ Skip internal dev/module files (only in dev)
250
251
  if (shouldSkipDevModule(requestUrl)) return;
251
252
 
252
- if (isDev) console.log("[SW] Fetch intercepted:", event.request.url);
253
+ if (isDev) console.log('[SW] Fetch intercepted:', event.request.url);
253
254
 
254
255
  event.respondWith(
255
256
  (async () => {
256
257
  const cached = await caches.match(event.request);
257
258
  if (cached) {
258
- if (isDev) console.log("[SW] Serving from cache:", event.request.url);
259
+ if (isDev) console.log('[SW] Serving from cache:', event.request.url);
259
260
  return cached;
260
261
  }
261
262
 
262
263
  try {
263
- if (event.request.mode === "navigate") {
264
+ if (event.request.mode === 'navigate') {
264
265
  const preloadResponse = await event.preloadResponse;
265
266
  if (preloadResponse) {
266
267
  if (isDev) {
267
268
  console.log(
268
- "[SW] Using preload response for:",
269
+ '[SW] Using preload response for:',
269
270
  event.request.url,
270
271
  );
271
272
  }
@@ -274,23 +275,23 @@ sw.addEventListener("fetch", (event) => {
274
275
  }
275
276
 
276
277
  if (isDev)
277
- console.log("[SW] Fetching from network:", event.request.url);
278
+ console.log('[SW] Fetching from network:', event.request.url);
278
279
 
279
280
  return await fetch(event.request);
280
281
  } catch (err) {
281
282
  if (isDev) {
282
283
  console.warn(
283
- "[SW] Fetch failed; offline fallback used:",
284
+ '[SW] Fetch failed; offline fallback used:',
284
285
  event.request.url,
285
286
  err,
286
287
  );
287
288
  }
288
289
 
289
- if (event.request.mode === "navigate") {
290
- const offline = await caches.match("/offline.html");
290
+ if (event.request.mode === 'navigate') {
291
+ const offline = await caches.match('/offline.html');
291
292
  if (offline) return offline;
292
- return new Response("<h1>Offline</h1>", {
293
- headers: { "Content-Type": "text/html" },
293
+ return new Response('<h1>Offline</h1>', {
294
+ headers: { 'Content-Type': 'text/html' },
294
295
  });
295
296
  }
296
297
 
@@ -14,7 +14,7 @@ This file is part of Network Pro.
14
14
  * @updated 2025-05-29
15
15
  */
16
16
 
17
- if (location.search.includes("nosw")) {
17
+ if (location.search.includes('nosw')) {
18
18
  window.__DISABLE_SW__ = true;
19
- console.warn("🧪 Service worker disabled via ?nosw flag in URL.");
19
+ console.warn('🧪 Service worker disabled via ?nosw flag in URL.');
20
20
  }
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="196.114" height="28" aria-label="POWERED BY: PROTON"><g shape-rendering="crispEdges"><path fill="#555" d="M0 0h117.614v28H0z"/><path fill="#6d4aff" d="M117.614 0h78.5v28h-78.5z"/></g><g fill="#fff" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" font-size="100" text-anchor="middle" text-rendering="geometricPrecision"><image width="11.114" height="14" x="9" y="7" href="data:image/svg+xml;base64,PHN2ZyBmaWxsPSJ3aGl0ZSIgcm9sZT0iaW1nIiB2aWV3Qm94PSIwIDAgMTkuMDUyMDAwMDAwMDAwMDAzIDI0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjx0aXRsZT5Qcm90b248L3RpdGxlPjxwYXRoIGQ9Ik0wIDE3Ljc1VjI0aDQuNDAxdi01Ljk3OWMwLTAuNTgyIDAuMjMyLTEuMTQgMC42NDUtMS41NTFhMi4yMDQgMi4yMDQgMCAwIDEgMS41NTYtMC42NDNoNC41MTNhNy45NTUgNy45NTUgMCAwIDAgNS42MTItMi4zMTggNy45MDcgNy45MDcgMCAwIDAgMi4zMjUtNS41OTUgNy45MSA3LjkxIDAgMCAwLTIuMzI1LTUuNTk2QTcuOTU4IDcuOTU4IDAgMCAwIDExLjExMyAwSDB2Ny44MTJoNC40MDFWNC4xMjloNi40MTZjMC45OTUgMCAxLjk1MSAwLjM5NCAyLjY1NiAxLjA5NyAwLjcwNCAwLjcgMS4xIDEuNjUzIDEuMTAxIDIuNjQ2YTMuNzQyIDMuNzQyIDAgMCAxLTEuMTAxIDIuNjQ4IDMuNzY2IDMuNzY2IDAgMCAxLTIuNjU2IDEuMDk3SDYuMTUzYTYuMTU4IDYuMTU4IDAgMCAwLTQuMzUyIDEuNzk1IDYuMTMzIDYuMTMzIDAgMCAwLTEuODAxIDQuMzM4WiIvPjwvc3ZnPg=="/><text x="658.637" y="175" textLength="795" transform="scale(.1)">POWERED BY</text><text x="1568.637" y="175" font-weight="bold" textLength="545" transform="scale(.1)">PROTON</text></g></svg>
@@ -43,10 +43,10 @@
43
43
  function updateTimestamp() {
44
44
  const now = new Date();
45
45
  const timeStr = now.toLocaleTimeString([], {
46
- hour: "2-digit",
47
- minute: "2-digit",
46
+ hour: '2-digit',
47
+ minute: '2-digit',
48
48
  });
49
- document.getElementById("timestamp").textContent = timeStr;
49
+ document.getElementById('timestamp').textContent = timeStr;
50
50
  }
51
51
 
52
52
  // Check connection status periodically
@@ -64,17 +64,17 @@
64
64
  setInterval(updateTimestamp, 60000);
65
65
 
66
66
  // Also listen for online event
67
- window.addEventListener("online", () => {
67
+ window.addEventListener('online', () => {
68
68
  window.location.reload();
69
69
  });
70
70
 
71
71
  // Prevent default action for offline links
72
72
  document
73
- .getElementById("contact-link")
74
- .addEventListener("click", function (e) {
73
+ .getElementById('contact-link')
74
+ .addEventListener('click', function (e) {
75
75
  if (!navigator.onLine) {
76
76
  e.preventDefault();
77
- alert("This link will be available when you are back online.");
77
+ alert('This link will be available when you are back online.');
78
78
  }
79
79
  });
80
80
  </script>
@@ -101,9 +101,9 @@
101
101
 
102
102
  <url>
103
103
 
104
- <loc>https://netwk.pro/bin/CC-BY-4.0.html</loc>
104
+ <loc>https://netwk.pro/pgp</loc>
105
105
 
106
- <lastmod>2025-06-10</lastmod>
106
+ <lastmod>2025-06-11</lastmod>
107
107
 
108
108
  <changefreq>monthly</changefreq>
109
109
 
@@ -111,15 +111,75 @@
111
111
 
112
112
  </url>
113
113
 
114
+ <url>
115
+
116
+ <loc>https://netwk.pro/bin/CC-BY-4.0.html</loc>
117
+
118
+ <lastmod>2025-06-10</lastmod>
119
+
120
+ <changefreq>yearly</changefreq>
121
+
122
+ <priority>0.3</priority>
123
+
124
+ </url>
125
+
114
126
  <url>
115
127
 
116
128
  <loc>https://netwk.pro/bin/COPYING.html</loc>
117
129
 
118
130
  <lastmod>2025-06-10</lastmod>
119
131
 
120
- <changefreq>monthly</changefreq>
132
+ <changefreq>yearly</changefreq>
121
133
 
122
- <priority>0.5</priority>
134
+ <priority>0.3</priority>
135
+
136
+ </url>
137
+
138
+ <url>
139
+
140
+ <loc>https://netwk.pro/.well-known/security.txt</loc>
141
+
142
+ <lastmod>2025-06-11</lastmod>
143
+
144
+ <changefreq>yearly</changefreq>
145
+
146
+ <priority>0.2</priority>
147
+
148
+ </url>
149
+
150
+ <url>
151
+
152
+ <loc>https://netwk.pro/.well-known/dnt-policy.txt</loc>
153
+
154
+ <lastmod>2025-06-11</lastmod>
155
+
156
+ <changefreq>yearly</changefreq>
157
+
158
+ <priority>0.2</priority>
159
+
160
+ </url>
161
+
162
+ <url>
163
+
164
+ <loc>https://netwk.pro/.well-known/gpc.json</loc>
165
+
166
+ <lastmod>2025-06-11</lastmod>
167
+
168
+ <changefreq>yearly</changefreq>
169
+
170
+ <priority>0.2</priority>
171
+
172
+ </url>
173
+
174
+ <url>
175
+
176
+ <loc>https://netwk.pro/.well-known/humans.txt</loc>
177
+
178
+ <lastmod>2025-06-11</lastmod>
179
+
180
+ <changefreq>yearly</changefreq>
181
+
182
+ <priority>0.1</priority>
123
183
 
124
184
  </url>
125
185
 
@@ -9,101 +9,101 @@ This file is part of Network Pro
9
9
  /** @type {import('stylelint').Config} */
10
10
  export default {
11
11
  extends: [
12
- "stylelint-config-recommended", // Base recommended config
13
- "stylelint-config-html/html", // For linting HTML files
14
- "stylelint-config-html/svelte", // For linting HTML within Svelte or similar frameworks
15
- "stylelint-config-html", // For linting HTML files
12
+ 'stylelint-config-recommended', // Base recommended config
13
+ 'stylelint-config-html/html', // For linting HTML files
14
+ 'stylelint-config-html/svelte', // For linting HTML within Svelte or similar frameworks
15
+ 'stylelint-config-html', // For linting HTML files
16
16
  ],
17
- plugins: ["stylelint-order"], // Add stylelint-order plugin
17
+ plugins: ['stylelint-order'], // Add stylelint-order plugin
18
18
  ignoreFiles: [
19
- "./src/lib/styles/fa-global.css", // Ignore CSS import files
20
- "./src/lib/styles/css/global.css", // Ignore CSS import files
21
- "./src/lib/styles/css/brands.css", // Ignore FontAwesome CSS files
22
- "**/*.min.css", // Also ignore minified CSS files as a best practice
19
+ './src/lib/styles/fa-global.css', // Ignore CSS import files
20
+ './src/lib/styles/css/global.css', // Ignore CSS import files
21
+ './src/lib/styles/css/brands.css', // Ignore FontAwesome CSS files
22
+ '**/*.min.css', // Also ignore minified CSS files as a best practice
23
23
  ],
24
24
  rules: {
25
- "selector-pseudo-class-no-unknown": [
25
+ 'selector-pseudo-class-no-unknown': [
26
26
  true,
27
27
  {
28
- ignorePseudoClasses: [":global"], // Allow :global for Svelte scoped styles
28
+ ignorePseudoClasses: [':global'], // Allow :global for Svelte scoped styles
29
29
  },
30
30
  ],
31
- "property-no-vendor-prefix": null, // Allow vendor prefixes
32
- "selector-no-vendor-prefix": null,
33
- "selector-pseudo-element-colon-notation": [
34
- "double",
31
+ 'property-no-vendor-prefix': null, // Allow vendor prefixes
32
+ 'selector-no-vendor-prefix': null,
33
+ 'selector-pseudo-element-colon-notation': [
34
+ 'double',
35
35
  {
36
- severity: "warning",
36
+ severity: 'warning',
37
37
  },
38
38
  ],
39
- "media-feature-name-no-vendor-prefix": null,
40
- "font-family-no-duplicate-names": [
39
+ 'media-feature-name-no-vendor-prefix': null,
40
+ 'font-family-no-duplicate-names': [
41
41
  true,
42
42
  {
43
- ignoreFontFamilyNames: ["monospace"],
43
+ ignoreFontFamilyNames: ['monospace'],
44
44
  },
45
45
  ],
46
- "selector-class-pattern": [
47
- "^(?!fa-).*$", // Disallow classes starting with "fa-"
46
+ 'selector-class-pattern': [
47
+ '^(?!fa-).*$', // Disallow classes starting with "fa-"
48
48
  {
49
49
  message:
50
50
  "Class names must not start with 'fa-' (FontAwesome classes are ignored)",
51
51
  },
52
52
  ],
53
- "order/properties-order": [
53
+ 'order/properties-order': [
54
54
  [
55
55
  {
56
- groupName: "Positioning",
57
- properties: ["position", "top", "right", "bottom", "left", "z-index"],
56
+ groupName: 'Positioning',
57
+ properties: ['position', 'top', 'right', 'bottom', 'left', 'z-index'],
58
58
  },
59
59
  {
60
- groupName: "Box Model",
60
+ groupName: 'Box Model',
61
61
  properties: [
62
- "display",
63
- "flex",
64
- "flex-grow",
65
- "flex-shrink",
66
- "flex-basis",
67
- "justify-content",
68
- "align-items",
69
- "align-self",
70
- "width",
71
- "height",
72
- "padding",
73
- "margin",
74
- "border",
75
- "box-shadow",
62
+ 'display',
63
+ 'flex',
64
+ 'flex-grow',
65
+ 'flex-shrink',
66
+ 'flex-basis',
67
+ 'justify-content',
68
+ 'align-items',
69
+ 'align-self',
70
+ 'width',
71
+ 'height',
72
+ 'padding',
73
+ 'margin',
74
+ 'border',
75
+ 'box-shadow',
76
76
  ],
77
77
  },
78
78
  {
79
- groupName: "Typography",
79
+ groupName: 'Typography',
80
80
  properties: [
81
- "font",
82
- "font-size",
83
- "font-weight",
84
- "line-height",
85
- "letter-spacing",
86
- "color",
87
- "text-align",
81
+ 'font',
82
+ 'font-size',
83
+ 'font-weight',
84
+ 'line-height',
85
+ 'letter-spacing',
86
+ 'color',
87
+ 'text-align',
88
88
  ],
89
89
  },
90
90
  {
91
- groupName: "Visual",
91
+ groupName: 'Visual',
92
92
  properties: [
93
- "background",
94
- "background-color",
95
- "background-image",
96
- "opacity",
97
- "visibility",
93
+ 'background',
94
+ 'background-color',
95
+ 'background-image',
96
+ 'opacity',
97
+ 'visibility',
98
98
  ],
99
99
  },
100
100
  {
101
- groupName: "Animation & Transform",
102
- properties: ["transition", "transform", "animation"],
101
+ groupName: 'Animation & Transform',
102
+ properties: ['transition', 'transform', 'animation'],
103
103
  },
104
104
  ],
105
105
  {
106
- unspecified: "bottomAlphabetical", // Place unspecified properties alphabetically at the bottom
106
+ unspecified: 'bottomAlphabetical', // Place unspecified properties alphabetically at the bottom
107
107
  },
108
108
  ],
109
109
  },