@networkpro/web 1.18.4 → 1.19.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.
- package/CHANGELOG.md +97 -31
- package/README.md +1 -0
- package/jsconfig.template.jsonc +3 -3
- package/package.json +8 -9
- package/src/app.html +1 -1
- package/src/lib/README.md +160 -0
- package/src/lib/components/FullWidthSection.svelte +0 -9
- package/src/lib/components/foss/index.js +21 -0
- package/src/lib/components/index.js +30 -0
- package/src/lib/components/layout/index.js +21 -0
- package/src/lib/index.js +14 -4
- package/src/lib/pages/AboutContent.svelte +28 -8
- package/src/lib/pages/index.js +27 -0
- package/src/lib/styles/css/default.css +7 -0
- package/src/lib/styles/global.min.css +3 -1
- package/src/lib/styles/index.js +0 -1
- package/src/lib/types/README.md +50 -0
- package/src/routes/+layout.svelte +4 -10
- package/src/routes/+page.svelte +9 -7
- package/src/routes/links/+page.svelte +3 -2
- package/static/disableSw.js +2 -2
- package/static/sitemap.xml +3 -3
- package/tests/unit/client/lib/PWAInstallButton.test.js +80 -0
- package/vitest-setup-client.js +9 -0
- package/scripts/testRedirects.js +0 -84
package/CHANGELOG.md
CHANGED
|
@@ -22,11 +22,71 @@ This project attempts to follow [Keep a Changelog](https://keepachangelog.com/en
|
|
|
22
22
|
|
|
23
23
|
---
|
|
24
24
|
|
|
25
|
-
## [1.
|
|
25
|
+
## [1.19.0] - 2025-10-06
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
|
|
29
|
+
- **`src/lib/components/index.js`**, **`src/lib/components/foss/index.js`**, **`src/lib/components/layout/index.js`**
|
|
30
|
+
- Introduced explicit component export modules to improve import consistency across the library.
|
|
31
|
+
- Added wildcard exports in `src/lib/index.js` for these component modules, enabling `$lib/components/...` shorthand imports.
|
|
32
|
+
- **`tests/unit/client/lib/PWAInstallButton.test.js`**
|
|
33
|
+
- Added focused unit tests for `PWAInstallButton.svelte` verifying install-event handling and user-prompt logic using `Vitest` and `@testing-library/svelte`.
|
|
34
|
+
- **`src/lib/README.md`**, **`src/lib/types/README.md`**
|
|
35
|
+
- Added contextual documentation for the library and type definition directories.
|
|
36
|
+
- Clarifies module structure, export hierarchy, and intended usage for contributors.
|
|
37
|
+
|
|
38
|
+
### Changed
|
|
39
|
+
|
|
40
|
+
- Bumped project version to `v1.19.0`.
|
|
41
|
+
- Updated `src/lib/pages/AboutContent.svelte` with new services
|
|
42
|
+
- Added DOM and animation mocks (`window.matchMedia`, `Element.prototype.animate`) to `vitest-setup-client.js` to stabilize component transition tests.
|
|
43
|
+
- Updated `src/lib/index.js` to export all component and utility submodules explicitly, replacing previous implicit import behavior.
|
|
44
|
+
- Centralized page-level component exports in `src/lib/pages/index.js` for consistent import structure.
|
|
45
|
+
- Updated `src/routes/+layout.svelte` to import objects from submodules, instead of by their explicit alias
|
|
46
|
+
- Minor alignment in `src/routes/+page.svelte` and `src/routes/links/+page.svelte` with updated component imports
|
|
47
|
+
- Moved inline CSS fom `src/lib/components/FullWidthSection.svelte` into `src/lib/styles/css/default.css`
|
|
48
|
+
- Generated an updated `src/lib/styles/global.min.css` file with LightningCSS
|
|
49
|
+
- Updated `.gitignore` to remove duplicate `.vercel` entry
|
|
50
|
+
- Updated last modified dates in `static/sitemap.xml`
|
|
51
|
+
- Updated dependencies:
|
|
52
|
+
- `eslint-plugin-jsdoc` `^60.8.1` → `^60.8.2`
|
|
53
|
+
- `posthog-js` `^1.270.1` → `^1.271.0`
|
|
54
|
+
- `svelte` `5.39.8` → `5.39.9`
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## [1.18.5] - 2025-10-05
|
|
59
|
+
|
|
60
|
+
### Added
|
|
61
|
+
|
|
62
|
+
- Added Vercel CLI scripts to `package.json`, including `dev:vercel` and `build:vercel`.
|
|
63
|
+
|
|
64
|
+
### Changed
|
|
65
|
+
|
|
66
|
+
- Bumped project version to `v1.18.5`.
|
|
67
|
+
- Updated generator metadata in `app.html` to reflect `SvelteKit 2.44.0`.
|
|
68
|
+
- Added `scripts/testRedirects.js` to `.gitignore`.
|
|
69
|
+
- Cleaned up header in `jsconfig.template.jsonc`.
|
|
70
|
+
- Updated **Repository Structure** section in `README.md`.
|
|
71
|
+
- Restructured `CHANGELOG.md` such that sections are presented in alphabetical order.
|
|
72
|
+
- Corrected JSDoc annotations in `static/disableSw.js`.
|
|
73
|
+
- Updated dependencies:
|
|
74
|
+
- `@sveltejs/kit` `2.43.8` → `2.44.0`
|
|
75
|
+
- `eslint-plugin-jsdoc` `^60.8.0` → `^60.8.1`
|
|
26
76
|
|
|
27
77
|
### Documentation
|
|
28
78
|
|
|
29
|
-
-
|
|
79
|
+
- Revised **Repository Structure** to accurately reflect the folders under `/tests`.
|
|
80
|
+
|
|
81
|
+
### Removed
|
|
82
|
+
|
|
83
|
+
- Removed all references to Netlify and all Netlify-specific scripts from `package.json`.
|
|
84
|
+
- Removed `test:redirects` script from `package.json`.
|
|
85
|
+
- The `testRedirects.js` script has been removed from version control, as it is no longer needed to test Netlify redirects.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## [1.18.4] - 2025-10-04
|
|
30
90
|
|
|
31
91
|
### Changes
|
|
32
92
|
|
|
@@ -53,6 +113,10 @@ This project attempts to follow [Keep a Changelog](https://keepachangelog.com/en
|
|
|
53
113
|
- `typescript` `^5.9.2` → `^5.9.3`
|
|
54
114
|
- `vite` `^7.1.7` → `^7.1.9`
|
|
55
115
|
|
|
116
|
+
### Documentation
|
|
117
|
+
|
|
118
|
+
- Updated **Repository Structure** to reflect current environment and files.
|
|
119
|
+
|
|
56
120
|
---
|
|
57
121
|
|
|
58
122
|
## [1.18.3] - 2025-09-27
|
|
@@ -164,31 +228,20 @@ This project attempts to follow [Keep a Changelog](https://keepachangelog.com/en
|
|
|
164
228
|
|
|
165
229
|
## [1.17.1] - 2025-09-17
|
|
166
230
|
|
|
231
|
+
### Changed
|
|
232
|
+
|
|
233
|
+
- Bumped version to `v1.17.1`.
|
|
234
|
+
|
|
167
235
|
### Security
|
|
168
236
|
|
|
169
237
|
- Patched transitive vulnerabilities by pinning dependencies via `overrides`:
|
|
170
238
|
- Forced `tmp` to `>=0.2.4` (resolves CVE-2025-54798 reported via `@lhci/cli`).
|
|
171
239
|
- Forced `cookie` to `^1.0.0` (used by `@sveltejs/kit` and `@lhci/cli`).
|
|
172
240
|
|
|
173
|
-
### Changed
|
|
174
|
-
|
|
175
|
-
- Bumped version to `v1.17.1`.
|
|
176
|
-
|
|
177
241
|
---
|
|
178
242
|
|
|
179
243
|
## [1.17.0] - 2025-09-17
|
|
180
244
|
|
|
181
|
-
### Security
|
|
182
|
-
|
|
183
|
-
- Updated dependencies to address known vulnerabilities (notably `@sveltejs/kit`, `vite`, and related plugins).
|
|
184
|
-
|
|
185
|
-
### Documentation
|
|
186
|
-
|
|
187
|
-
- Clarified CSP reporting setup in `README.md`:
|
|
188
|
-
- Explained relationship with external CSP reporting endpoint (`csp-endpoint` repo).
|
|
189
|
-
- Documented use of both `report-uri` (legacy) and `report-to` (modern, recommended).
|
|
190
|
-
- Added example headers including `Report-To` definition.
|
|
191
|
-
|
|
192
245
|
### Added
|
|
193
246
|
|
|
194
247
|
- New `meta-check.yml` GitHub Actions workflow to validate `<title>` and `<meta>` descriptions using Vitest.
|
|
@@ -236,11 +289,22 @@ This project attempts to follow [Keep a Changelog](https://keepachangelog.com/en
|
|
|
236
289
|
- `svelte-eslint-parser` `^1.3.0` → `^1.3.2`
|
|
237
290
|
- `vite` `^7.0.6` → `^7.1.5`
|
|
238
291
|
|
|
292
|
+
### Documentation
|
|
293
|
+
|
|
294
|
+
- Clarified CSP reporting setup in `README.md`:
|
|
295
|
+
- Explained relationship with external CSP reporting endpoint (`csp-endpoint` repo).
|
|
296
|
+
- Documented use of both `report-uri` (legacy) and `report-to` (modern, recommended).
|
|
297
|
+
- Added example headers including `Report-To` definition.
|
|
298
|
+
|
|
239
299
|
### Removed
|
|
240
300
|
|
|
241
301
|
- Deleted `src/routes/example.svx`, which was unused and unneeded.
|
|
242
302
|
- Removed `mdsvex` from package.json, as it is unlikely to be used.
|
|
243
303
|
|
|
304
|
+
### Security
|
|
305
|
+
|
|
306
|
+
- Updated dependencies to address known vulnerabilities (notably `@sveltejs/kit`, `vite`, and related plugins).
|
|
307
|
+
|
|
244
308
|
### Notes
|
|
245
309
|
|
|
246
310
|
- Pinned `jsdom` to `26.1.0` due to build incompatibility in `27.x` (`cssstyle` parsing error with Vite/Rollup).
|
|
@@ -502,6 +566,11 @@ This project attempts to follow [Keep a Changelog](https://keepachangelog.com/en
|
|
|
502
566
|
|
|
503
567
|
## [1.14.1] - 2025-06-16
|
|
504
568
|
|
|
569
|
+
### Added
|
|
570
|
+
|
|
571
|
+
- Introduced `.github/workflows/publish-test.yml`, a standalone workflow to safely simulate `npm publish` without publishing.
|
|
572
|
+
- Added commands to display Node.js and npm versions for visibility and troubleshooting in all relevant jobs.
|
|
573
|
+
|
|
505
574
|
### Changed
|
|
506
575
|
|
|
507
576
|
- Updated Node.js engine to `24` to match the specified engine constraints in `package.json`.
|
|
@@ -509,11 +578,6 @@ This project attempts to follow [Keep a Changelog](https://keepachangelog.com/en
|
|
|
509
578
|
- Refactored `build-and-publish.yml` to use `git archive` for artifact preparation and aligned it with a tested publishing flow.
|
|
510
579
|
- Removed `.npmrc` token-based authentication in favor of environment secrets to avoid credential conflicts.
|
|
511
580
|
|
|
512
|
-
### Added
|
|
513
|
-
|
|
514
|
-
- Introduced `.github/workflows/publish-test.yml`, a standalone workflow to safely simulate `npm publish` without publishing.
|
|
515
|
-
- Added commands to display Node.js and npm versions for visibility and troubleshooting in all relevant jobs.
|
|
516
|
-
|
|
517
581
|
---
|
|
518
582
|
|
|
519
583
|
## [1.14.0] - 2025-06-16
|
|
@@ -842,13 +906,7 @@ This project attempts to follow [Keep a Changelog](https://keepachangelog.com/en
|
|
|
842
906
|
- Upgraded `posthog-js` from `v1.249.4` to `v1.249.5`.
|
|
843
907
|
- Upgraded `vitest` from `v3.2.2` to `v3.2.3`.
|
|
844
908
|
|
|
845
|
-
###
|
|
846
|
-
|
|
847
|
-
- Updated Lighthouse CI annotation step to explicitly select only valid Lighthouse report files (e.g., `*.report.json`, `lhr-*.json`) and ignore `assertion-results.json`, which caused `jq` parsing errors during CI runs.
|
|
848
|
-
- Scoped Lighthouse assertions in `.lighthouserc.cjs` to `resource-summary` only, preventing unwanted failures from default performance audits.
|
|
849
|
-
- Resolved malformed PR comment formatting in the Lighthouse GitHub Actions workflow by replacing Markdown tables with plain-text bullet lists.
|
|
850
|
-
|
|
851
|
-
### Docs
|
|
909
|
+
### Documentation
|
|
852
910
|
|
|
853
911
|
- Updated `README.md` with improved context and phrasing around the CHANGELOG reference.
|
|
854
912
|
- Added `CHANGELOG.md` to the documented project structure with a descriptive label:
|
|
@@ -857,7 +915,13 @@ This project attempts to follow [Keep a Changelog](https://keepachangelog.com/en
|
|
|
857
915
|
├── CHANGELOG.md # Chronological record of notable project changes
|
|
858
916
|
```
|
|
859
917
|
|
|
860
|
-
###
|
|
918
|
+
### Fixed
|
|
919
|
+
|
|
920
|
+
- Updated Lighthouse CI annotation step to explicitly select only valid Lighthouse report files (e.g., `*.report.json`, `lhr-*.json`) and ignore `assertion-results.json`, which caused `jq` parsing errors during CI runs.
|
|
921
|
+
- Scoped Lighthouse assertions in `.lighthouserc.cjs` to `resource-summary` only, preventing unwanted failures from default performance audits.
|
|
922
|
+
- Resolved malformed PR comment formatting in the Lighthouse GitHub Actions workflow by replacing Markdown tables with plain-text bullet lists.
|
|
923
|
+
|
|
924
|
+
### Notes
|
|
861
925
|
|
|
862
926
|
- Confirmed that `Authenticate GitHub CLI` is not needed in `build-and-publish.yml`, as only the `check-codeql` job uses the GitHub CLI and is already authenticated.
|
|
863
927
|
- Verified that `scripts/openReport.js` does not require unit testing, as it performs side-effect-only CLI actions. Linting and manual testing are sufficient.
|
|
@@ -977,7 +1041,9 @@ This project attempts to follow [Keep a Changelog](https://keepachangelog.com/en
|
|
|
977
1041
|
|
|
978
1042
|
<!-- Link references -->
|
|
979
1043
|
|
|
980
|
-
[Unreleased]: https://github.com/netwk-pro/netwk-pro.github.io/compare/v1.
|
|
1044
|
+
[Unreleased]: https://github.com/netwk-pro/netwk-pro.github.io/compare/v1.19.0...HEAD
|
|
1045
|
+
[1.19.0]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.19.0
|
|
1046
|
+
[1.18.5]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.18.5
|
|
981
1047
|
[1.18.4]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.18.4
|
|
982
1048
|
[1.18.3]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.18.3
|
|
983
1049
|
[1.18.2]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.18.2
|
package/README.md
CHANGED
|
@@ -90,6 +90,7 @@ This project follows the principles of [Keep a Changelog](https://keepachangelog
|
|
|
90
90
|
│ └── sitemap.xml # SEO: full site map
|
|
91
91
|
├── tests/
|
|
92
92
|
│ ├── e2e/ # Playwright end-to-end tests
|
|
93
|
+
│ ├── meta/ # Metadata end-to-end CI tests
|
|
93
94
|
│ └── unit/ # Vitest unit tests
|
|
94
95
|
│ ├── client/ # Client-side (jsdom) unit tests
|
|
95
96
|
│ ├── server/ # Server-side (node) unit tests
|
package/jsconfig.template.jsonc
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/* =========================================================================
|
|
2
2
|
jsconfig.template.jsonc
|
|
3
3
|
|
|
4
|
-
NOTE: This file is for reference only and is not actively used by SvelteKit
|
|
5
|
-
tooling. SvelteKit uses the jsconfig.json file without comments for
|
|
6
|
-
configuration.
|
|
4
|
+
NOTE: This file is for reference only and is not actively used by SvelteKit
|
|
5
|
+
or tooling. SvelteKit uses the jsconfig.json file without comments for
|
|
6
|
+
actual configuration.
|
|
7
7
|
|
|
8
8
|
Copyright © 2025 Network Pro Strategies (Network Pro™)
|
|
9
9
|
SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@networkpro/web",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.19.0",
|
|
5
5
|
"description": "Locking Down Networks, Unlocking Confidence™ | Security, Networking, Privacy — Network Pro Strategies",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"advisory",
|
|
@@ -36,10 +36,10 @@
|
|
|
36
36
|
"scripts": {
|
|
37
37
|
"dev": "vite dev",
|
|
38
38
|
"start": "npm run dev",
|
|
39
|
-
"dev:
|
|
39
|
+
"dev:vercel": "vercel dev",
|
|
40
40
|
"build": "vite build",
|
|
41
|
+
"build:vercel": "vercel build",
|
|
41
42
|
"preview": "vite preview",
|
|
42
|
-
"build:netlify": "netlify build",
|
|
43
43
|
"css:bundle": "node scripts/bundleCss.js",
|
|
44
44
|
"prepare": "svelte-kit sync || echo ''",
|
|
45
45
|
"check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json",
|
|
@@ -60,7 +60,6 @@
|
|
|
60
60
|
"test:watch": "vitest --config vitest.config.client.js --watch",
|
|
61
61
|
"test:coverage": "npm run test:client -- --run --coverage && npm run test:server -- --run --coverage",
|
|
62
62
|
"test:e2e": "npx playwright test --retries=1",
|
|
63
|
-
"test:redirects": "node scripts/testRedirects.js",
|
|
64
63
|
"coverage:client": "node scripts/openReport.js client",
|
|
65
64
|
"coverage:server": "node scripts/openReport.js server",
|
|
66
65
|
"coverage:open": "npm run coverage:client && npm run coverage:server",
|
|
@@ -68,7 +67,7 @@
|
|
|
68
67
|
"lint:fix": "eslint . --ext .mjs,.js,.svelte --fix",
|
|
69
68
|
"lint:jsdoc": "eslint . --ext .js,.mjs,.svelte --max-warnings=0",
|
|
70
69
|
"lint:css": "stylelint \"**/*.{css,svelte}\" --ignore-path .stylelintignore",
|
|
71
|
-
"lint:md": "npx markdownlint-cli2 \"**/*.{md,markdown}\" \"#node_modules/**\" \"#build/**\" \"
|
|
70
|
+
"lint:md": "npx markdownlint-cli2 \"**/*.{md,markdown}\" \"#node_modules/**\" \"#build/**\" \"#playwright-report/**\" \"#test-results/**\"",
|
|
72
71
|
"lint:all": "npm run lint && npm run lint:md && npm run lint:css && npm run format",
|
|
73
72
|
"format": "prettier --check .",
|
|
74
73
|
"format:fix": "prettier --write .",
|
|
@@ -79,9 +78,9 @@
|
|
|
79
78
|
},
|
|
80
79
|
"dependencies": {
|
|
81
80
|
"dompurify": "^3.2.7",
|
|
82
|
-
"posthog-js": "^1.
|
|
81
|
+
"posthog-js": "^1.271.0",
|
|
83
82
|
"semver": "^7.7.2",
|
|
84
|
-
"svelte": "5.39.
|
|
83
|
+
"svelte": "5.39.9"
|
|
85
84
|
},
|
|
86
85
|
"devDependencies": {
|
|
87
86
|
"@eslint/compat": "^1.4.0",
|
|
@@ -89,7 +88,7 @@
|
|
|
89
88
|
"@lhci/cli": "^0.15.1",
|
|
90
89
|
"@playwright/test": "^1.55.1",
|
|
91
90
|
"@sveltejs/adapter-vercel": "^5.10.3",
|
|
92
|
-
"@sveltejs/kit": "2.
|
|
91
|
+
"@sveltejs/kit": "2.44.0",
|
|
93
92
|
"@sveltejs/vite-plugin-svelte": "^6.2.1",
|
|
94
93
|
"@testing-library/jest-dom": "^6.9.1",
|
|
95
94
|
"@testing-library/svelte": "^5.2.8",
|
|
@@ -98,7 +97,7 @@
|
|
|
98
97
|
"browserslist": "^4.26.3",
|
|
99
98
|
"eslint": "^9.37.0",
|
|
100
99
|
"eslint-config-prettier": "^10.1.8",
|
|
101
|
-
"eslint-plugin-jsdoc": "^60.8.
|
|
100
|
+
"eslint-plugin-jsdoc": "^60.8.2",
|
|
102
101
|
"eslint-plugin-svelte": "^3.12.4",
|
|
103
102
|
"globals": "^16.4.0",
|
|
104
103
|
"jsdom": "26.1.0",
|
package/src/app.html
CHANGED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
<!-- =====================================================================
|
|
2
|
+
src/lib/README.md
|
|
3
|
+
|
|
4
|
+
Copyright © 2025 Network Pro Strategies (Network Pro™)
|
|
5
|
+
SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
|
|
6
|
+
This file is part of Network Pro.
|
|
7
|
+
====================================================================== -->
|
|
8
|
+
|
|
9
|
+
# `/src/lib` Overview
|
|
10
|
+
|
|
11
|
+
This directory contains all reusable **modules**, **assets**, and **constants** used across the app.
|
|
12
|
+
It acts as the project’s _internal library_.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 📦 Importing from `$lib`
|
|
17
|
+
|
|
18
|
+
SvelteKit automatically aliases `$lib` → `src/lib/`, allowing you to import from this directory anywhere in the project:
|
|
19
|
+
|
|
20
|
+
```js
|
|
21
|
+
import { something } from '$lib';
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
> 💡 You don’t need to use relative paths like `../../../lib/...`; the `$lib` alias handles that automatically.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 📁 Directory Structure
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
src/lib/
|
|
32
|
+
├── components/ # Svelte UI components
|
|
33
|
+
├── img/ # Static image assets
|
|
34
|
+
├── images.js # Imports and re-exports images from /img/
|
|
35
|
+
├── index.js # Main export hub (images, constants, etc.)
|
|
36
|
+
└── README.md # You are here
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## 🖼️ Image Imports
|
|
42
|
+
|
|
43
|
+
All image assets are re-exported via `images.js` and then made available in `$lib/index.js`.
|
|
44
|
+
|
|
45
|
+
This allows images to be imported directly from `$lib`:
|
|
46
|
+
|
|
47
|
+
```js
|
|
48
|
+
import { logoPng, faviconSvg } from '$lib';
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**Example (Svelte component):**
|
|
52
|
+
|
|
53
|
+
```svelte
|
|
54
|
+
<script>
|
|
55
|
+
import { logoPng } from '$lib';
|
|
56
|
+
</script>
|
|
57
|
+
|
|
58
|
+
<img src={logoPng} alt="Network Pro Logo" />
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
If you prefer, you can still import by full path:
|
|
62
|
+
|
|
63
|
+
```js
|
|
64
|
+
import logoPng from '$lib/img/logo-web.png';
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Both are valid — the re-exports simply make imports cleaner and centralized.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## ⚙️ Constants and Utilities
|
|
72
|
+
|
|
73
|
+
`index.js` defines and exports a `CONSTANTS` object for consistent app-wide values.
|
|
74
|
+
These are grouped into logical categories for easy reference.
|
|
75
|
+
|
|
76
|
+
```js
|
|
77
|
+
import { CONSTANTS } from '$lib';
|
|
78
|
+
|
|
79
|
+
console.log(CONSTANTS.COMPANY_INFO.APP_NAME); // "Network Pro"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### 🏢 COMPANY_INFO
|
|
83
|
+
|
|
84
|
+
| Key | Description | Example |
|
|
85
|
+
| ---------- | ---------------------------- | ------------------------ |
|
|
86
|
+
| `NAME` | Full company name | `Network Pro Strategies` |
|
|
87
|
+
| `APP_NAME` | Application or branding name | `Network Pro` |
|
|
88
|
+
| `YEAR` | Copyright / app year | `2025` |
|
|
89
|
+
|
|
90
|
+
### 📬 CONTACT
|
|
91
|
+
|
|
92
|
+
| Key | Description | Example |
|
|
93
|
+
| --------- | ----------------------- | --------------------------- |
|
|
94
|
+
| `EMAIL` | General support email | `support (at) neteng.pro` |
|
|
95
|
+
| `SECURE` | Secure contact address | `contact (at) s.neteng.pro` |
|
|
96
|
+
| `PRIVACY` | Privacy-related contact | `privacy (at) netwk.pro` |
|
|
97
|
+
| `PHONE` | Company phone number | `(623) 252-4350` |
|
|
98
|
+
|
|
99
|
+
### 🗂️ PAGE
|
|
100
|
+
|
|
101
|
+
| Key | Description | Example |
|
|
102
|
+
| ------- | --------------------- | --------------------- |
|
|
103
|
+
| `BLANK` | Opens a new tab | `_blank` |
|
|
104
|
+
| `REL` | Default rel attribute | `noopener noreferrer` |
|
|
105
|
+
| `SELF` | Opens in same tab | `_self` |
|
|
106
|
+
|
|
107
|
+
### 🧭 NAV
|
|
108
|
+
|
|
109
|
+
| Key | Description | Example |
|
|
110
|
+
| --------- | ----------------------- | ------------- |
|
|
111
|
+
| `BACKTOP` | Label for “back to top” | `Back to top` |
|
|
112
|
+
| `HREFTOP` | Anchor link to top | `#top` |
|
|
113
|
+
|
|
114
|
+
### 🌐 LINKS
|
|
115
|
+
|
|
116
|
+
| Key | Description | Example |
|
|
117
|
+
| ------ | ---------------- | ------------------------ |
|
|
118
|
+
| `HOME` | Company home URL | `https://netwk.pro` |
|
|
119
|
+
| `BLOG` | Company blog URL | `https://blog.netwk.pro` |
|
|
120
|
+
|
|
121
|
+
🧠 Tip: If you add new global constants (e.g., API endpoints, metadata, etc.),
|
|
122
|
+
extend `CONSTANTS` here and update this table for quick reference.
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## 🧩 Components (if applicable)
|
|
127
|
+
|
|
128
|
+
Reusable components can also be exported from this directory:
|
|
129
|
+
|
|
130
|
+
```js
|
|
131
|
+
import { Logo } from '$lib';
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
If you add more UI components later, re-export them from `index.js` for easy access.
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## 🧠 Developer Notes
|
|
139
|
+
|
|
140
|
+
`$lib` is an alias — not a relative path.
|
|
141
|
+
It points directly to `src/lib/`.
|
|
142
|
+
|
|
143
|
+
`export * from './images.js';` re-exports all image imports so you can reference them easily.
|
|
144
|
+
|
|
145
|
+
Keep asset imports centralized in `images.js` to simplify maintenance.
|
|
146
|
+
|
|
147
|
+
No need to modify imports when adding new images — just add them to `images.js`.
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
<span style="font-size: 12px; text-align: center;">
|
|
152
|
+
|
|
153
|
+
Copyright © 2025
|
|
154
|
+
**[Network Pro Strategies](https://netwk.pro) (Network Pro™)**
|
|
155
|
+
|
|
156
|
+
Network Pro™, the shield logo, and the "Locking Down Networks...™" slogan are [trademarks](https://netwk.pro/license#trademark) of Network Pro Strategies.
|
|
157
|
+
|
|
158
|
+
Licensed under **[CC BY 4.0](https://netwk.pro/license#cc-by)** and the **[GNU GPL](https://netwk.pro/license#gnu-gpl)**, as published by the [Free Software Foundation](https://www.fsf.org), either version 3 of the License, or (at your option) any later version.
|
|
159
|
+
|
|
160
|
+
</span>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/* ==========================================================================
|
|
2
|
+
src/lib/components/foss/index.js
|
|
3
|
+
|
|
4
|
+
Copyright © 2025 Network Pro Strategies (Network Pro™)
|
|
5
|
+
SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
|
|
6
|
+
This file is part of Network Pro.
|
|
7
|
+
========================================================================== */
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Library index file
|
|
11
|
+
*
|
|
12
|
+
* @file index.js
|
|
13
|
+
* @description Export point for FOSS library components
|
|
14
|
+
* @module src/lib/components/foss
|
|
15
|
+
* @author Scott Lopez
|
|
16
|
+
* @updated 2025-10-05
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
export { default as FossFeatures } from './FossFeatures.svelte';
|
|
20
|
+
export { default as FossItemContent } from './FossItemContent.svelte';
|
|
21
|
+
export { default as ObtainiumBlock } from './ObtainiumBlock.svelte';
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/* ==========================================================================
|
|
2
|
+
src/lib/components/index.js
|
|
3
|
+
|
|
4
|
+
Copyright © 2025 Network Pro Strategies (Network Pro™)
|
|
5
|
+
SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
|
|
6
|
+
This file is part of Network Pro.
|
|
7
|
+
========================================================================== */
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Library index file
|
|
11
|
+
*
|
|
12
|
+
* @file index.js
|
|
13
|
+
* @description Export point for library components
|
|
14
|
+
* @module src/lib/components
|
|
15
|
+
* @author SunDevil311
|
|
16
|
+
* @updated 2025-10-05
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
export { default as Badges } from './Badges.svelte';
|
|
20
|
+
export { default as CodeBlock } from './CodeBlock.svelte';
|
|
21
|
+
export { default as ContainerSection } from './ContainerSection.svelte';
|
|
22
|
+
export * from './foss/index.js';
|
|
23
|
+
export { default as FullWidthSection } from './FullWidthSection.svelte';
|
|
24
|
+
export * from './layout/index.js';
|
|
25
|
+
export { default as LegalNav } from './LegalNav.svelte';
|
|
26
|
+
export { default as Logo } from './Logo.svelte';
|
|
27
|
+
export { default as MetaTags } from './MetaTags.svelte';
|
|
28
|
+
export { default as PWAInstallButton } from './PWAInstallButton.svelte';
|
|
29
|
+
export { default as RedirectPage } from './RedirectPage.svelte';
|
|
30
|
+
export { default as SocialMedia } from './SocialMedia.svelte';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/* ==========================================================================
|
|
2
|
+
src/lib/components/layout/index.js
|
|
3
|
+
|
|
4
|
+
Copyright © 2025 Network Pro Strategies (Network Pro™)
|
|
5
|
+
SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
|
|
6
|
+
This file is part of Network Pro.
|
|
7
|
+
========================================================================== */
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Library index file
|
|
11
|
+
*
|
|
12
|
+
* @file index.js
|
|
13
|
+
* @description Export point for layout components
|
|
14
|
+
* @module src/lib/components/layout
|
|
15
|
+
* @author Scott Lopez
|
|
16
|
+
* @updated 2025-10-05
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
export { default as Footer } from './Footer.svelte';
|
|
20
|
+
export { default as HeaderDefault } from './HeaderDefault.svelte';
|
|
21
|
+
export { default as HeaderHome } from './HeaderHome.svelte';
|
package/src/lib/index.js
CHANGED
|
@@ -10,16 +10,26 @@ This file is part of Network Pro.
|
|
|
10
10
|
* Library index file
|
|
11
11
|
*
|
|
12
12
|
* @file index.js
|
|
13
|
-
* @description
|
|
13
|
+
* @description Main export hub for $lib modules
|
|
14
|
+
*
|
|
15
|
+
* Components, images, and utilities are organized in submodules
|
|
16
|
+
* and re-exported here for flat `$lib` imports.
|
|
14
17
|
* @module src/lib
|
|
15
18
|
* @author SunDevil311
|
|
16
|
-
* @updated 2025-
|
|
19
|
+
* @updated 2025-10-05
|
|
17
20
|
*/
|
|
18
21
|
|
|
19
|
-
// Re-export images
|
|
20
|
-
//
|
|
22
|
+
// Re-export all images so they can be imported directly from `$lib`
|
|
23
|
+
// Example usage:
|
|
24
|
+
// import { logoPng } from '$lib';
|
|
21
25
|
export * from './images.js';
|
|
22
26
|
|
|
27
|
+
// Re-export all components so they can be imported directly from `$lib`
|
|
28
|
+
export * from './components/index.js';
|
|
29
|
+
|
|
30
|
+
// Re-export all pages so they can be imported directly from `$lib`
|
|
31
|
+
export * from './pages/index.js';
|
|
32
|
+
|
|
23
33
|
// Export utility functions
|
|
24
34
|
// Uncomment and adjust these as needed for your project
|
|
25
35
|
// export * from './utils/formatting.js';
|
|
@@ -138,7 +138,7 @@ This file is part of Network Pro.
|
|
|
138
138
|
<p>
|
|
139
139
|
<strong>{COMPANY_INFO.NAME} ({COMPANY_INFO.APP_NAME}™)</strong>
|
|
140
140
|
<br />
|
|
141
|
-
<em>
|
|
141
|
+
<em>Networking, Security, Privacy</em>
|
|
142
142
|
</p>
|
|
143
143
|
</section>
|
|
144
144
|
|
|
@@ -162,10 +162,11 @@ This file is part of Network Pro.
|
|
|
162
162
|
|
|
163
163
|
<p>
|
|
164
164
|
At <strong>{COMPANY_INFO.NAME} ({COMPANY_INFO.APP_NAME}™)</strong>, we
|
|
165
|
-
deliver network security
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
165
|
+
deliver network security and engineering, information security (IS),
|
|
166
|
+
information technology (IT), cyber security, and digital privacy consulting
|
|
167
|
+
with clarity, credibility, and care. We believe that real security doesn't
|
|
168
|
+
have to come at the cost of user autonomy, and that privacy-minded solutions
|
|
169
|
+
can be both practical and powerful.
|
|
169
170
|
</p>
|
|
170
171
|
|
|
171
172
|
<p>
|
|
@@ -189,7 +190,7 @@ This file is part of Network Pro.
|
|
|
189
190
|
<ul>
|
|
190
191
|
<li><strong>Network Hardening & Perimeter Defense</strong></li>
|
|
191
192
|
<li><strong>Firewall Architecture & Policy Optimization</strong></li>
|
|
192
|
-
<li><strong>
|
|
193
|
+
<li><strong>Zero Trust Implementation</strong></li>
|
|
193
194
|
<li><strong>Secure Infrastructure Design & Implementation</strong></li>
|
|
194
195
|
<li><strong>Risk Reduction & Security Posture Assessment</strong></li>
|
|
195
196
|
</ul>
|
|
@@ -201,6 +202,24 @@ This file is part of Network Pro.
|
|
|
201
202
|
clear value, with zero fluff.
|
|
202
203
|
</p>
|
|
203
204
|
|
|
205
|
+
<div class="spacer"></div>
|
|
206
|
+
|
|
207
|
+
<p>
|
|
208
|
+
Additionally, {COMPANY_INFO.APP_NAME}™ provides on-site services in the
|
|
209
|
+
Greater Phoenix Metro Area (Maricopa County, AZ). Our on-site services are
|
|
210
|
+
available to both businesses and consumers. In addition to consulting, we
|
|
211
|
+
offer the following services:
|
|
212
|
+
</p>
|
|
213
|
+
|
|
214
|
+
<ul>
|
|
215
|
+
<li><strong>Home Modem Setup</strong></li>
|
|
216
|
+
<li><strong>Basic Router Setup</strong></li>
|
|
217
|
+
<li><strong>Wi-Fi and Wireless Networking Setup</strong></li>
|
|
218
|
+
<li><strong>Network Troubleshooting</strong></li>
|
|
219
|
+
<li><strong>Network Security Review</strong></li>
|
|
220
|
+
<li><strong>Add a Wi-Fi Device</strong></li>
|
|
221
|
+
</ul>
|
|
222
|
+
|
|
204
223
|
<p>
|
|
205
224
|
We also believe education is a core pillar of real-world security. That's why
|
|
206
225
|
we invest in raising awareness—across both technical and general audiences—on
|
|
@@ -210,7 +229,8 @@ This file is part of Network Pro.
|
|
|
210
229
|
<p>
|
|
211
230
|
<strong
|
|
212
231
|
>{COMPANY_INFO.APP_NAME}™ exists to bring strong, thoughtful security
|
|
213
|
-
to organizations that value integrity—without sacrificing
|
|
232
|
+
to organizations and individuals that value integrity—without sacrificing
|
|
233
|
+
agility or trust.</strong>
|
|
214
234
|
We don't just secure infrastructure. We secure confidence.
|
|
215
235
|
</p>
|
|
216
236
|
|
|
@@ -218,7 +238,7 @@ This file is part of Network Pro.
|
|
|
218
238
|
|
|
219
239
|
<p>
|
|
220
240
|
<a href={contactLink} target={PAGE.BLANK}>Let's connect</a>
|
|
221
|
-
to discuss how we can help secure and strengthen your business today.
|
|
241
|
+
to discuss how we can help secure and strengthen your business or home today.
|
|
222
242
|
</p>
|
|
223
243
|
|
|
224
244
|
<div class="spacer"></div>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/* ==========================================================================
|
|
2
|
+
src/lib/pages/index.js
|
|
3
|
+
|
|
4
|
+
Copyright © 2025 Network Pro Strategies (Network Pro™)
|
|
5
|
+
SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
|
|
6
|
+
This file is part of Network Pro.
|
|
7
|
+
========================================================================== */
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Library index file
|
|
11
|
+
*
|
|
12
|
+
* @file index.js
|
|
13
|
+
* @description Export point for Svelte pages
|
|
14
|
+
* @module src/lib/pages
|
|
15
|
+
* @author SunDevil311
|
|
16
|
+
* @updated 2025-10-05
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
export { default as AboutContent } from './AboutContent.svelte';
|
|
20
|
+
export { default as FossContent } from './FossContent.svelte';
|
|
21
|
+
export { default as HomeContent } from './HomeContent.svelte';
|
|
22
|
+
export { default as LicenseContent } from './LicenseContent.svelte';
|
|
23
|
+
export { default as PGPContent } from './PGPContent.svelte';
|
|
24
|
+
export { default as PrivacyContent } from './PrivacyContent.svelte';
|
|
25
|
+
export { default as PrivacyDashboard } from './PrivacyDashboard.svelte';
|
|
26
|
+
export { default as TermsConditionsContent } from './TermsConditionsContent.svelte';
|
|
27
|
+
export { default as TermsUseContent } from './TermsUseContent.svelte';
|
|
@@ -469,6 +469,13 @@ footer .container {
|
|
|
469
469
|
word-break: normal; /* avoid deprecated behavior */
|
|
470
470
|
}
|
|
471
471
|
|
|
472
|
+
.full-width-section.centered {
|
|
473
|
+
display: flex;
|
|
474
|
+
justify-content: center;
|
|
475
|
+
flex-direction: column;
|
|
476
|
+
min-height: 80vh;
|
|
477
|
+
}
|
|
478
|
+
|
|
472
479
|
.fingerprint {
|
|
473
480
|
display: block;
|
|
474
481
|
font-weight: bold;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/*! ==========================================================================
|
|
2
|
+
src/lib/styles/css/global.css
|
|
3
|
+
|
|
2
4
|
Copyright © 2025 Network Pro Strategies (Network Pro™)
|
|
3
5
|
SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
|
|
4
6
|
This file is part of Network Pro.
|
|
5
7
|
========================================================================== */
|
|
6
|
-
html{-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{margin:.67em 0;font-size:2em}hr{box-sizing:content-box}pre{font-family:monospace;font-size:1em}a{background-color:#0000}abbr[title]{border-bottom:none;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace;font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:100%;line-height:1.15}button,input{overflow:visible}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button;appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted buttontext}fieldset{padding:.35em .75em .625em}legend{color:inherit;box-sizing:border-box;white-space:normal;max-width:100%;padding:0;display:table}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}details{display:block}summary{display:list-item}template{display:none}html{color:#222;scroll-behavior:smooth;font-size:1em;line-height:1.4}::-moz-selection{text-shadow:none;background:#191919}::selection{text-shadow:none;background:#191919}hr{border:0;border-top:1px solid #ccc;height:1px;margin:1em 0;padding:0;display:block;overflow:visible}audio,canvas,iframe,img,svg,video{vertical-align:middle}fieldset{border:0;margin:0;padding:0}textarea{resize:vertical}body{color:#fafafa;background-color:#191919;margin:10px;font-family:Arial,Helvetica,sans-serif}a{text-decoration:none}a:link{color:#ffc627}a:hover,a:active{color:#ffc627;text-decoration:underline}a:focus{color:#111;background-color:#ffc627}a:visited,a:visited:hover{color:#cba557}a:visited:focus,a:visited:focus-visible{color:#111!important}.hidden,[hidden]{display:none!important}.visually-hidden{clip:rect(0,0,0,0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.visually-hidden.focusable:active,.visually-hidden.focusable:focus{clip:auto;width:auto;height:auto;white-space:inherit;margin:0;position:static;overflow:visible}.invisible{visibility:hidden}.clearfix:before,.clearfix:after{content:"";display:table}.clearfix:after{clear:both}@media print{*,:before,:after{color:#000!important;box-shadow:none!important;text-shadow:none!important;background:#fff!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href)")"}abbr[title]:after{content:" (" attr(title)")"}a[href^=\#]:after,a[href^=javascript\:]:after{content:""}pre{white-space:pre-wrap!important}pre,blockquote{break-inside:avoid;border:1px solid #999}tr,img{break-inside:avoid}p,h2,h3{orphans:3;widows:3}h2,h3{break-after:avoid}}.full-width-section{background-position:50%;background-size:cover;width:100%;max-width:1920px;margin:0 auto}.container{max-width:1200px;margin:0 auto;padding:0 12px}.readable{max-width:900px;margin:0 auto}header,footer{width:100%}header .container,footer .container{max-width:1200px;margin:0 auto;padding:20px 12px}.gh{border-collapse:collapse;border-spacing:0;margin:0 auto}.gh td,.gh th{border-collapse:collapse;word-break:normal;padding:10px 5px;overflow:hidden}.gh .gh-tcell{text-align:center;vertical-align:middle}@media screen and (width<=767px){.gh,.gh col{width:auto!important}.gh-wrap{-webkit-overflow-scrolling:touch;margin:auto 0;overflow-x:auto}}.soc{border-collapse:collapse;border-spacing:0;margin:0 auto}.soc td,.soc th{border-collapse:collapse;word-break:normal;padding:8px;overflow:hidden}.soc .soc-fa{text-align:center;vertical-align:middle}@media screen and (width<=767px){.soc,.soc col{width:auto!important}.soc-wrap{-webkit-overflow-scrolling:touch;margin:auto 0;overflow-x:auto}}.foss{border-collapse:collapse;border-spacing:0}.foss td,.foss th{border-collapse:collapse;word-break:normal;padding:10px 5px;overflow:hidden}.foss .foss-cell{text-align:center;vertical-align:middle}@media screen and (width<=767px){.foss,.foss col{width:auto!important}.foss-wrap{-webkit-overflow-scrolling:touch;overflow-x:auto}}.bnav{text-align:center;border-collapse:collapse;border-spacing:0;margin:0 auto}.bnav td,.bnav th{text-align:center;vertical-align:middle;word-break:normal;border-style:none;padding:10px;font-size:.875rem;font-weight:700;line-height:1.125rem;overflow:hidden}.bnav .bnav-cell{text-align:center;vertical-align:middle;align-content:center}@media screen and (width<=767px){.bnav,.bnav col{width:auto!important}.bnav-wrap{-webkit-overflow-scrolling:touch;margin:auto 0;overflow-x:auto}}.bnav2{border-collapse:collapse;border-spacing:0;margin:0 auto}.bnav2 td{word-break:normal;border-style:none;padding:10px;font-size:.875rem;font-weight:700;line-height:1.125rem;overflow:hidden}.bnav2 th{word-break:normal;border-style:none;padding:12px;font-size:.875rem;line-height:1.125rem;overflow:hidden}.bnav2 .bnav2-cell{text-align:center;vertical-align:middle;align-content:center}@media screen and (width<=767px){.bnav2,.bnav2 col{width:auto!important}.bnav2-wrap{-webkit-overflow-scrolling:touch;margin:auto 0;overflow-x:auto}}.pgp{border-collapse:collapse;border-spacing:0;margin:0 auto}.pgp td{word-break:normal;border-style:none;padding:10px;font-size:.875rem;line-height:1.125rem;overflow:hidden}.pgp th{word-break:normal;border:1px solid #000;padding:10px;font-size:.875rem;line-height:1.125rem;overflow:hidden}.pgp .pgp-col1{text-align:right;vertical-align:middle;padding-right:1rem}.pgp .pgp-col2{text-align:left;vertical-align:middle;padding-left:1rem}@media screen and (width<=767px){.pgp,.pgp col{width:auto!important}.pgp-wrap{-webkit-overflow-scrolling:touch;margin:2rem 0 auto;overflow-x:auto}}.logo{margin-left:auto;margin-right:auto;display:block}.index-title1{text-align:center;font-style:italic;font-weight:700}.index-title2{letter-spacing:-.015em;text-align:center;font-variant:small-caps;font-size:1.25rem;line-height:1.625rem}.index1{letter-spacing:-.035em;text-align:center;font-style:italic;font-weight:700;line-height:2.125rem}.index2{letter-spacing:-.035em;text-align:center;font-variant:small-caps;font-size:1.5rem;line-height:1.75rem}.index3{letter-spacing:-.035em;text-align:center;font-size:1.5rem;line-height:1.75rem}.index4{letter-spacing:-.035em;text-align:center;font-size:1.5rem;line-height:1.75rem;text-decoration:underline}.subhead{letter-spacing:-.035em;font-variant:small-caps;font-size:1.5rem;line-height:1.75rem}.bold{font-weight:700}.emphasis{font-style:italic}.uline{text-decoration:underline}.bolditalic{font-style:italic;font-weight:700}.bquote{border-left:3px solid #9e9e9e;margin-left:30px;padding-left:10px;font-style:italic}.small-text{font-size:.75rem;line-height:1.125rem}.large-text-center{text-align:center;font-size:1.25rem;line-height:1.75rem}.prewrap{white-space:pre-wrap;display:block}.hr-styled{width:75%;margin:auto}.center-text{text-align:center}.copyright{text-align:center;font-size:.75rem;line-height:1.125rem}.gold{color:#ffc627}.visited{color:#cba557}.goldseparator{color:#ffc627;margin:0 .5rem}.center-nav{text-align:center;padding:5px;font-size:1rem;line-height:1.5rem}.block{overflow-wrap:break-word;resize:none;white-space:normal;word-break:normal;background:0 0;border:none;border-radius:0;outline:none;width:100%;font-family:monospace;font-size:.875rem;line-height:1.125rem}.fingerprint{white-space:pre-line;font-weight:700;display:block}.pgp-image{width:150px;height:150px}.spacer{margin:2rem 0}.separator{margin:0 .5rem}.emoji{margin-right:8px}.headline{margin-bottom:4px;font-style:italic;font-weight:700;display:block}.label{font-family:inherit;font-weight:700}.description{font-family:inherit;font-style:normal;font-weight:400;display:inline}.sr-only{clip:rect(0,0,0,0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.pgp-entry{flex-wrap:wrap;align-items:center;gap:2rem;margin-bottom:2rem;display:flex}.pgp-text{flex:2;min-width:250px}.pgp-qr{flex:1;min-width:150px}.obtainium-direct-label{margin:.25rem 0 .75rem;font-weight:700}.obtainium-manual-label{margin-top:.75rem;font-weight:700}.obtainium-img{width:185px;height:55px;margin-bottom:.25rem}.obtainium-margin{margin-left:4px}.obtainium-fa-down{color:#ffc627;margin-left:4px}.obtainium-icon{width:50px;height:50px}.proton-img{width:168px;height:24px}.redirect-text{text-align:center;margin-top:4rem}.redirect-content{text-align:center;margin-top:2rem;font-family:system-ui,sans-serif}.loading-spinner{border:4px solid #ddd;border-top-color:#ffc627;border-radius:50%;width:48px;height:48px;margin:2rem auto;animation:1s linear infinite spin}@keyframes spin{to{transform:rotate(360deg)}}.cc-link{text-decoration:none}.cc-img{vertical-align:text-bottom;margin-left:3px;display:inline-block;height:18px!important}
|
|
8
|
+
html{-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{margin:.67em 0;font-size:2em}hr{box-sizing:content-box}pre{font-family:monospace;font-size:1em}a{background-color:#0000}abbr[title]{border-bottom:none;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace;font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:100%;line-height:1.15}button,input{overflow:visible}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button;appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted buttontext}fieldset{padding:.35em .75em .625em}legend{color:inherit;box-sizing:border-box;white-space:normal;max-width:100%;padding:0;display:table}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}details{display:block}summary{display:list-item}template{display:none}html{color:#222;scroll-behavior:smooth;font-size:1em;line-height:1.4}::-moz-selection{text-shadow:none;background:#191919}::selection{text-shadow:none;background:#191919}hr{border:0;border-top:1px solid #ccc;height:1px;margin:1em 0;padding:0;display:block;overflow:visible}audio,canvas,iframe,img,svg,video{vertical-align:middle}fieldset{border:0;margin:0;padding:0}textarea{resize:vertical}body{color:#fafafa;background-color:#191919;margin:10px;font-family:Arial,Helvetica,sans-serif}a{text-decoration:none}a:link{color:#ffc627}a:hover,a:active{color:#ffc627;text-decoration:underline}a:focus{color:#111;background-color:#ffc627}a:visited,a:visited:hover{color:#cba557}a:visited:focus,a:visited:focus-visible{color:#111!important}.hidden,[hidden]{display:none!important}.visually-hidden{clip:rect(0,0,0,0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.visually-hidden.focusable:active,.visually-hidden.focusable:focus{clip:auto;width:auto;height:auto;white-space:inherit;margin:0;position:static;overflow:visible}.invisible{visibility:hidden}.clearfix:before,.clearfix:after{content:"";display:table}.clearfix:after{clear:both}@media print{*,:before,:after{color:#000!important;box-shadow:none!important;text-shadow:none!important;background:#fff!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href)")"}abbr[title]:after{content:" (" attr(title)")"}a[href^=\#]:after,a[href^=javascript\:]:after{content:""}pre{white-space:pre-wrap!important}pre,blockquote{break-inside:avoid;border:1px solid #999}tr,img{break-inside:avoid}p,h2,h3{orphans:3;widows:3}h2,h3{break-after:avoid}}.full-width-section{background-position:50%;background-size:cover;width:100%;max-width:1920px;margin:0 auto}.container{max-width:1200px;margin:0 auto;padding:0 12px}.readable{max-width:900px;margin:0 auto}header,footer{width:100%}header .container,footer .container{max-width:1200px;margin:0 auto;padding:20px 12px}.gh{border-collapse:collapse;border-spacing:0;margin:0 auto}.gh td,.gh th{border-collapse:collapse;word-break:normal;padding:10px 5px;overflow:hidden}.gh .gh-tcell{text-align:center;vertical-align:middle}@media screen and (width<=767px){.gh,.gh col{width:auto!important}.gh-wrap{-webkit-overflow-scrolling:touch;margin:auto 0;overflow-x:auto}}.soc{border-collapse:collapse;border-spacing:0;margin:0 auto}.soc td,.soc th{border-collapse:collapse;word-break:normal;padding:8px;overflow:hidden}.soc .soc-fa{text-align:center;vertical-align:middle}@media screen and (width<=767px){.soc,.soc col{width:auto!important}.soc-wrap{-webkit-overflow-scrolling:touch;margin:auto 0;overflow-x:auto}}.foss{border-collapse:collapse;border-spacing:0}.foss td,.foss th{border-collapse:collapse;word-break:normal;padding:10px 5px;overflow:hidden}.foss .foss-cell{text-align:center;vertical-align:middle}@media screen and (width<=767px){.foss,.foss col{width:auto!important}.foss-wrap{-webkit-overflow-scrolling:touch;overflow-x:auto}}.bnav{text-align:center;border-collapse:collapse;border-spacing:0;margin:0 auto}.bnav td,.bnav th{text-align:center;vertical-align:middle;word-break:normal;border-style:none;padding:10px;font-size:.875rem;font-weight:700;line-height:1.125rem;overflow:hidden}.bnav .bnav-cell{text-align:center;vertical-align:middle;align-content:center}@media screen and (width<=767px){.bnav,.bnav col{width:auto!important}.bnav-wrap{-webkit-overflow-scrolling:touch;margin:auto 0;overflow-x:auto}}.bnav2{border-collapse:collapse;border-spacing:0;margin:0 auto}.bnav2 td{word-break:normal;border-style:none;padding:10px;font-size:.875rem;font-weight:700;line-height:1.125rem;overflow:hidden}.bnav2 th{word-break:normal;border-style:none;padding:12px;font-size:.875rem;line-height:1.125rem;overflow:hidden}.bnav2 .bnav2-cell{text-align:center;vertical-align:middle;align-content:center}@media screen and (width<=767px){.bnav2,.bnav2 col{width:auto!important}.bnav2-wrap{-webkit-overflow-scrolling:touch;margin:auto 0;overflow-x:auto}}.pgp{border-collapse:collapse;border-spacing:0;margin:0 auto}.pgp td{word-break:normal;border-style:none;padding:10px;font-size:.875rem;line-height:1.125rem;overflow:hidden}.pgp th{word-break:normal;border:1px solid #000;padding:10px;font-size:.875rem;line-height:1.125rem;overflow:hidden}.pgp .pgp-col1{text-align:right;vertical-align:middle;padding-right:1rem}.pgp .pgp-col2{text-align:left;vertical-align:middle;padding-left:1rem}@media screen and (width<=767px){.pgp,.pgp col{width:auto!important}.pgp-wrap{-webkit-overflow-scrolling:touch;margin:2rem 0 auto;overflow-x:auto}}.logo{margin-left:auto;margin-right:auto;display:block}.index-title1{text-align:center;font-style:italic;font-weight:700}.index-title2{letter-spacing:-.015em;text-align:center;font-variant:small-caps;font-size:1.25rem;line-height:1.625rem}.index1{letter-spacing:-.035em;text-align:center;font-style:italic;font-weight:700;line-height:2.125rem}.index2{letter-spacing:-.035em;text-align:center;font-variant:small-caps;font-size:1.5rem;line-height:1.75rem}.index3{letter-spacing:-.035em;text-align:center;font-size:1.5rem;line-height:1.75rem}.index4{letter-spacing:-.035em;text-align:center;font-size:1.5rem;line-height:1.75rem;text-decoration:underline}.subhead{letter-spacing:-.035em;font-variant:small-caps;font-size:1.5rem;line-height:1.75rem}.bold{font-weight:700}.emphasis{font-style:italic}.uline{text-decoration:underline}.bolditalic{font-style:italic;font-weight:700}.bquote{border-left:3px solid #9e9e9e;margin-left:30px;padding-left:10px;font-style:italic}.small-text{font-size:.75rem;line-height:1.125rem}.large-text-center{text-align:center;font-size:1.25rem;line-height:1.75rem}.prewrap{white-space:pre-wrap;display:block}.hr-styled{width:75%;margin:auto}.center-text{text-align:center}.copyright{text-align:center;font-size:.75rem;line-height:1.125rem}.gold{color:#ffc627}.visited{color:#cba557}.goldseparator{color:#ffc627;margin:0 .5rem}.center-nav{text-align:center;padding:5px;font-size:1rem;line-height:1.5rem}.block{overflow-wrap:break-word;resize:none;white-space:normal;word-break:normal;background:0 0;border:none;border-radius:0;outline:none;width:100%;font-family:monospace;font-size:.875rem;line-height:1.125rem}.full-width-section.centered{flex-direction:column;justify-content:center;min-height:80vh;display:flex}.fingerprint{white-space:pre-line;font-weight:700;display:block}.pgp-image{width:150px;height:150px}.spacer{margin:2rem 0}.separator{margin:0 .5rem}.emoji{margin-right:8px}.headline{margin-bottom:4px;font-style:italic;font-weight:700;display:block}.label{font-family:inherit;font-weight:700}.description{font-family:inherit;font-style:normal;font-weight:400;display:inline}.sr-only{clip:rect(0,0,0,0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.pgp-entry{flex-wrap:wrap;align-items:center;gap:2rem;margin-bottom:2rem;display:flex}.pgp-text{flex:2;min-width:250px}.pgp-qr{flex:1;min-width:150px}.obtainium-direct-label{margin:.25rem 0 .75rem;font-weight:700}.obtainium-manual-label{margin-top:.75rem;font-weight:700}.obtainium-img{width:185px;height:55px;margin-bottom:.25rem}.obtainium-margin{margin-left:4px}.obtainium-fa-down{color:#ffc627;margin-left:4px}.obtainium-icon{width:50px;height:50px}.proton-img{width:168px;height:24px}.redirect-text{text-align:center;margin-top:4rem}.redirect-content{text-align:center;margin-top:2rem;font-family:system-ui,sans-serif}.loading-spinner{border:4px solid #ddd;border-top-color:#ffc627;border-radius:50%;width:48px;height:48px;margin:2rem auto;animation:1s linear infinite spin}@keyframes spin{to{transform:rotate(360deg)}}.cc-link{text-decoration:none}.cc-img{vertical-align:text-bottom;margin-left:3px;display:inline-block;height:18px!important}
|
package/src/lib/styles/index.js
CHANGED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
<!-- =====================================================================
|
|
2
|
+
src/lib/types/README.md
|
|
3
|
+
|
|
4
|
+
Copyright © 2025 Network Pro Strategies (Network Pro™)
|
|
5
|
+
SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
|
|
6
|
+
This file is part of Network Pro.
|
|
7
|
+
====================================================================== -->
|
|
8
|
+
|
|
9
|
+
# Typing Policy
|
|
10
|
+
|
|
11
|
+
This directory contains JSDoc-based type definitions for reusable modules
|
|
12
|
+
within the Network Pro codebase. The goal is to provide meaningful IntelliSense,
|
|
13
|
+
editor documentation, and lightweight type safety without requiring TypeScript
|
|
14
|
+
conversion.
|
|
15
|
+
|
|
16
|
+
## Scope and Philosophy
|
|
17
|
+
|
|
18
|
+
- **Structured Data Only** – Typing is focused on objects that benefit from
|
|
19
|
+
explicit schemas (e.g., configuration, constants, utilities).
|
|
20
|
+
- **Svelte Components** – Components are intentionally _not_ fully typed at this
|
|
21
|
+
stage. Component auto-completion is already handled by the Svelte language
|
|
22
|
+
server, and explicit typedefs would add unnecessary complexity.
|
|
23
|
+
- **Scalability** – Typing is modular. New typedefs can be added under
|
|
24
|
+
`/src/lib/types/` as the codebase grows.
|
|
25
|
+
- **Documentation-Driven** – JSDoc comments serve both as type definitions and
|
|
26
|
+
developer documentation. This minimizes friction while improving clarity.
|
|
27
|
+
|
|
28
|
+
## Example
|
|
29
|
+
|
|
30
|
+
```js
|
|
31
|
+
/** @typedef {import('./types/appConstants.js').AppConstants} AppConstants */
|
|
32
|
+
/** @type {AppConstants} */
|
|
33
|
+
export const CONSTANTS = { ... };
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
This approach balances clarity and maintainability without introducing a
|
|
37
|
+
TypeScript build requirement.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
<span style="font-size: 12px; text-align: center;">
|
|
42
|
+
|
|
43
|
+
Copyright © 2025
|
|
44
|
+
**[Network Pro Strategies](https://netwk.pro) (Network Pro™)**
|
|
45
|
+
|
|
46
|
+
Network Pro™, the shield logo, and the "Locking Down Networks...™" slogan are [trademarks](https://netwk.pro/license#trademark) of Network Pro Strategies.
|
|
47
|
+
|
|
48
|
+
Licensed under **[CC BY 4.0](https://netwk.pro/license#cc-by)** and the **[GNU GPL](https://netwk.pro/license#gnu-gpl)**, as published by the [Free Software Foundation](https://www.fsf.org), either version 3 of the License, or (at your option) any later version.
|
|
49
|
+
|
|
50
|
+
</span>
|
|
@@ -14,21 +14,15 @@ This file is part of Network Pro.
|
|
|
14
14
|
import { initPostHog, showReminder, capture } from '$lib/stores/posthog';
|
|
15
15
|
import { registerServiceWorker } from '$lib/registerServiceWorker.js';
|
|
16
16
|
import { browser } from '$app/environment';
|
|
17
|
+
import { logoPng, logoWbp, faviconSvg, appleTouchIcon } from '$lib';
|
|
18
|
+
import { ContainerSection, PWAInstallButton } from '$lib/components';
|
|
19
|
+
import { Footer, HeaderDefault, HeaderHome } from '$lib/components/layout';
|
|
17
20
|
|
|
18
|
-
import
|
|
19
|
-
import Footer from '$lib/components/layout/Footer.svelte';
|
|
20
|
-
import HeaderDefault from '$lib/components/layout/HeaderDefault.svelte';
|
|
21
|
-
import HeaderHome from '$lib/components/layout/HeaderHome.svelte';
|
|
22
|
-
import PWAInstallButton from '$lib/components/PWAInstallButton.svelte';
|
|
21
|
+
//import PWAInstallButton from '$lib/components/PWAInstallButton.svelte';
|
|
23
22
|
|
|
24
23
|
import '$lib/styles/global.min.css';
|
|
25
24
|
import '$lib/styles/fa-global.css';
|
|
26
25
|
|
|
27
|
-
import logoPng from '$lib/img/logo-web.png';
|
|
28
|
-
import logoWbp from '$lib/img/logo-web.webp';
|
|
29
|
-
import faviconSvg from '$lib/img/favicon.svg';
|
|
30
|
-
import appleTouchIcon from '$lib/img/icon-180x180.png';
|
|
31
|
-
|
|
32
26
|
$: shouldShowReminder = $showReminder;
|
|
33
27
|
|
|
34
28
|
onMount(() => {
|
package/src/routes/+page.svelte
CHANGED
|
@@ -7,13 +7,15 @@ This file is part of Network Pro.
|
|
|
7
7
|
========================================================================== -->
|
|
8
8
|
|
|
9
9
|
<script>
|
|
10
|
-
import
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
10
|
+
import {
|
|
11
|
+
Badges,
|
|
12
|
+
FullWidthSection,
|
|
13
|
+
LegalNav,
|
|
14
|
+
Logo,
|
|
15
|
+
SocialMedia,
|
|
16
|
+
MetaTags,
|
|
17
|
+
} from '$lib/components';
|
|
18
|
+
import { HomeContent } from '$lib/pages';
|
|
17
19
|
|
|
18
20
|
/**
|
|
19
21
|
* @type {string}
|
|
@@ -7,16 +7,17 @@ This file is part of Network Pro.
|
|
|
7
7
|
========================================================================== -->
|
|
8
8
|
|
|
9
9
|
<script>
|
|
10
|
-
import RedirectPage from '$lib/components/RedirectPage.svelte';
|
|
11
10
|
import { appendUTM } from '$lib/utils/utm.js';
|
|
12
11
|
import { getUTMParams } from '$lib/utils/getUTMParams.js';
|
|
13
12
|
import { trackingEnabled } from '$lib/stores/trackingPreferences';
|
|
14
|
-
import
|
|
13
|
+
import { RedirectPage } from '$lib/components';
|
|
15
14
|
import { get } from 'svelte/store';
|
|
16
15
|
import { onMount } from 'svelte';
|
|
17
16
|
import { browser } from '$app/environment';
|
|
18
17
|
import { CONSTANTS } from '$lib';
|
|
19
18
|
|
|
19
|
+
import posthog from 'posthog-js';
|
|
20
|
+
|
|
20
21
|
//console.log(CONSTANTS.COMPANY_INFO.APP_NAME);
|
|
21
22
|
|
|
22
23
|
const { PAGE } = CONSTANTS;
|
package/static/disableSw.js
CHANGED
|
@@ -9,9 +9,9 @@ This file is part of Network Pro.
|
|
|
9
9
|
/**
|
|
10
10
|
* @file disableSw.js
|
|
11
11
|
* @description Allows for Service Worker to be disabled for debugging by appending ?nosw to the path.
|
|
12
|
-
* @module
|
|
12
|
+
* @module static
|
|
13
13
|
* @author SunDevil311
|
|
14
|
-
* @updated 2025-05
|
|
14
|
+
* @updated 2025-10-05
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
if (location.search.includes('nosw')) {
|
package/static/sitemap.xml
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<!-- Sitemap last updated 2025-
|
|
2
|
+
<!-- Sitemap last updated 2025-10-06 -->
|
|
3
3
|
|
|
4
4
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
5
5
|
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
<loc>https://netwk.pro</loc>
|
|
9
9
|
|
|
10
|
-
<lastmod>2025-
|
|
10
|
+
<lastmod>2025-10-06</lastmod>
|
|
11
11
|
|
|
12
12
|
<changefreq>weekly</changefreq>
|
|
13
13
|
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
|
|
32
32
|
<loc>https://netwk.pro/about</loc>
|
|
33
33
|
|
|
34
|
-
<lastmod>2025-06
|
|
34
|
+
<lastmod>2025-10-06</lastmod>
|
|
35
35
|
|
|
36
36
|
<changefreq>monthly</changefreq>
|
|
37
37
|
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/* ==========================================================================
|
|
2
|
+
tests/unit/client/lib/PWAInstallButton.test.js
|
|
3
|
+
|
|
4
|
+
Copyright © 2025 Network Pro Strategies (Network Pro™)
|
|
5
|
+
SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
|
|
6
|
+
This file is part of Network Pro.
|
|
7
|
+
========================================================================== */
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @file redirect.test.js
|
|
11
|
+
* @description Unit test for PWA install component
|
|
12
|
+
* @module tests/unit/lib
|
|
13
|
+
* @author SunDevil311
|
|
14
|
+
* @updated 2025-10-05
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import PWAInstallButton from '$lib/components/PWAInstallButton.svelte';
|
|
18
|
+
import { fireEvent, render, waitFor } from '@testing-library/svelte';
|
|
19
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
20
|
+
|
|
21
|
+
/* --------------------------------------------------------------------------
|
|
22
|
+
Fake BeforeInstallPromptEvent Mock
|
|
23
|
+
--------------------------------------------------------------------------
|
|
24
|
+
*/
|
|
25
|
+
class FakeBeforeInstallPromptEvent {
|
|
26
|
+
constructor() {
|
|
27
|
+
this.prompt = vi.fn();
|
|
28
|
+
this.userChoice = Promise.resolve({
|
|
29
|
+
outcome: 'accepted',
|
|
30
|
+
platform: 'test',
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/* --------------------------------------------------------------------------
|
|
36
|
+
Tests
|
|
37
|
+
-------------------------------------------------------------------------- */
|
|
38
|
+
describe('PWAInstallButton', () => {
|
|
39
|
+
it('shows button when pwa-install-available event is fired', async () => {
|
|
40
|
+
const { getByRole, queryByRole } = render(PWAInstallButton);
|
|
41
|
+
|
|
42
|
+
// Initially, the install button should not be in the DOM
|
|
43
|
+
expect(queryByRole('button')).toBeNull();
|
|
44
|
+
|
|
45
|
+
// Dispatch the custom event that makes the button appear
|
|
46
|
+
const fakeEvent = new FakeBeforeInstallPromptEvent();
|
|
47
|
+
window.dispatchEvent(
|
|
48
|
+
new CustomEvent('pwa-install-available', { detail: fakeEvent }),
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
// Verify that the button now appears
|
|
52
|
+
const button = await waitFor(() =>
|
|
53
|
+
getByRole('button', { name: /install app/i }),
|
|
54
|
+
);
|
|
55
|
+
expect(button).toBeInTheDocument();
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('calls prompt() when install button is clicked', async () => {
|
|
59
|
+
const { getByRole } = render(PWAInstallButton);
|
|
60
|
+
|
|
61
|
+
// Fire the event that makes the button visible
|
|
62
|
+
const fakeEvent = new FakeBeforeInstallPromptEvent();
|
|
63
|
+
window.dispatchEvent(
|
|
64
|
+
new CustomEvent('pwa-install-available', { detail: fakeEvent }),
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
// Wait until the button appears
|
|
68
|
+
const button = await waitFor(() =>
|
|
69
|
+
getByRole('button', { name: /install app/i }),
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
// Simulate a user clicking the install button
|
|
73
|
+
await fireEvent.click(button);
|
|
74
|
+
|
|
75
|
+
// Verify that prompt() was called — the core behavior we care about
|
|
76
|
+
expect(fakeEvent.prompt).toHaveBeenCalled();
|
|
77
|
+
|
|
78
|
+
// (Removed: button disappearance check, since it depends on async animation timing)
|
|
79
|
+
});
|
|
80
|
+
});
|
package/vitest-setup-client.js
CHANGED
|
@@ -25,6 +25,15 @@ Object.defineProperty(window, 'matchMedia', {
|
|
|
25
25
|
})),
|
|
26
26
|
});
|
|
27
27
|
|
|
28
|
+
// Mock Web Animations API (jsdom doesn't implement element.animate)
|
|
29
|
+
if (!Element.prototype.animate) {
|
|
30
|
+
Element.prototype.animate = () => ({
|
|
31
|
+
onfinish: null,
|
|
32
|
+
cancel: () => {},
|
|
33
|
+
finished: Promise.resolve(),
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
28
37
|
// Automatically clean up the DOM after each test
|
|
29
38
|
afterEach(() => {
|
|
30
39
|
cleanup();
|
package/scripts/testRedirects.js
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
/* ==========================================================================
|
|
2
|
-
scripts/testRedirects.js
|
|
3
|
-
|
|
4
|
-
Copyright © 2025 Network Pro Strategies (Network Pro™)
|
|
5
|
-
SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
|
|
6
|
-
This file is part of Network Pro.
|
|
7
|
-
========================================================================== */
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* @file testRedirects.js
|
|
11
|
-
* @description Tests Netlify redirects against actual endpoints to verify
|
|
12
|
-
* trailing-slash behavior.
|
|
13
|
-
*
|
|
14
|
-
* @module scripts/
|
|
15
|
-
* @author SunDevil311
|
|
16
|
-
* @updated 2025-07-01
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
import https from 'https';
|
|
20
|
-
import { URL } from 'url';
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* @typedef {object} RedirectTest
|
|
24
|
-
* @property {string} from - The source URL to test.
|
|
25
|
-
* @property {string} to - The expected destination URL.
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
|
-
/** @type {RedirectTest[]} */
|
|
29
|
-
const urls = [
|
|
30
|
-
{ from: 'https://netwk.pro/privacy-policy', to: 'https://netwk.pro/privacy' },
|
|
31
|
-
{
|
|
32
|
-
from: 'https://netwk.pro/privacy-policy/',
|
|
33
|
-
to: 'https://netwk.pro/privacy',
|
|
34
|
-
},
|
|
35
|
-
{ from: 'https://netwk.pro/foss', to: 'https://netwk.pro/foss-spotlight' },
|
|
36
|
-
{ from: 'https://netwk.pro/foss/', to: 'https://netwk.pro/foss-spotlight' },
|
|
37
|
-
{
|
|
38
|
-
from: 'https://www.netwk.pro/foss',
|
|
39
|
-
to: 'https://netwk.pro/foss-spotlight',
|
|
40
|
-
},
|
|
41
|
-
];
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Tests a single redirect by making a GET request and checking the status code and location header.
|
|
45
|
-
* @param {RedirectTest} redirect - The redirect configuration to test.
|
|
46
|
-
* @returns {Promise<boolean>} - Resolves to true if the redirect is correct, false otherwise.
|
|
47
|
-
*/
|
|
48
|
-
function testRedirect({ from, to }) {
|
|
49
|
-
return new Promise((resolve) => {
|
|
50
|
-
const req = https.request(new URL(from), { method: 'GET' }, (res) => {
|
|
51
|
-
const location = res.headers.location;
|
|
52
|
-
const expectedPath = new URL(to).pathname;
|
|
53
|
-
|
|
54
|
-
if (res.statusCode === 301 && location === expectedPath) {
|
|
55
|
-
console.log(`✅ ${from} → ${location}`);
|
|
56
|
-
resolve(true);
|
|
57
|
-
} else {
|
|
58
|
-
console.error(
|
|
59
|
-
`❌ ${from} → Expected 301 to ${expectedPath}, got ${res.statusCode} to ${location}`,
|
|
60
|
-
);
|
|
61
|
-
resolve(false);
|
|
62
|
-
}
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
req.on('error', (err) => {
|
|
66
|
-
console.error(`❌ ${from} → Network error: ${err.message}`);
|
|
67
|
-
resolve(false);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
req.end();
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Runs all redirect tests and exits the process with a status code reflecting success or failure.
|
|
76
|
-
* @returns {Promise<void>}
|
|
77
|
-
*/
|
|
78
|
-
const runTests = async () => {
|
|
79
|
-
const results = await Promise.all(urls.map(testRedirect));
|
|
80
|
-
const failed = results.filter((r) => !r).length;
|
|
81
|
-
process.exit(failed > 0 ? 1 : 0);
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
runTests();
|