feat: some miscellaneous tweaks (#5)

### Explanation

_No response_

### Issue

_No response_

### Attestations

- [ ] I have read and agree to the [Code of Conduct](https://docs.nhcarrigan.com/community/coc/)
- [ ] I have read and agree to the [Community Guidelines](https://docs.nhcarrigan.com/community/guide/).
- [ ] My contribution complies with the [Contributor Covenant](https://docs.nhcarrigan.com/dev/covenant/).

### Dependencies

- [ ] I have pinned the dependencies to a specific patch version.

### Style

- [ ] I have run the linter and resolved any errors.
- [ ] My pull request uses an appropriate title, matching the conventional commit standards.
- [ ] My scope of feat/fix/chore/etc. correctly matches the nature of changes in my pull request.

### Tests

- [ ] My contribution adds new code, and I have added tests to cover it.
- [ ] My contribution modifies existing code, and I have updated the tests to reflect these changes.
- [ ] All new and existing tests pass locally with my changes.
- [ ] Code coverage remains at or above the configured threshold.

### Documentation

_No response_

### Versioning

_No response_

Reviewed-on: https://codeberg.org/nhcarrigan/website-headers/pulls/5
Co-authored-by: Naomi Carrigan <commits@nhcarrigan.com>
Co-committed-by: Naomi Carrigan <commits@nhcarrigan.com>
This commit is contained in:
Naomi Carrigan 2024-12-21 03:34:59 +00:00 committed by Naomi the Technomancer
parent a9be8a08e9
commit 18d06aa13f
7 changed files with 236 additions and 12 deletions

View File

@ -2,7 +2,7 @@
This project generates a JavaScript file to be uploaded to our CDN. This file automatically generates metadata, favicons, styles, and scripts for all of our production pages.
To work on the file locally, you can serve the `index.html` file using your preferred application. Make changes to the `src/index.ts` file and run `pnpm build`, and the HTML will source the resulting JavaScript automatically.
To work on the file locally, use `pnpm dev`. This command will compile the TypeScript into JavaScript and simultaneously run the resulting dev server in `src/develop.ts`. This allows you to iterate over changes quickly and watch them update in real time.
When building the file, it is important to use `pnpm build` so that the minification step is run. Running `tsc` directly will bypass this step - while this is perfectly acceptable for debugging locally, the file MUST be minified before uploading to our CDN.

View File

@ -10,4 +10,9 @@ export default [
}
}
},
{
rules: {
"no-console": "off"
}
}
];

View File

@ -8,7 +8,7 @@
name="description"
content="Just a script that loads our custom CSS and JS"
/>
<script src="./prod/index.js" defer></script>
<script src="/prod/index.js" defer></script>
</head>
<body>
<main>

View File

@ -5,9 +5,12 @@
"main": "index.js",
"type": "module",
"scripts": {
"dev": "concurrently \"pnpm build:watch\" \"pnpm start\"",
"prebuild": "pnpm lint",
"build": "tsc && tsx build.ts",
"build:watch": "tsc --watch",
"lint": "eslint src --max-warnings 0",
"start": "echo \"This is not an executable script. Please review the README for more instructions.\" && exit 1",
"start": "node --watch prod/develop.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
@ -17,6 +20,7 @@
"@nhcarrigan/eslint-config": "5.0.0",
"@nhcarrigan/typescript-config": "4.0.0",
"@types/node": "22.10.2",
"concurrently": "9.1.0",
"eslint": "9.17.0",
"globals": "15.14.0",
"terser": "5.37.0",

143
pnpm-lock.yaml generated
View File

@ -17,6 +17,9 @@ importers:
'@types/node':
specifier: 22.10.2
version: 22.10.2
concurrently:
specifier: 9.1.0
version: 9.1.0
eslint:
specifier: 9.17.0
version: 9.17.0
@ -742,6 +745,10 @@ packages:
ajv@6.12.6:
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
ansi-regex@5.0.1:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
engines: {node: '>=8'}
ansi-styles@4.3.0:
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
engines: {node: '>=8'}
@ -865,6 +872,10 @@ packages:
resolution: {integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==}
engines: {node: '>=4'}
cliui@8.0.1:
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
engines: {node: '>=12'}
color-convert@2.0.1:
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
engines: {node: '>=7.0.0'}
@ -882,6 +893,11 @@ packages:
concat-map@0.0.1:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
concurrently@9.1.0:
resolution: {integrity: sha512-VxkzwMAn4LP7WyMnJNbHN5mKV9L2IbyDjpzemKr99sXNR3GqRNMMHdm7prV1ws9wg7ETj6WUkNOigZVsptwbgg==}
engines: {node: '>=18'}
hasBin: true
core-js-compat@3.39.0:
resolution: {integrity: sha512-VgEUx3VwlExr5no0tXlBt+silBvhTryPwCXRI2Id1PN8WTKu7MreethvddqOubrYxkFdv/RnYrqlv1sFNAUelw==}
@ -948,6 +964,9 @@ packages:
electron-to-chromium@1.5.75:
resolution: {integrity: sha512-Lf3++DumRE/QmweGjU+ZcKqQ+3bKkU/qjaKYhIJKEOhgIO9Xs6IiAQFkfFoj+RhgDk4LUeNsLo6plExHqSyu6Q==}
emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
error-ex@1.3.2:
resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==}
@ -1194,6 +1213,10 @@ packages:
functions-have-names@1.2.3:
resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
get-caller-file@2.0.5:
resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
engines: {node: 6.* || 8.* || >= 10.*}
get-intrinsic@1.2.6:
resolution: {integrity: sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==}
engines: {node: '>= 0.4'}
@ -1341,6 +1364,10 @@ packages:
resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==}
engines: {node: '>= 0.4'}
is-fullwidth-code-point@3.0.0:
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
engines: {node: '>=8'}
is-generator-function@1.0.10:
resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==}
engines: {node: '>= 0.4'}
@ -1472,6 +1499,9 @@ packages:
lodash.merge@4.6.2:
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
lodash@4.17.21:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
loose-envify@1.4.0:
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
hasBin: true
@ -1693,6 +1723,10 @@ packages:
resolution: {integrity: sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==}
hasBin: true
require-directory@2.1.1:
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
engines: {node: '>=0.10.0'}
requireindex@1.2.0:
resolution: {integrity: sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==}
engines: {node: '>=0.10.5'}
@ -1725,6 +1759,9 @@ packages:
run-parallel@1.2.0:
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
rxjs@7.8.1:
resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==}
safe-array-concat@1.1.3:
resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==}
engines: {node: '>=0.4'}
@ -1762,6 +1799,10 @@ packages:
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
engines: {node: '>=8'}
shell-quote@1.8.2:
resolution: {integrity: sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==}
engines: {node: '>= 0.4'}
side-channel-list@1.0.0:
resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==}
engines: {node: '>= 0.4'}
@ -1820,6 +1861,10 @@ packages:
std-env@3.8.0:
resolution: {integrity: sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==}
string-width@4.2.3:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
engines: {node: '>=8'}
string.prototype.matchall@4.0.12:
resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==}
engines: {node: '>= 0.4'}
@ -1839,6 +1884,10 @@ packages:
resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==}
engines: {node: '>= 0.4'}
strip-ansi@6.0.1:
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
engines: {node: '>=8'}
strip-bom@3.0.0:
resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
engines: {node: '>=4'}
@ -1855,6 +1904,10 @@ packages:
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
engines: {node: '>=8'}
supports-color@8.1.1:
resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==}
engines: {node: '>=10'}
supports-preserve-symlinks-flag@1.0.0:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'}
@ -1890,6 +1943,10 @@ packages:
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
engines: {node: '>=8.0'}
tree-kill@1.2.2:
resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==}
hasBin: true
ts-api-utils@1.4.3:
resolution: {integrity: sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==}
engines: {node: '>=16'}
@ -2054,6 +2111,22 @@ packages:
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
engines: {node: '>=0.10.0'}
wrap-ansi@7.0.0:
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
engines: {node: '>=10'}
y18n@5.0.8:
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
engines: {node: '>=10'}
yargs-parser@21.1.1:
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
engines: {node: '>=12'}
yargs@17.7.2:
resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
engines: {node: '>=12'}
yocto-queue@0.1.0:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'}
@ -2650,6 +2723,8 @@ snapshots:
json-schema-traverse: 0.4.1
uri-js: 4.4.1
ansi-regex@5.0.1: {}
ansi-styles@4.3.0:
dependencies:
color-convert: 2.0.1
@ -2800,6 +2875,12 @@ snapshots:
dependencies:
escape-string-regexp: 1.0.5
cliui@8.0.1:
dependencies:
string-width: 4.2.3
strip-ansi: 6.0.1
wrap-ansi: 7.0.0
color-convert@2.0.1:
dependencies:
color-name: 1.1.4
@ -2812,6 +2893,16 @@ snapshots:
concat-map@0.0.1: {}
concurrently@9.1.0:
dependencies:
chalk: 4.1.2
lodash: 4.17.21
rxjs: 7.8.1
shell-quote: 1.8.2
supports-color: 8.1.1
tree-kill: 1.2.2
yargs: 17.7.2
core-js-compat@3.39.0:
dependencies:
browserslist: 4.24.3
@ -2880,6 +2971,8 @@ snapshots:
electron-to-chromium@1.5.75: {}
emoji-regex@8.0.0: {}
error-ex@1.3.2:
dependencies:
is-arrayish: 0.2.1
@ -3313,6 +3406,8 @@ snapshots:
functions-have-names@1.2.3: {}
get-caller-file@2.0.5: {}
get-intrinsic@1.2.6:
dependencies:
call-bind-apply-helpers: 1.0.1
@ -3461,6 +3556,8 @@ snapshots:
dependencies:
call-bound: 1.0.3
is-fullwidth-code-point@3.0.0: {}
is-generator-function@1.0.10:
dependencies:
has-tostringtag: 1.0.2
@ -3584,6 +3681,8 @@ snapshots:
lodash.merge@4.6.2: {}
lodash@4.17.21: {}
loose-envify@1.4.0:
dependencies:
js-tokens: 4.0.0
@ -3803,6 +3902,8 @@ snapshots:
dependencies:
jsesc: 0.5.0
require-directory@2.1.1: {}
requireindex@1.2.0: {}
resolve-from@4.0.0: {}
@ -3852,6 +3953,10 @@ snapshots:
dependencies:
queue-microtask: 1.2.3
rxjs@7.8.1:
dependencies:
tslib: 2.8.1
safe-array-concat@1.1.3:
dependencies:
call-bind: 1.0.8
@ -3894,6 +3999,8 @@ snapshots:
shebang-regex@3.0.0: {}
shell-quote@1.8.2: {}
side-channel-list@1.0.0:
dependencies:
es-errors: 1.3.0
@ -3960,6 +4067,12 @@ snapshots:
std-env@3.8.0: {}
string-width@4.2.3:
dependencies:
emoji-regex: 8.0.0
is-fullwidth-code-point: 3.0.0
strip-ansi: 6.0.1
string.prototype.matchall@4.0.12:
dependencies:
call-bind: 1.0.8
@ -4004,6 +4117,10 @@ snapshots:
define-properties: 1.2.1
es-object-atoms: 1.0.0
strip-ansi@6.0.1:
dependencies:
ansi-regex: 5.0.1
strip-bom@3.0.0: {}
strip-indent@3.0.0:
@ -4016,6 +4133,10 @@ snapshots:
dependencies:
has-flag: 4.0.0
supports-color@8.1.1:
dependencies:
has-flag: 4.0.0
supports-preserve-symlinks-flag@1.0.0: {}
synckit@0.9.2:
@ -4044,6 +4165,8 @@ snapshots:
dependencies:
is-number: 7.0.0
tree-kill@1.2.2: {}
ts-api-utils@1.4.3(typescript@5.7.2):
dependencies:
typescript: 5.7.2
@ -4247,4 +4370,24 @@ snapshots:
word-wrap@1.2.5: {}
wrap-ansi@7.0.0:
dependencies:
ansi-styles: 4.3.0
string-width: 4.2.3
strip-ansi: 6.0.1
y18n@5.0.8: {}
yargs-parser@21.1.1: {}
yargs@17.7.2:
dependencies:
cliui: 8.0.1
escalade: 3.2.0
get-caller-file: 2.0.5
require-directory: 2.1.1
string-width: 4.2.3
y18n: 5.0.8
yargs-parser: 21.1.1
yocto-queue@0.1.0: {}

