@networkpro/web 1.21.1 → 1.22.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 CHANGED
@@ -22,6 +22,68 @@ This project attempts to follow [Keep a Changelog](https://keepachangelog.com/en
22
22
 
23
23
  ---
24
24
 
25
+ ## [1.22.0] - 2025-10-20
26
+
27
+ ### Added
28
+
29
+ - Introduced **dynamic QR code image imports** using `import.meta.glob` in `src/lib/images.js`.
30
+ - Implemented new `getQR()` helper function for streamlined QR lookups.
31
+ - Added `QR_IMAGES` registry for centralized QR asset management.
32
+ - Created dedicated PGP key data module (`src/lib/data/pgpKeys.js`) with dynamic QR bindings.
33
+ - Added new app constants (`EMAIL_LINK`, `SECURE_LINK`, `PRIVACY_LINK`) to:
34
+ - `src/lib/index.js`
35
+ - `src/lib/types/appConstants.js`
36
+ - Re-exported `src/lib/data/pgpKeys.js` from `src/lib/index.js`.
37
+ - Added favicon and manifest entry for `icon-about.png`.
38
+ - Introduced updated **contact assets block** in `AboutContent.svelte` with enhanced typing.
39
+ - Exported `src/lib/img/powered-by-proton.svg` from `src/lib/images.js`.
40
+ - Added missing JSDoc annotation to `src/lib/data/fossData.js`.
41
+ - Added updated PGP key for `support@netwk.pro` (previously `support@neteng.pro`).
42
+
43
+ ### Changed
44
+
45
+ - Bumped project version to `v1.22.0`.
46
+ - Updated generator metadata in `src/app.html` to reflect **SvelteKit 2.47.2**.
47
+ - Refactored **PGPContent.svelte** to use the `getQR()` helper and dynamic QR registry.
48
+ - Refactored **AboutContent.svelte** to use the centralized `PGP_KEYS` dataset and app constants.
49
+ - Split PGP key fingerprints into two lines for improved readability.
50
+ - Enhanced **images.js** with support for eager QR image imports.
51
+ - Replaced static PGP imports with automated dynamic resolution.
52
+ - Updated **manifest.json** to reference the new app icon.
53
+ - Revised layout and text consistency for PGP and contact sections in **AboutContent.svelte**.
54
+ - Updated type definitions in `src/lib/types/appConstants.js` for `CONTACT` constants.
55
+ - Cleaned up unused imports and improved inline JSDoc typings throughout the app.
56
+ - Updated asset references in `IGNORE_PATHS` and `REQUIRED_ASSETS` in `src/service-worker.js`.
57
+ - Added spacing adjustments to the tagline in **Logo.svelte**.
58
+ - Updated **HeaderDefault.svelte** to reference the global constant for the **Blog** link.
59
+ - Revised text and app constant usage in **HomeContent.svelte**.
60
+ - Updated the contact section and **Effective Date** in **ServicesContent.svelte**.
61
+ - Rebuilt `src/lib/styles/global.min.css` using **LightningCSS**.
62
+ - Refreshed `_Last Modified_` timestamps in `static/sitemap.xml`.
63
+
64
+ ### Fixed
65
+
66
+ - Fixed SSR error caused by missing `getQR` reference during page load.
67
+ - Corrected destructuring of `CONTACT` constants during SSR initialization.
68
+ - Fixed fingerprint rendering fallback when fingerprint type was non-array.
69
+ - Adjusted QR image alignment and eager/lazy decoding behavior.
70
+
71
+ ### Removed
72
+
73
+ - Deleted outdated static assets from `static/pgp`, replaced with dynamically loaded QR images.
74
+ - Removed redundant manual image imports from legacy sections of `images.js`.
75
+ - Removed unnecessary comment block from the `<head>` section of `src/app.html`.
76
+ - Removed `font-weight: bold` property from the `.fingerprint` CSS class in `src/lib/styles/css/default.css`.
77
+
78
+ ### 🧩 Technical Notes
79
+
80
+ - Updated `vite` from `v7.1.10` → `v7.1.11` to address **CVE-2025-62522**.
81
+ - Updated dependencies for SvelteKit `2.47.2` compatibility:
82
+ - `@sveltejs/kit`, `svelte`, `vite`, and `eslint`-related plugins.
83
+ - Cleaned up build cache and service worker registration logic in `src/service-worker.js`.
84
+
85
+ ---
86
+
25
87
  ## [1.21.1] - 2025-10-17
26
88
 
27
89
  ### Added
@@ -1169,7 +1231,8 @@ This project attempts to follow [Keep a Changelog](https://keepachangelog.com/en
1169
1231
 
1170
1232
  <!-- Link references -->
1171
1233
 
1172
- [Unreleased]: https://github.com/netwk-pro/netwk-pro.github.io/compare/v1.21.1...HEAD
1234
+ [Unreleased]: https://github.com/netwk-pro/netwk-pro.github.io/compare/v1.22.0...HEAD
1235
+ [1.22.0]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.22.0
1173
1236
  [1.21.1]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.21.1
1174
1237
  [1.21.0]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.21.0
1175
1238
  [1.20.0]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.20.0
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@networkpro/web",
3
3
  "private": false,
4
- "version": "1.21.1",
4
+ "version": "1.22.0",
5
5
  "description": "Locking Down Networks, Unlocking Confidence™ | Security, Networking, Privacy — Network Pro Strategies",
6
6
  "keywords": [
7
7
  "advisory",
@@ -78,9 +78,9 @@
78
78
  },
79
79
  "dependencies": {
80
80
  "dompurify": "^3.3.0",
81
- "posthog-js": "^1.276.0",
81
+ "posthog-js": "^1.278.0",
82
82
  "semver": "^7.7.3",
83
- "svelte": "5.40.2"
83
+ "svelte": "5.41.1"
84
84
  },
85
85
  "devDependencies": {
86
86
  "@eslint/compat": "^1.4.0",
@@ -88,7 +88,7 @@
88
88
  "@lhci/cli": "^0.15.1",
89
89
  "@playwright/test": "^1.56.1",
90
90
  "@sveltejs/adapter-vercel": "^6.0.0",
91
- "@sveltejs/kit": "2.47.1",
91
+ "@sveltejs/kit": "2.47.2",
92
92
  "@sveltejs/vite-plugin-svelte": "^6.2.1",
93
93
  "@testing-library/jest-dom": "^6.9.1",
94
94
  "@testing-library/svelte": "^5.2.8",
@@ -97,8 +97,8 @@
97
97
  "browserslist": "^4.26.3",
98
98
  "eslint": "^9.38.0",
99
99
  "eslint-config-prettier": "^10.1.8",
100
- "eslint-plugin-jsdoc": "^61.1.4",
101
- "eslint-plugin-svelte": "^3.12.4",
100
+ "eslint-plugin-jsdoc": "^61.1.5",
101
+ "eslint-plugin-svelte": "^3.12.5",
102
102
  "globals": "^16.4.0",
103
103
  "jsdom": "26.1.0",
104
104
  "lightningcss": "^1.30.2",
@@ -113,10 +113,10 @@
113
113
  "stylelint-config-recommended": "^17.0.0",
114
114
  "stylelint-order": "^7.0.0",
115
115
  "svelte-check": "^4.3.3",
116
- "svelte-eslint-parser": "^1.3.3",
116
+ "svelte-eslint-parser": "^1.4.0",
117
117
  "svelte-preprocess": "^6.0.3",
118
118
  "typescript": "^5.9.3",
119
- "vite": "^7.1.10",
119
+ "vite": "^7.1.11",
120
120
  "vite-plugin-lightningcss": "^0.0.5",
121
121
  "vite-tsconfig-paths": "^5.1.4",
122
122
  "vitest": "^3.2.4"
package/src/app.html CHANGED
@@ -24,17 +24,6 @@
24
24
  sizes="any"
25
25
  type="image/x-icon" />
26
26
 
27
- <!-- Preconnect to PostHog domains
28
- <link
29
- rel="preconnect"
30
- href="https://us.i.posthog.com"
31
- crossorigin="anonymous" />
32
- <link
33
- rel="preconnect"
34
- href="https://us-assets.i.posthog.com"
35
- crossorigin="anonymous" />
36
- -->
37
-
38
27
  <!-- Preload FontAwesome webfonts -->
39
28
  <link
40
29
  rel="preload"
@@ -64,7 +53,7 @@
64
53
  content="bx4ham0zkpvzztzu213bhpt76m9siq" />
65
54
  <!-- cspell:enable -->
66
55
 
67
- <meta name="generator" content="SvelteKit 2.47.1" />
56
+ <meta name="generator" content="SvelteKit 2.47.2" />
68
57
 
69
58
  <script src="/disableSw.js"></script>
70
59
 
@@ -75,12 +75,6 @@ This file is part of Network Pro.
75
75
  * @type {"high" | "low" | "auto"}
76
76
  */
77
77
  export let fetchpriority = 'high';
78
-
79
- /**
80
- * Tagline text to display.
81
- * @type {string}
82
- */
83
- export let tagline = 'Security | Networking | Privacy';
84
78
  </script>
85
79
 
86
80
  <!-- BEGIN LOGO AND SITE TITLE -->
@@ -107,6 +101,7 @@ This file is part of Network Pro.
107
101
  <div class="spacer"></div>
108
102
 
109
103
  {#if showTagline}
110
- <h2 class="index-title2">{tagline}</h2>
104
+ <h2 class="index-title2"
105
+ >{['Security', 'Networking', 'Privacy'].join(' \u00A0 | \u00A0 ')}</h2>
111
106
  {/if}
112
107
  <!-- END LOGO AND SITE TITLE -->
@@ -15,14 +15,13 @@ This file is part of Network Pro.
15
15
 
16
16
  //console.log(CONSTANTS.COMPANY_INFO.APP_NAME);
17
17
 
18
- const { PAGE } = CONSTANTS;
18
+ const { PAGE, LINKS } = CONSTANTS;
19
19
 
20
20
  const homeLink = base || '/';
21
21
  const aboutLink = `${base}/about`;
22
22
  const servLink = `${base}/services`;
23
23
  const lhubLink = `${base}/links`;
24
24
  const fossLink = `${base}/foss-spotlight`;
25
- const blogLink = 'https://blog.netwk.pro';
26
25
  const discussLink =
27
26
  'https://github.com/netwk-pro/netwk-pro.github.io/discussions';
28
27
 
@@ -46,7 +45,7 @@ This file is part of Network Pro.
46
45
  { label: 'services', href: servLink, target: PAGE.SELF, external: false },
47
46
  {
48
47
  label: 'blog',
49
- href: blogLink,
48
+ href: LINKS.BLOG,
50
49
  target: PAGE.SELF,
51
50
  external: false,
52
51
  },
@@ -6,6 +6,14 @@ SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
6
6
  This file is part of Network Pro.
7
7
  ========================================================================== */
8
8
 
9
+ /**
10
+ * @file fossData.js
11
+ * @description Data for FOSS Spotlight route
12
+ * @module src/lib/data
13
+ * @author Scott Lopez
14
+ * @updated 2025-10-20
15
+ */
16
+
9
17
  // Import FOSS images
10
18
  import { acodePng, acodeWbp, cryptomPng, cryptomWbp, eauthPng, eauthWbp, hboardPng, hboardWbp, lsheetPng, lsheetWbp, otphelpPng, otphelpWbp, pmxPng, pmxWbp, squirclePng, squircleWbp, tosPng, tosWbp, urlPng, urlWbp } from "$lib";
11
19
 
@@ -0,0 +1,82 @@
1
+ /* ==========================================================================
2
+ src/lib/data/pgpKeys.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 pgpKeys.js
11
+ * @description Dedicated data module for PGP key definitions
12
+ * @module src/lib/data
13
+ * @author Scott Lopez
14
+ * @updated 2025-10-20
15
+ */
16
+
17
+ import { getQR } from '$lib';
18
+
19
+ /**
20
+ * @typedef {{ png?: string; webp?: string }} QrImagePair
21
+ *
22
+ * @typedef {QrImagePair & {
23
+ * id: string;
24
+ * name: string;
25
+ * email: string;
26
+ * fingerprint: string;
27
+ * opgp: string;
28
+ * file: string;
29
+ * }} PgpKeyEntry
30
+ */
31
+
32
+ /**
33
+ * Base definitions for PGP keys. Each `id` must match a QR code image name
34
+ * (e.g. "pgp-support" → pgp-support.png / pgp-support.webp).
35
+ *
36
+ * @type {Array<{
37
+ * id: string;
38
+ * name: string;
39
+ * email: string;
40
+ * fingerprint: string;
41
+ * opgp: string;
42
+ * file: string;
43
+ * }>}
44
+ */
45
+ const BASE_PGP_KEYS = [
46
+ {
47
+ id: 'pgp-support',
48
+ name: 'General Contact & Support',
49
+ email: 'support (at) netwk.pro',
50
+ fingerprint: '6590 B992 E2E3 EFF1 2738 7BCE 2AF0 93E9 DEC6 1BA0',
51
+ opgp: 'https://keys.openpgp.org/search?q=support%40netwk.pro',
52
+ file: '/pgp/support@netwk.pro.asc',
53
+ },
54
+ {
55
+ id: 'pgp-contact',
56
+ name: 'Secure Email',
57
+ email: 'contact (at) s.neteng.pro',
58
+ fingerprint: 'DF11 8BAA 6C2D 9DCD EBDC 2DDC F993 7349 9495 F957',
59
+ opgp: 'https://keys.openpgp.org/search?q=contact%40s.neteng.pro',
60
+ file: '/pgp/contact@s.neteng.pro.asc',
61
+ },
62
+ {
63
+ id: 'pgp-security',
64
+ name: 'Security Contact',
65
+ email: 'security (at) s.neteng.pro',
66
+ fingerprint: 'B7FE 1D4E 6CAB 3E71 4A9F DF6E 48CB 7290 C00D 0DA5',
67
+ opgp: 'https://keys.openpgp.org/search?q=security%40s.neteng.pro',
68
+ file: '/pgp/security@s.neteng.pro.asc',
69
+ },
70
+ ];
71
+
72
+ /**
73
+ * Full list of enriched PGP keys, each with dynamically resolved QR images.
74
+ *
75
+ * @type {PgpKeyEntry[]}
76
+ */
77
+ export const PGP_KEYS = BASE_PGP_KEYS.map((entry) => ({
78
+ ...entry,
79
+ ...getQR(entry.id),
80
+ }));
81
+
82
+ // cspell:ignore EBDC
package/src/lib/images.js CHANGED
@@ -13,7 +13,7 @@ This file is part of Network Pro.
13
13
  * @description Provides convenient access to images in the src/lib/img directory
14
14
  * @module src/lib
15
15
  * @author Scott Lopez
16
- * @updated 2025-06-16
16
+ * @updated 2025-10-20
17
17
  */
18
18
 
19
19
  // Import favicon images
@@ -33,6 +33,7 @@ import bySvg from '$lib/img/by.svg';
33
33
  import ccSvg from '$lib/img/cc.svg';
34
34
  import obtainiumPng from '$lib/img/obtainium.png';
35
35
  import obtainiumWbp from '$lib/img/obtainium.webp';
36
+ import protonPower from '$lib/img/powered-by-proton.svg';
36
37
 
37
38
  // Import images for posts
38
39
  import acodePng from '$lib/img/posts/acode.png';
@@ -56,15 +57,47 @@ import tosWbp from '$lib/img/posts/tosdr.webp';
56
57
  import urlPng from '$lib/img/posts/urlcheck.png';
57
58
  import urlWbp from '$lib/img/posts/urlcheck.webp';
58
59
 
59
- // Import QR code images
60
- import pgpContactPng from '$lib/img/qr/pgp-contact.png';
61
- import pgpContactWbp from '$lib/img/qr/pgp-contact.webp';
62
- import pgpSecurityPng from '$lib/img/qr/pgp-security.png';
63
- import pgpSecurityWbp from '$lib/img/qr/pgp-security.webp';
64
- import pgpSupportPng from '$lib/img/qr/pgp-support.png';
65
- import pgpSupportWbp from '$lib/img/qr/pgp-support.webp';
66
- import vcfPng from '$lib/img/qr/vcard.png';
67
- import vcfWbp from '$lib/img/qr/vcard.webp';
60
+ // ================================================================
61
+ // Dynamic QR code image imports
62
+ // ================================================================
63
+
64
+ // Dynamically import all QR code images in src/lib/img/qr
65
+ const qrModules = import.meta.glob('$lib/img/qr/*.{png,webp}', { eager: true });
66
+
67
+ /**
68
+ * Aggregated QR code image lookup.
69
+ * Example: QR_IMAGES['pgp-support'].png → blob URL
70
+ * @typedef {'png' | 'webp'} QRExtension
71
+ * @type {Record<string, { png?: string; webp?: string }>}
72
+ */
73
+ export const QR_IMAGES = {};
74
+
75
+ // Populate QR_IMAGES
76
+ for (const [path, mod] of Object.entries(qrModules)) {
77
+ // Ensure we’re dealing with an ES module with a default export
78
+ const module = /** @type {{ default: string }} */ (mod);
79
+
80
+ const file = path.split('/').pop();
81
+ if (!file) continue; // file is possibly undefined
82
+
83
+ const [name, ext] = file.split('.');
84
+ if (!QR_IMAGES[name]) QR_IMAGES[name] = {};
85
+
86
+ if (ext === 'png' || ext === 'webp') {
87
+ QR_IMAGES[name][ext] = module.default;
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Retrieve QR code image pair (png/webp) by name.
93
+ * Safely returns an empty object if not found.
94
+ *
95
+ * @param {string} name - Base filename (e.g., "pgp-support" or "vcard")
96
+ * @returns {{ png?: string; webp?: string }}
97
+ */
98
+ export function getQR(name) {
99
+ return QR_IMAGES[name] ?? {};
100
+ }
68
101
 
69
102
  // Re-export all imports
70
103
  export {
@@ -87,19 +120,15 @@ export {
87
120
  lsheetPng,
88
121
  lsheetWbp, obtainiumPng,
89
122
  obtainiumWbp, otphelpPng,
90
- otphelpWbp, pgpContactPng,
91
- pgpContactWbp, pgpSecurityPng,
92
- pgpSecurityWbp, pgpSupportPng,
93
- pgpSupportWbp, pmxPng,
123
+ otphelpWbp, pmxPng,
94
124
  pmxWbp,
125
+ protonPower,
95
126
  squirclePng,
96
127
  squircleWbp,
97
128
  tosPng,
98
129
  tosWbp,
99
130
  urlPng,
100
- urlWbp,
101
- vcfPng,
102
- vcfWbp
131
+ urlWbp
103
132
  };
104
133
 
105
134
  // cspell:ignore eauth hboard cryptom tosdr otphelp
package/src/lib/index.js CHANGED
@@ -16,7 +16,7 @@ This file is part of Network Pro.
16
16
  * and re-exported here for flat `$lib` imports.
17
17
  * @module src/lib
18
18
  * @author Scott Lopez
19
- * @updated 2025-10-10
19
+ * @updated 2025-10-20
20
20
  */
21
21
 
22
22
  // Re-export all images so they can be imported directly from `$lib`
@@ -30,6 +30,9 @@ export * from './components/index.js';
30
30
  // Re-export all pages so they can be imported directly from `$lib`
31
31
  export * from './pages/index.js';
32
32
 
33
+ // Re-export `pgpKeys` data so it can be imported directly from `$lib`
34
+ export { PGP_KEYS } from '$lib/data/pgpKeys.js';
35
+
33
36
  // Export utility functions
34
37
  // Uncomment and adjust these as needed for your project
35
38
  // export * from './utils/formatting.js';
@@ -53,9 +56,12 @@ export const CONSTANTS = {
53
56
  YEAR: '2025',
54
57
  },
55
58
  CONTACT: {
56
- EMAIL: 'support (at) neteng.pro',
59
+ EMAIL: 'support (at) netwk.pro',
60
+ EMAIL_LINK: 'support@netwk.pro',
57
61
  SECURE: 'contact (at) s.neteng.pro',
62
+ SECURE_LINK: 'contact@s.neteng.pro',
58
63
  PRIVACY: 'privacy (at) netwk.pro',
64
+ PRIVACY_LINK: 'privacy@netwk.pro',
59
65
  PHONE: '(623) 252-4350',
60
66
  },
61
67
  PAGE: {
@@ -7,16 +7,8 @@ This file is part of Network Pro.
7
7
  ========================================================================== -->
8
8
 
9
9
  <script>
10
- import {
11
- pgpContactPng,
12
- pgpContactWbp,
13
- pgpSupportPng,
14
- pgpSupportWbp,
15
- vcfPng,
16
- vcfWbp,
17
- } from '$lib';
10
+ import { CONSTANTS, getQR, PGP_KEYS } from '$lib';
18
11
  import { base } from '$app/paths';
19
- import { CONSTANTS } from '$lib';
20
12
 
21
13
  // Log the base path to verify its value
22
14
  //console.log("Base path:", base);
@@ -24,6 +16,9 @@ This file is part of Network Pro.
24
16
  //console.log(CONSTANTS.COMPANY_INFO.APP_NAME);
25
17
 
26
18
  const { COMPANY_INFO, CONTACT, PAGE } = CONSTANTS;
19
+ const pgpKeys = PGP_KEYS.filter(
20
+ (k) => k.id === 'pgp-support' || k.id === 'pgp-contact',
21
+ );
27
22
 
28
23
  /**
29
24
  * URL to the Contact Form route, using the base path
@@ -37,6 +32,12 @@ This file is part of Network Pro.
37
32
  */
38
33
  const consultLink = `${base}/consultation`;
39
34
 
35
+ /**
36
+ * URL to the Services route, using the base path
37
+ * @type {string}
38
+ */
39
+ const servLink = `${base}/services`;
40
+
40
41
  /**
41
42
  * URL to the PGP route, using the base path
42
43
  * @type {string}
@@ -74,60 +75,35 @@ This file is part of Network Pro.
74
75
  {
75
76
  label: 'SPDX License Identifier',
76
77
  href: 'https://spdx.dev/learn/handling-license-info',
77
- target: '_blank',
78
+ target: PAGE.BLANK,
78
79
  text: 'CC-BY-4.0 OR GPL-3.0-or-later',
79
80
  },
80
81
  {
81
82
  label: 'Docs',
82
83
  href: 'https://docs.netwk.pro',
83
- target: '_self',
84
- },
85
- ];
86
-
87
- /**
88
- * PGP key information for contact emails
89
- * @type {Array<{
90
- * label: string,
91
- * qrSrc: string,
92
- * qrWbp: string,
93
- * keySearch: string,
94
- * fingerprint: string[]
95
- * }>}
96
- */
97
- const pgpKeys = [
98
- {
99
- label: 'support@neteng.pro',
100
- qrSrc: pgpSupportPng,
101
- qrWbp: pgpSupportWbp,
102
- keySearch: 'https://keys.openpgp.org/search?q=support%40neteng.pro',
103
- fingerprint: ['6590B992E2E3EFF12738', '7BCE2AF093E9DEC61BA0'],
104
- },
105
- {
106
- label: 'contact@s.neteng.pro',
107
- qrSrc: pgpContactPng,
108
- qrWbp: pgpContactWbp,
109
- keySearch: 'https://keys.openpgp.org/search?q=contact%40s.neteng.pro',
110
- fingerprint: ['DF118BAA6C2D9DCDEBDC', '2DDCF99373499495F957'],
84
+ target: PAGE.SELF,
111
85
  },
112
86
  ];
113
87
 
114
88
  /**
115
89
  * @typedef {Object} ContactAssets
116
- * @property {string} vcf
117
- * @property {string} qrSrc
118
- * @property {string} qrWbp
119
- * @property {string} supportAsc
120
- * @property {string} contactAsc
90
+ * @property {string} vcf - Path to the downloadable vCard file.
91
+ * @property {string} [png] - PNG version of the vCard QR code.
92
+ * @property {string} [webp] - WebP version of the vCard QR code.
93
+ * @property {string} supportAsc - Path to the general support PGP key.
94
+ * @property {string} contactAsc - Path to the secure contact PGP key.
121
95
  */
122
96
 
123
97
  /** @type {ContactAssets} */
124
98
  const contactAssets = {
125
99
  vcf: '/bin/contact.vcf',
126
- qrSrc: vcfPng,
127
- qrWbp: vcfWbp,
128
- supportAsc: '/pgp/support@neteng.pro.asc',
100
+ ...getQR('vcard'),
101
+ supportAsc: '/pgp/support@netwk.pro.asc',
129
102
  contactAsc: '/pgp/contact@s.neteng.pro.asc',
130
103
  };
104
+
105
+ $: supportFp = pgpKeys[0]?.fingerprint?.split(' ') ?? [];
106
+ $: contactFp = pgpKeys[1]?.fingerprint?.split(' ') ?? [];
131
107
  </script>
132
108
 
133
109
  <!-- BEGIN TITLE -->
@@ -148,7 +124,7 @@ This file is part of Network Pro.
148
124
  </p>
149
125
  </section>
150
126
 
151
- &nbsp;
127
+ <div class="spacer"></div>
152
128
 
153
129
  <section id="subhead">
154
130
  <h2>Security That Respects You</h2>
@@ -211,10 +187,11 @@ This file is part of Network Pro.
211
187
  <div class="spacer"></div>
212
188
 
213
189
  <p>
214
- Additionally, {COMPANY_INFO.APP_NAME}&trade; provides on-site services in the
215
- Greater Phoenix Metro Area (Maricopa County, AZ). Our on-site services are
216
- available to both businesses and consumers. In addition to consulting, we
217
- offer the following services:
190
+ Additionally, {COMPANY_INFO.APP_NAME}&trade; provides
191
+ <a href={servLink} target={PAGE.SELF}>on-site services</a>
192
+ in the Greater Phoenix Metro Area (Maricopa County, AZ). Our
193
+ <a href={servLink} target={PAGE.SELF}>on-site services</a> are available to both
194
+ consumers and businesses. In addition to consulting, we offer the following services:
218
195
  </p>
219
196
 
220
197
  <ul>
@@ -253,8 +230,14 @@ This file is part of Network Pro.
253
230
  <p>
254
231
  <strong>{COMPANY_INFO.NAME}</strong><br />
255
232
  📞 Phone: {CONTACT.PHONE}<br />
256
- 📧 General Inquiries: {CONTACT.EMAIL}<br />
257
- 🔐 Secure Email: {CONTACT.SECURE}
233
+ 📧 General Inquiries:
234
+ <a href={`mailto:${CONTACT.EMAIL_LINK}`} target={PAGE.BLANK}>
235
+ {CONTACT.EMAIL_LINK}
236
+ </a><br />
237
+ 🔐 Secure Email:
238
+ <a href={`mailto:${CONTACT.SECURE_LINK}`} target={PAGE.BLANK}>
239
+ {CONTACT.SECURE_LINK}
240
+ </a>
258
241
  </p>
259
242
 
260
243
  <div class="spacer"></div>
@@ -275,74 +258,84 @@ This file is part of Network Pro.
275
258
  <div class="pgp-wrap">
276
259
  <table class="pgp">
277
260
  <tbody>
278
- <!-- Row 0 (First row) remains unchanged -->
261
+ <!-- Row 0 (Support) -->
279
262
  <tr>
280
263
  <td class="pgp-col1">
281
264
  <picture>
282
- <source srcset={pgpKeys[0].qrWbp} type="image/webp" />
265
+ <source srcset={pgpKeys[0].webp} type="image/webp" />
283
266
  <img
284
267
  {decoding}
285
268
  {loading}
286
- src={pgpKeys[0].qrSrc}
269
+ src={pgpKeys[0].png}
287
270
  class="pgp-image"
288
- alt={`PGP Key - ${pgpKeys[0].label}`} />
271
+ alt={`QR code for ${pgpKeys[0].email}`} />
289
272
  </picture>
290
273
  </td>
291
274
  <td class="pgp-col2">
292
- <a rel={PAGE.REL} href={pgpKeys[0].keySearch} target={PAGE.BLANK}>
293
- <strong>{pgpKeys[0].label}</strong>
294
- </a>
295
- <p
296
- ><strong
297
- ><a
298
- href={contactAssets.supportAsc}
299
- type="application/pgp-keys"
300
- download
301
- target={PAGE.BLANK}
302
- >asc &nbsp;<span class="fas fa-file-arrow-down"></span></a
303
- ></strong>
275
+ <p>
276
+ <strong
277
+ ><a rel={PAGE.REL} href={pgpKeys[0].opgp} target={PAGE.BLANK}>
278
+ {pgpKeys[0].email}
279
+ </a></strong>
304
280
  </p>
305
- <p
306
- >Fingerprint:<br />
307
- <span class="fingerprint">
308
- {pgpKeys[0].fingerprint.join('\n')}
309
- </span>
281
+ <p>
282
+ <a
283
+ href={pgpKeys[0].file}
284
+ type="application/pgp-keys"
285
+ download
286
+ target={PAGE.BLANK}>
287
+ asc &nbsp;<span class="fas fa-file-arrow-down"></span>
288
+ </a>
289
+ </p>
290
+ <p>
291
+ <strong>Fingerprint:</strong><br />
292
+ {#if supportFp.length}
293
+ <span class="fingerprint">
294
+ {supportFp.slice(0, supportFp.length / 2).join(' ')}<br />
295
+ {supportFp.slice(supportFp.length / 2).join(' ')}
296
+ </span>
297
+ {/if}
310
298
  </p>
311
299
  </td>
312
300
  </tr>
313
301
 
314
- <!-- Row 1 (Second row) has its columns swapped -->
302
+ <!-- Row 1 (Secure Contact) -->
315
303
  <tr>
316
304
  <td class="pgp-col1">
317
- <a rel={PAGE.REL} href={pgpKeys[1].keySearch} target={PAGE.BLANK}>
318
- <strong>{pgpKeys[1].label}</strong>
319
- </a>
320
305
  <p>
321
306
  <strong
322
- ><a
323
- href={contactAssets.contactAsc}
324
- type="application/pgp-keys"
325
- download
326
- target={PAGE.BLANK}
327
- >asc &nbsp;<span class="fas fa-file-arrow-down"></span></a
328
- ></strong>
307
+ ><a rel={PAGE.REL} href={pgpKeys[1].opgp} target={PAGE.BLANK}>
308
+ {pgpKeys[1].email}
309
+ </a></strong>
310
+ </p>
311
+ <p>
312
+ <a
313
+ href={pgpKeys[1].file}
314
+ type="application/pgp-keys"
315
+ download
316
+ target={PAGE.BLANK}>
317
+ asc &nbsp;<span class="fas fa-file-arrow-down"></span>
318
+ </a>
329
319
  </p>
330
- <p
331
- >Fingerprint:<br />
332
- <span class="fingerprint">
333
- {pgpKeys[1].fingerprint.join('\n')}
334
- </span>
320
+ <p>
321
+ <strong>Fingerprint:</strong><br />
322
+ {#if contactFp.length}
323
+ <span class="fingerprint">
324
+ {contactFp.slice(0, contactFp.length / 2).join(' ')}<br />
325
+ {contactFp.slice(contactFp.length / 2).join(' ')}
326
+ </span>
327
+ {/if}
335
328
  </p>
336
329
  </td>
337
330
  <td class="pgp-col2">
338
331
  <picture>
339
- <source srcset={pgpKeys[1].qrWbp} type="image/webp" />
332
+ <source srcset={pgpKeys[1].webp} type="image/webp" />
340
333
  <img
341
334
  {decoding}
342
335
  {loading}
343
- src={pgpKeys[1].qrSrc}
336
+ src={pgpKeys[1].png}
344
337
  class="pgp-image"
345
- alt={`PGP Key - ${pgpKeys[1].label}`} />
338
+ alt={`QR code for ${pgpKeys[1].email}`} />
346
339
  </picture>
347
340
  </td>
348
341
  </tr>
@@ -351,13 +344,17 @@ This file is part of Network Pro.
351
344
  <tr>
352
345
  <td class="pgp-col1">
353
346
  <picture>
354
- <source srcset={contactAssets.qrWbp} type="image/webp" />
355
- <img
356
- {decoding}
357
- {loading}
358
- src={contactAssets.qrSrc}
359
- class="pgp-image"
360
- alt="vCard" />
347
+ {#if contactAssets.webp}
348
+ <source srcset={contactAssets.webp} type="image/webp" />
349
+ {/if}
350
+ {#if contactAssets.png}
351
+ <img
352
+ {decoding}
353
+ {loading}
354
+ src={contactAssets.png}
355
+ class="pgp-image"
356
+ alt="vCard" />
357
+ {/if}
361
358
  </picture>
362
359
  </td>
363
360
  <td class="pgp-col2">
@@ -46,17 +46,17 @@ This file is part of Network Pro.
46
46
  <h3 class={classIndex}>🔒 Practical Cybersecurity. Trusted Expertise.</h3>
47
47
 
48
48
  <p class={classCenter}>
49
- At <strong>{COMPANY_INFO.NAME}</strong>, we specialize in network security,
50
- cybersecurity, and digital privacy consulting that meets today's real-world
51
- demands. Our remote-first approach combines technical depth with practical
52
- solutions—leveraging a strategic mix of open source and proprietary
49
+ At <strong>{COMPANY_INFO.NAME}</strong>, we specialize in network engineering
50
+ and security, cybersecurity, and digital privacy consulting that meets today's
51
+ real-world demands. Our remote-first approach combines technical depth with
52
+ practical solutions—leveraging a strategic mix of open source and proprietary
53
53
  technologies based on performance, scalability, and trustworthiness.
54
54
  </p>
55
55
 
56
56
  <p class={classCenter}>
57
57
  From secure network design to cloud infrastructure and perimeter defense, we
58
- help organizations build stronger, smarter security postures—without
59
- compromising flexibility or transparency.
58
+ help individuals and organizations build stronger, smarter security
59
+ postures—without compromising flexibility or transparency.
60
60
  </p>
61
61
 
62
62
  <p class={classCenter}>
@@ -76,9 +76,12 @@ This file is part of Network Pro.
76
76
  📞 <strong>Phone:</strong>
77
77
  {CONTACT.PHONE}<br />
78
78
  📧 <strong>General Inquiries:</strong>
79
- {CONTACT.EMAIL}<br />
79
+ <a href={`mailto:${CONTACT.EMAIL_LINK}`} target={PAGE.BLANK}
80
+ >{CONTACT.EMAIL_LINK}</a
81
+ ><br />
80
82
  🔐 <strong>Secure Email:</strong>
81
- {CONTACT.SECURE}
83
+ <a href={`mailto:${CONTACT.SECURE_LINK}`} target={PAGE.BLANK}
84
+ >{CONTACT.SECURE_LINK}</a>
82
85
  </p>
83
86
 
84
87
  &nbsp;
@@ -7,43 +7,16 @@ This file is part of Network Pro.
7
7
  ========================================================================== -->
8
8
 
9
9
  <script>
10
- import CodeBlock from '$lib/components/CodeBlock.svelte';
10
+ import { CONSTANTS, protonPower, getQR, PGP_KEYS as keys } from '$lib';
11
+ import { CodeBlock } from '$lib/components';
11
12
  import { base } from '$app/paths';
12
- import { CONSTANTS } from '$lib';
13
13
 
14
14
  // Log the base path to verify its value
15
15
  //console.log("Base path:", base);
16
16
 
17
17
  //console.log(CONSTANTS.COMPANY_INFO.APP_NAME);
18
18
 
19
- const { PAGE } = CONSTANTS;
20
-
21
- const keys = [
22
- {
23
- name: 'General Contact & Support',
24
- email: 'support (at) neteng.pro',
25
- fingerprint: '6590 B992 E2E3 EFF1 2738 7BCE 2AF0 93E9 DEC6 1BA0',
26
- opgp: 'https://keys.openpgp.org/search?q=support%40neteng.pro',
27
- file: '/pgp/support@neteng.pro.asc',
28
- img: 'pgp-support',
29
- },
30
- {
31
- name: 'Secure Email',
32
- email: 'contact (at) s.neteng.pro',
33
- fingerprint: 'DF11 8BAA 6C2D 9DCD EBDC 2DDC F993 7349 9495 F957',
34
- opgp: 'https://keys.openpgp.org/search?q=contact%40s.neteng.pro',
35
- file: '/pgp/contact@s.neteng.pro.asc',
36
- img: 'pgp-contact',
37
- },
38
- {
39
- name: 'Security Contact',
40
- email: 'security (at) s.neteng.pro',
41
- fingerprint: 'B7FE 1D4E 6CAB 3E71 4A9F DF6E 48CB 7290 C00D 0DA5',
42
- opgp: 'https://keys.openpgp.org/search?q=security%40s.neteng.pro',
43
- file: '/pgp/security@s.neteng.pro.asc',
44
- img: 'pgp-security',
45
- },
46
- ];
19
+ const { CONTACT, PAGE } = CONSTANTS;
47
20
 
48
21
  /**
49
22
  * Tracks which PGP key's fingerprint was last copied.
@@ -81,7 +54,7 @@ This file is part of Network Pro.
81
54
  </p>
82
55
  <p>
83
56
  <img
84
- src="/img/powered-by-proton.svg"
57
+ src={protonPower}
85
58
  alt="Powered by Proton"
86
59
  class="proton-img"
87
60
  loading="eager"
@@ -93,9 +66,9 @@ This file is part of Network Pro.
93
66
  </p>
94
67
 
95
68
  {#each keys as key, i}
96
- <section class="pgp-entry" aria-labelledby={`pgp-${key.img}`}>
69
+ <section class="pgp-entry" aria-labelledby={`pgp-${key.id}`}>
97
70
  <div class="pgp-text">
98
- <h2 id={`pgp-${key.img}`}>{key.name}</h2>
71
+ <h2 id={`pgp-${key.id}`}>{key.name}</h2>
99
72
  <h3>
100
73
  &lt;
101
74
  {#if key.opgp}
@@ -129,13 +102,19 @@ This file is part of Network Pro.
129
102
  </div>
130
103
  <div class="pgp-qr">
131
104
  <picture>
132
- <source srcset={`/pgp/${key.img}.webp`} type="image/webp" />
133
- <img
134
- src={`/pgp/${key.img}.png`}
135
- alt={`QR code for ${key.email}`}
136
- class="pgp-image"
137
- loading={i === 0 ? 'eager' : 'lazy'}
138
- decoding={i === 0 ? 'sync' : 'async'} />
105
+ {#if key.webp}
106
+ <source srcset={key.webp} type="image/webp" />
107
+ {/if}
108
+ {#if key.png}
109
+ <img
110
+ src={key.png}
111
+ alt={`QR code for ${key.email}`}
112
+ class="pgp-image"
113
+ loading={i === 0 ? 'eager' : 'lazy'}
114
+ decoding={i === 0 ? 'sync' : 'async'} />
115
+ {:else}
116
+ <p>QR image missing for {key.id}</p>
117
+ {/if}
139
118
  </picture>
140
119
  </div>
141
120
  </section>
@@ -44,7 +44,7 @@ This file is part of Network Pro.
44
44
  * @type {{ effectiveDate: string, classSmall: string }}
45
45
  */
46
46
  const constants = {
47
- effectiveDate: 'October 18, 2025',
47
+ effectiveDate: 'October 20, 2025',
48
48
  classSmall: 'small-text',
49
49
  };
50
50
  </script>
@@ -92,7 +92,10 @@ This file is part of Network Pro.
92
92
  <p>
93
93
  <strong>{COMPANY_INFO.NAME}</strong><br />
94
94
  📞 Phone: {CONTACT.PHONE}<br />
95
- 📧 General Inquiries: {CONTACT.EMAIL}<br />
95
+ 📧 General Inquiries:
96
+ <a href={`mailto:${CONTACT.EMAIL_LINK}`} target={PAGE.BLANK}
97
+ >{CONTACT.EMAIL_LINK}</a
98
+ ><br />
96
99
  </p>
97
100
 
98
101
  <div class="spacer"></div>
@@ -552,7 +552,7 @@ footer .container {
552
552
 
553
553
  .fingerprint {
554
554
  display: block;
555
- font-weight: bold;
555
+ font-family: monospace;
556
556
  white-space: pre-line; /* Ensures newlines are respected for "\n" */
557
557
  }
558
558
 
@@ -3,4 +3,4 @@ Copyright © 2025 Network Pro Strategies (Network Pro™)
3
3
  SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
4
4
  This file is part of Network Pro.
5
5
  ========================================================================== */
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}}#service-summary{color:#e6e6e6;margin-top:2rem;margin-bottom:2.5rem}.service-table{color:#e6e6e6;border-collapse:collapse;background-color:#191919;width:100%;font-size:.95rem}.service-table th,.service-table td{text-align:left;vertical-align:top;border-bottom:1px solid #333;padding:.75rem 1rem}.service-table th{color:#ffc627;text-transform:uppercase;background-color:#222;font-size:.85rem;font-weight:600}.service-table a{color:#ffc627;font-weight:500;text-decoration:none}.service-table a:hover{text-decoration:underline}.service-table tr:hover{background-color:#222;transition:background-color .3s,box-shadow .3s;box-shadow:0 0 10px 2px #ffc62740}.service-table tr.selected{background-color:#222;border-left:4px solid #ffc627;transition:background-color .3s,border-left-color .3s}.service-table tr.selected:hover{background-color:#252525;box-shadow:0 0 12px 3px #ffc62759}@media (width<=768px){.service-table{font-size:.9rem}.service-table th,.service-table td{padding:.5rem}}.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}#toc ul{padding-left:1.5rem;list-style-type:disc}#toc a{color:var(--color-primary,#ffc627);text-decoration:none}#toc a:hover{text-decoration:underline}
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}}#service-summary{color:#e6e6e6;margin-top:2rem;margin-bottom:2.5rem}.service-table{color:#e6e6e6;border-collapse:collapse;background-color:#191919;width:100%;font-size:.95rem}.service-table th,.service-table td{text-align:left;vertical-align:top;border-bottom:1px solid #333;padding:.75rem 1rem}.service-table th{color:#ffc627;text-transform:uppercase;background-color:#222;font-size:.85rem;font-weight:600}.service-table a{color:#ffc627;font-weight:500;text-decoration:none}.service-table a:hover{text-decoration:underline}.service-table tr:hover{background-color:#222;transition:background-color .3s,box-shadow .3s;box-shadow:0 0 10px 2px #ffc62740}.service-table tr.selected{background-color:#222;border-left:4px solid #ffc627;transition:background-color .3s,border-left-color .3s}.service-table tr.selected:hover{background-color:#252525;box-shadow:0 0 12px 3px #ffc62759}@media (width<=768px){.service-table{font-size:.9rem}.service-table th,.service-table td{padding:.5rem}}.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-family:monospace;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}#toc ul{padding-left:1.5rem;list-style-type:disc}#toc a{color:var(--color-primary,#ffc627);text-decoration:none}#toc a:hover{text-decoration:underline}
@@ -23,9 +23,12 @@ This file is part of Network Pro.
23
23
 
24
24
  /**
25
25
  * @typedef {object} ContactInfo
26
- * @property {string} EMAIL - Primary contact email
27
- * @property {string} SECURE - Secure contact email
28
- * @property {string} PRIVACY - Privacy policy email
26
+ * @property {string} EMAIL - Primary contact email (human-readable form)
27
+ * @property {string} EMAIL_LINK - Primary contact email (clickable address)
28
+ * @property {string} SECURE - Secure contact email (human-readable form)
29
+ * @property {string} SECURE_LINK - Secure contact email (clickable address)
30
+ * @property {string} PRIVACY - Privacy contact email (human-readable form)
31
+ * @property {string} PRIVACY_LINK - Privacy contact email (clickable address)
29
32
  * @property {string} PHONE - Support phone number
30
33
  */
31
34
 
@@ -30,11 +30,11 @@ const excludedAssets = [];
30
30
  const IGNORE_PATHS = new Set([
31
31
  '/.well-known/security.txt.sig',
32
32
  '/img/banner-1280x640.png',
33
+ '/img/banner-og-1200x630.png',
34
+ '/img/fb-banner.png',
33
35
  '/img/logo-transparent.png',
34
36
  '/img/logo.png',
35
37
  '/img/svelte.png',
36
- '/pgp/pgp-github.png',
37
- '/pgp/pgp-github.webp',
38
38
  '/pgp/contact@s.neteng.pro.asc',
39
39
  '/pgp/github@sl.neteng.cc.asc',
40
40
  '/pgp/security@s.neteng.pro.asc',
@@ -84,18 +84,10 @@ const REQUIRED_ASSETS = [
84
84
  '/icon-192x192.png',
85
85
  '/icon-512x512-maskable.png',
86
86
  '/icon-512x512.png',
87
+ '/icon-about.png',
87
88
  '/icon-contact.png',
88
89
  '/icon-services.png',
89
90
  '/icon-splash.png',
90
- '/img/banner-og-1200x630.png',
91
- '/pgp/pgp-contact.png',
92
- '/pgp/pgp-contact.webp',
93
- '/pgp/pgp-security.png',
94
- '/pgp/pgp-security.webp',
95
- '/pgp/pgp-support.png',
96
- '/pgp/pgp-support.webp',
97
- '/pgp/vcard.png',
98
- '/pgp/vcard.webp',
99
91
  '/manifest.json',
100
92
  '/offline.html',
101
93
  '/offline.min.css',
Binary file
@@ -3,7 +3,7 @@
3
3
  "start_url": "/?utm_source=homescreen",
4
4
  "scope": "/",
5
5
  "name": "Network Pro Strategies",
6
- "short_name": "Network Pro",
6
+ "short_name": "Network Pro",
7
7
  "description": "Access our expert cybersecurity services anytime, anywhere with our streamlined Progressive Web App. Optimized for speed, security, and mobile use, this app offers a seamless experience to explore our solutions, view project highlights, and get in touch—all in one place.",
8
8
  "lang": "en-US",
9
9
  "dir": "ltr",
@@ -69,10 +69,10 @@
69
69
  ],
70
70
  "shortcuts": [
71
71
  {
72
- "name": "Consulting Services",
72
+ "name": "On-Site Services",
73
73
  "short_name": "Services",
74
- "description": "Explore our cybersecurity services",
75
- "url": "/about?utm_source=shortcut",
74
+ "description": "Explore the services we offer",
75
+ "url": "/services?utm_source=shortcut",
76
76
  "icons": [
77
77
  {
78
78
  "src": "/icon-services.png",
@@ -81,6 +81,19 @@
81
81
  }
82
82
  ]
83
83
  },
84
+ {
85
+ "name": "About Us",
86
+ "short_name": "About",
87
+ "description": "Learn more about Network Pro™",
88
+ "url": "/about?utm_source=shortcut",
89
+ "icons": [
90
+ {
91
+ "src": "/icon-about.png",
92
+ "sizes": "96x96",
93
+ "type": "image/png"
94
+ }
95
+ ]
96
+ },
84
97
  {
85
98
  "name": "Contact Us",
86
99
  "short_name": "Contact",
@@ -0,0 +1,77 @@
1
+ -----BEGIN PGP PUBLIC KEY BLOCK-----
2
+ Comment: User ID: Network Pro Strategies <support@neteng.pro>
3
+ Comment: a.k.a.: Network Pro Strategies <contact@neteng.pro>
4
+ Comment: a.k.a.: Network Pro Strategies <github@neteng.pro>
5
+ Comment: a.k.a.: Network Pro Strategies <no-reply@neteng.pro>
6
+ Comment: a.k.a.: Network Pro Strategies <social@neteng.pro>
7
+ Comment: a.k.a.: Network Pro Strategies <website@neteng.pro>
8
+ Comment: a.k.a.: Network Pro Strategies <privacy@netwk.pro>
9
+ Comment: a.k.a.: Network Pro Strategies <support@netwk.pro>
10
+ Comment: Valid from: 3/28/2025 5:16 PM
11
+ Comment: Valid until: 3/27/2028 5:16 PM
12
+ Comment: Type: 255-bit EdDSA (secret key available)
13
+ Comment: Usage: Signing, Encryption, Certifying User IDs
14
+ Comment: Fingerprint: 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
75
+ pOdVpYLVDQ==
76
+ =v4Zv
77
+ -----END PGP PUBLIC KEY BLOCK-----
@@ -1,5 +1,5 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
- <!-- Sitemap last updated 2025-10-17 -->
2
+ <!-- Sitemap last updated 2025-10-20 -->
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-17</lastmod>
10
+ <lastmod>2025-10-20</lastmod>
11
11
 
12
12
  <changefreq>weekly</changefreq>
13
13
 
@@ -19,7 +19,7 @@
19
19
 
20
20
  <loc>https://netwk.pro/services</loc>
21
21
 
22
- <lastmod>2025-10-17</lastmod>
22
+ <lastmod>2025-10-20</lastmod>
23
23
 
24
24
  <changefreq>monthly</changefreq>
25
25
 
@@ -43,7 +43,7 @@
43
43
 
44
44
  <loc>https://netwk.pro/about</loc>
45
45
 
46
- <lastmod>2025-10-17</lastmod>
46
+ <lastmod>2025-10-20</lastmod>
47
47
 
48
48
  <changefreq>monthly</changefreq>
49
49
 
@@ -115,7 +115,7 @@
115
115
 
116
116
  <loc>https://netwk.pro/pgp</loc>
117
117
 
118
- <lastmod>2025-06-11</lastmod>
118
+ <lastmod>2025-10-20</lastmod>
119
119
 
120
120
  <changefreq>monthly</changefreq>
121
121
 
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -1,47 +0,0 @@
1
- -----BEGIN PGP PUBLIC KEY BLOCK-----
2
- Comment: User ID: Network Pro Strategies <support@neteng.pro>
3
- Comment: a.k.a.: Network Pro Strategies <contact@neteng.pro>
4
- Comment: a.k.a.: Network Pro Strategies <github@neteng.pro>
5
- Comment: a.k.a.: Network Pro Strategies <no-reply@neteng.pro>
6
- Comment: a.k.a.: Network Pro Strategies <social@neteng.pro>
7
- Comment: a.k.a.: Network Pro Strategies <website@neteng.pro>
8
- Comment: Valid from: 3/28/25 5:16 PM
9
- Comment: Valid until: 3/27/28 5:16 PM
10
- Comment: Type: 255-bit EdDSA (secret key available)
11
- Comment: Usage: Signing, Encryption, Certifying User IDs
12
- Comment: Fingerprint: 6590B992E2E3EFF127387BCE2AF093E9DEC61BA0
13
-
14
-
15
- mDMEZ+c71xYJKwYBBAHaRw8BAQdAXrXB9LKKHj7tgAzrCkheQe+yJ0KD50yVrHM7
16
- yOopYuW0K05ldHdvcmsgUHJvIFN0cmF0ZWdpZXMgPHN1cHBvcnRAbmV0ZW5nLnBy
17
- bz6InAQTFgoARAIbAwUJBaOagAULCQgHAgIiAgYVCgkICwIEFgIDAQIeBwIXgBYh
18
- BGWQuZLi4+/xJzh7zirwk+nexhugBQJn5zzLAhkBAAoJECrwk+nexhugp9UBAJ4O
19
- J4aR6SBdYCInPri4DuRrLeLtMIT6yPN2XP0+aRH5AP4piPrWA5Qx22t7DZTF8S08
20
- 6rhDtFuslGkMab4ITA+8AbQrTmV0d29yayBQcm8gU3RyYXRlZ2llcyA8Y29udGFj
21
- dEBuZXRlbmcucHJvPoiZBBMWCgBBFiEEZZC5kuLj7/EnOHvOKvCT6d7GG6AFAmfn
22
- PJgCGwMFCQWjmoAFCwkIBwICIgIGFQoJCAsCBBYCAwECHgcCF4AACgkQKvCT6d7G
23
- G6CBCgD/aC/WM7bOfQoTZitpluifrEQIjP6RelCpksULK7jcEzkA/iTuessO95fe
24
- 72MtCRiOjFlcVXuXfgaap0PwNmwfMz0GtCpOZXR3b3JrIFBybyBTdHJhdGVnaWVz
25
- IDxnaXRodWJAbmV0ZW5nLnBybz6ImQQTFgoAQRYhBGWQuZLi4+/xJzh7zirwk+ne
26
- xhugBQJn5zyiAhsDBQkFo5qABQsJCAcCAiICBhUKCQgLAgQWAgMBAh4HAheAAAoJ
27
- ECrwk+nexhug0tsBAKjrZMO7wfGUOiNQQr5IPzSEwOLYy0hkxq4SqOuMuPpVAP9/
28
- b3sZ0BbmTaU/+gnuXyUbMRQHLDqHh7ESRxSgll3WDLQsTmV0d29yayBQcm8gU3Ry
29
- YXRlZ2llcyA8bm8tcmVwbHlAbmV0ZW5nLnBybz6ImQQTFgoAQRYhBGWQuZLi4+/x
30
- Jzh7zirwk+nexhugBQJn5zywAhsDBQkFo5qABQsJCAcCAiICBhUKCQgLAgQWAgMB
31
- Ah4HAheAAAoJECrwk+nexhugjAQA+gNrz3htQtHPTifyIps/p8CuA6LR/5F99jip
32
- 5obARSaLAQDuodGbF3NIZ5b6C98aoNQ7adj/Neg53z6rgVRHkNuiCrQqTmV0d29y
33
- ayBQcm8gU3RyYXRlZ2llcyA8c29jaWFsQG5ldGVuZy5wcm8+iJkEExYKAEEWIQRl
34
- kLmS4uPv8Sc4e84q8JPp3sYboAUCZ+c8vAIbAwUJBaOagAULCQgHAgIiAgYVCgkI
35
- CwIEFgIDAQIeBwIXgAAKCRAq8JPp3sYboE6hAQCLyAl45ty3muvvw7vpkJjhbkyp
36
- daLVTIltW6x+cotifQEAqbXMngGnwAZPxiZH/r/NbopqD57YTT+HXx62thwefw+0
37
- K05ldHdvcmsgUHJvIFN0cmF0ZWdpZXMgPHdlYnNpdGVAbmV0ZW5nLnBybz6ImQQT
38
- FgoAQRYhBGWQuZLi4+/xJzh7zirwk+nexhugBQJn5zzHAhsDBQkFo5qABQsJCAcC
39
- AiICBhUKCQgLAgQWAgMBAh4HAheAAAoJECrwk+nexhugRUcA/RHfApSl1S+APoXN
40
- jmTki5pUk8+AD1kveRymT9g49FIVAQCtX8+cbM+9jLrg9EyyJ6kvE9btGExOOufA
41
- JNY15IdwBbg4BGfnO9cSCisGAQQBl1UBBQEBB0BiSu/MobXZljtB25Inf4cJwdoH
42
- z+gqapJHs+5y9mNPCgMBCAeIfgQYFgoAJhYhBGWQuZLi4+/xJzh7zirwk+nexhug
43
- BQJn5zvXAhsMBQkFo5qAAAoJECrwk+nexhugsXoA+QHr0FAorF0ZEgDA4wL/oZpB
44
- oIARdo9kYzL+cTi/F3g6AQCtbupe/JymVJuwLUcq3AsxXe0DLyoodT7CpOdVpYLV
45
- DQ==
46
- =pBLp
47
- -----END PGP PUBLIC KEY BLOCK-----
Binary file
Binary file
File without changes