31
src/develop.ts Normal file
View File

@ -0,0 +1,31 @@
/**
* @copyright nhcarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { readFile } from "node:fs/promises";
import http from "node:http";
import { join } from "node:path";
// eslint-disable-next-line @typescript-eslint/no-misused-promises
const server = http.createServer(async(request, response) => {
if (request.url === "/") {
const file = await readFile(join(process.cwd(), "index.html"), "utf-8");
// eslint-disable-next-line @typescript-eslint/naming-convention
response.writeHead(200, { "Content-Type": "text/html" });
response.end(file);
}
if (request.url === "/prod/index.js") {
const file = await
readFile(join(process.cwd(), "prod", "index.js"), "utf-8");
// eslint-disable-next-line @typescript-eslint/naming-convention
response.writeHead(200, { "Content-Type": "application/javascript" });
response.end(file);
}
});
server.listen(8080, () => {
console.log("Server listening on port 8080");
});

View File

@ -9,7 +9,8 @@ const version = "{{ version }}";
console.log(`
========================================
Loading NHCarrigan library v${version}.
Copyright (c) ${new Date().getFullYear()} NHCarrigan
Copyright (c) ${new Date().getFullYear().
toString()} NHCarrigan
Changelog: https://codeberg.org/nhcarrigan/website-headers/releases
Licensed under our public license: https://docs.nhcarrigan.com/legal/license
Questions? Contact us at https://docs.nhcarrigan.com/about/contact
@ -115,6 +116,12 @@ styles.innerHTML = `
--background: #abfcecdd;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html {
font-family: 'OpenDyslexic', monospace;
cursor: url('https://cdn.nhcarrigan.com/cursors/cursor.cur'), auto;
@ -145,6 +152,8 @@ main {
width: 95%;
max-width: 1080px;
margin: auto;
margin-bottom: 100px;
padding: 10px;
}
footer {
width: 100%;
@ -155,13 +164,30 @@ footer {
background-color: var(--background);
position: fixed;
bottom: 0;
height: 75px;
padding-left: 100px;
}
a {
color: unset;
cursor: url('https://cdn.nhcarrigan.com/cursors/pointer.cur'), pointer;
}
span[style*="background-image"][style*="crisp.chat/avatar/website"] {
bottom: 100px !important;
#tree-nation-offset-website {
display: flex;
align-items: center;
}
#audio-theme-button {
background: none;
border: none;
cursor: url('https://cdn.nhcarrigan.com/cursors/pointer.cur'), pointer;
color: var(--foreground);
}
@media screen and (max-width: 600px) {
#tree-nation-offset-website {
display: none;
}
footer {
padding-right: 100px;
}
}
`;
@ -175,7 +201,10 @@ footer.innerHTML = `
<a href="https://chat.nhcarrigan.com" target="_blank" rel="noreferrer">
<i class="fa-solid fa-comments"></i>
</a>
<div className="h-4/5" id="tree-nation-offset-website"></div>
<button id="audio-theme-button" type="button">
<i class="fa-solid fa-play"></i>
</button>
<div id="tree-nation-offset-website"></div>
`;
const videoOverlay = document.createElement("video");
@ -222,10 +251,6 @@ hubspot.src = "https://js.hs-scripts.com/47086586.js";
hubspot.async = true;
hubspot.defer = true;
hubspot.id = "hs-script-loader";
const crisp = document.createElement("script");
crisp.innerHTML = `
window.$crisp=[];window.CRISP_WEBSITE_ID="5398ce41-4ceb-4e31-9049-4c784a70179a";(function(){d=document;s=d.createElement("script");s.src="https://client.crisp.chat/l.js";s.async=1;d.getElementsByTagName("head")[0].appendChild(s);})();
`;
const analytics = document.createElement("script");
analytics.defer = true;
analytics.setAttribute("domain", "nhcarrigan.com");
@ -266,7 +291,6 @@ head?.appendChild(styles);
head?.appendChild(treeNation);
head?.appendChild(fontAwesome);
head?.appendChild(hubspot);
head?.appendChild(crisp);
head?.appendChild(analytics);
head?.appendChild(analytics2);
@ -274,3 +298,20 @@ body?.appendChild(footer);
body?.appendChild(videoOverlay);
body?.appendChild(treeNationBottom);
// #endregion
// #region Audio
const playButton = document.querySelector("#audio-theme-button");
const audio = new Audio("https://cdn.nhcarrigan.com/theme.mp3");
let playing = false;
playButton?.addEventListener("click", () => {
if (playing) {
audio.pause();
playing = false;
playButton.innerHTML = "<i class=\"fa-solid fa-play\"></i>";
} else {
void audio.play();
playing = true;
playButton.innerHTML = "<i class=\"fa-solid fa-pause\"></i>";
}
});