Compare commits

..

646 commits

Author SHA1 Message Date
rifting
77dbccfc7e
Merge pull request #301 from Avad3/patch-1
Major bug fix
2025-02-07 16:33:41 -06:00
Avad3
b80f4bd053
Major bug fix 2025-02-07 17:01:54 -05:00
MotorTruck1221
14e1f1f935
Fix the .gitignore 2025-01-15 02:25:34 -07:00
MotorTruck1221
527221462b
Apparently the gruvbox image wasn't there 2025-01-15 02:22:40 -07:00
MotorTruck1221
009836647b
Remove the random testing plugin 2025-01-15 02:15:58 -07:00
MotorTruck1221
8b25af88e0
CI: add submodule cloning 2025-01-15 00:30:15 -07:00
MotorTruck1221
de2cde4541
Bump version to 9.1.0 2025-01-15 00:27:27 -07:00
MotorTruck1221
8240668a5c
Revert "."
This reverts commit 8a79e063e8.
2025-01-15 00:22:08 -07:00
MotorTruck1221
8a79e063e8
. 2025-01-15 00:21:06 -07:00
MotorTruck1221
fdc0246c0a
Fix 2025-01-15 00:07:43 -07:00
MotorTruck1221
4cb20539fd
Revert "."
This reverts commit 06d02c42f1.
2025-01-15 00:04:22 -07:00
MotorTruck1221
06d02c42f1
. 2025-01-15 00:03:51 -07:00
MotorTruck1221
660e4c34d9
Merge branch 'logic-rewrite' 2025-01-15 00:01:33 -07:00
MotorTruck1221
d17d008d7e
Add an actual LICENSE to the repo 2025-01-15 00:00:36 -07:00
MotorTruck1221
c5799fb986
Revert "Stupid types"
This reverts commit 2c4ea3ebad.
2025-01-14 23:56:30 -07:00
MotorTruck1221
39f49aa54c
Revert "Main should build now"
This reverts commit b462e42d33.
2025-01-14 23:56:01 -07:00
MotorTruck1221
abd87fafd2
Settings: add the ability to reset your instance 2025-01-14 23:52:11 -07:00
MotorTruck1221
b462e42d33
Main should build now 2025-01-14 16:32:54 -07:00
MotorTruck1221
2c4ea3ebad
Stupid types 2025-01-14 16:31:29 -07:00
MotorTruck1221
389ad9e5ec
Merge pull request #298 from NebulaServices/main
Config: seo disabled by default
2025-01-14 15:10:05 -08:00
MotorTruck1221
0d8fc89bf5
Config: seo disabled by default 2025-01-14 16:09:36 -07:00
MotorTruck1221
ce0781536c
Merge pull request #297 from NebulaServices/main
Config: make sure the SEO field is there
2025-01-14 15:00:09 -08:00
MotorTruck1221
58a6de3a5d
Config: make sure the SEO field is there 2025-01-14 15:58:55 -07:00
MotorTruck1221
eb3a44a759
Regen pnpm-lock 2025-01-14 05:43:13 -07:00
MotorTruck1221
b0f7eb1922
Bye bye nanostores 2025-01-14 05:42:49 -07:00
MotorTruck1221
1a6a5828dc
I was right, the store isn't needed for mobile 2025-01-14 05:37:06 -07:00
MotorTruck1221
76375ad02a
MP, settings an other things are now done. 2025-01-14 04:30:12 -07:00
MotorTruck1221
ddca0f3038
InstalledPlugins 2025-01-12 02:00:11 -07:00
MotorTruck1221
4fe4efd95a
InstalledTheme is done 2025-01-12 01:22:03 -07:00
MotorTruck1221
833b323267
It's closeee... 2025-01-11 06:34:19 -07:00
MotorTruck1221
c1b1a9de4c
Allow the user to reset their instance if they are having troubles 2025-01-10 04:55:37 -07:00
MotorTruck1221
72b0d4bbac
(most of) The settings are done! 2025-01-10 04:23:58 -07:00
MotorTruck1221
91199d3460
Tab settings 2025-01-10 02:20:43 -07:00
MotorTruck1221
c04c83c22a
Functionality is all done! 2025-01-10 01:34:13 -07:00
MotorTruck1221
82e169150e
No more silly globals 2025-01-10 01:27:39 -07:00
MotorTruck1221
1bd272ec8d
No more silly globals 2025-01-10 01:27:22 -07:00
MotorTruck1221
1616fa21f2
A whole bunch of shit 2025-01-07 03:19:52 -07:00
MotorTruck1221
920d9f198f
Games are back! 2025-01-07 00:40:30 -07:00
MotorTruck1221
f82c2de301
. 2025-01-07 00:05:55 -07:00
MotorTruck1221
1e0508ac85
Index page is back 2025-01-07 00:05:21 -07:00
MotorTruck1221
84f8605269
Index page is almost back : D 2025-01-06 05:58:22 -07:00
MotorTruck1221
ef0f7055a0
Ok cool, now time to rewrite the settings (I am dreading this) 2025-01-04 02:46:58 -07:00
MotorTruck1221
5b578806c7
Settings init is close to being ready to do 2025-01-04 02:33:46 -07:00
MotorTruck1221
b06c338c20
This already looks a number times better 2025-01-04 01:17:53 -07:00
MotorTruck1221
9c3ffcc58e
SW stuff is done for now 2025-01-04 00:06:01 -07:00
MotorTruck1221
3ca47ce108
I like .bind() more 2025-01-04 00:05:32 -07:00
MotorTruck1221
702bc64bc3
I like .bind() more 2025-01-04 00:04:59 -07:00
MotorTruck1221
b34b24e783
More changes? 2025-01-03 12:52:58 -07:00
MotorTruck1221
5bd87033e2
Start the change to the new stuff 2025-01-03 05:17:35 -07:00
MotorTruck1221
927b68dab7
Change the way EventHandler works 2025-01-03 05:04:44 -07:00
MotorTruck1221
5aa0169e81
Remove extra file 2025-01-03 04:46:38 -07:00
MotorTruck1221
9ff01d1d7d
SW shit 2025-01-03 04:45:42 -07:00
MotorTruck1221
16f1976e28
Man, do I love JSDoc 2025-01-01 05:23:10 -07:00
MotorTruck1221
3d4a8f43aa
Events stuff 2025-01-01 05:15:29 -07:00
MotorTruck1221
5b335d2bff
Start the rewrite (it's already SO much better) 2025-01-01 04:48:46 -07:00
MotorTruck1221
8736491818
Version bump 2024-12-30 00:56:20 -07:00
MotorTruck1221
037a2bf8c3
Scramjet 🚀 2024-12-30 00:55:14 -07:00
MotorTruck1221
fcbf8d2e3a
Remove unneeded dep 2024-12-29 22:46:38 -07:00
MotorTruck1221
cc8a8bf801
Make CatalogCard not use Svelte 2024-12-29 21:35:29 -07:00
MotorTruck1221
bab09be364
Unpin Epoxy 2024-12-28 04:05:09 -07:00
MotorTruck1221
7a0167f31b
Bump deps 2024-12-28 04:02:13 -07:00
MotorTruck1221
47fb761c71
Version bump 2024-12-28 03:58:15 -07:00
MotorTruck1221
18980488c6
Bugfix: themes with caps don't uninstall properly 2024-12-28 03:56:49 -07:00
MotorTruck1221
3e844696b0
That component is no longer needed 2024-12-28 03:49:18 -07:00
MotorTruck1221
4bbe97f887
Installed plugins 2024-12-28 03:47:38 -07:00
MotorTruck1221
a9b94c27d4
Don't fetch the data unless on the page 2024-12-28 03:41:11 -07:00
MotorTruck1221
d2b05a1b1b
Remove the svelte component from InstalledThemes 2024-12-28 03:25:12 -07:00
MotorTruck1221
a03f7d111b
Form data isn't needed like at all 2024-12-04 15:16:06 -07:00
MotorTruck1221
87ce59dab6
Why do I have ora as a package? 2024-12-04 15:14:55 -07:00
MotorTruck1221
77ec7e5a56
Remove concurrently 2024-12-04 15:14:33 -07:00
MotorTruck1221
6de99225c4
More SEO garbage 2024-12-04 05:14:54 -07:00
MotorTruck1221
6c0cbf2737
Fix the Svlete stuff, time to 'trim the fat' 2024-12-04 05:06:45 -07:00
MotorTruck1221
b0fca23a20
Ok, fixed that. NOW I need to update all of the effing svelte components 2024-12-04 04:32:55 -07:00
MotorTruck1221
96a904db0d
robots.txt, sitemap 2024-12-04 03:04:45 -07:00
MotorTruck1221
41c109416f
Some SEO stuff 2024-12-04 02:20:39 -07:00
rifting
208b37ce75
this should not be enabled by default 2024-12-02 09:02:33 -06:00
rifting
9bd33020ae
Merge pull request #294 from MadjikDotPng/patch-2
Make the favicon ourple Saturn.
2024-11-21 14:48:20 -06:00
Madjik
e506f5e37e
Make the favicon ourple Saturn. 2024-11-21 14:45:06 -06:00
rifting
89179de230
Merge pull request #292 from PrimeKidMN/main
Update README.md
2024-11-20 18:27:28 -06:00
Possibly Mason N.
d235862eb2
Update README.md 2024-11-20 09:05:36 -05:00
MotorTruck1221
2226483ed3
Deps bump 2024-11-16 02:14:35 -07:00
MotorTruck1221
ed7455985a
Remove the open in settings from the proxy page 2024-11-16 02:13:12 -07:00
rifting
42a9018e87
Update [...packageName].astro 2024-11-12 17:29:26 -06:00
rifting
2e9584e39e
Update Layout.astro 2024-11-12 17:22:33 -06:00
rift
4ab3de409e theme image embed 2024-11-10 22:25:59 -06:00
rift
aab156560f Add embed theme support 2024-11-10 15:53:14 -06:00
rifting
3e09ab61a5
Update README.md 2024-11-09 14:55:21 -06:00
MotorTruck1221
cad7ad2ceb
Version bump 2024-11-09 01:31:46 -07:00
MotorTruck1221
af5352eba2
WHOOPS 2024-11-09 01:28:25 -07:00
MotorTruck1221
20cb82ec7b
Rift, try this 2024-11-09 01:22:03 -07:00
MotorTruck1221
c9e92d92f8
Feat: custom wisp server urls 2024-11-09 01:18:58 -07:00
rifting
9bc00baa38
increase file size limit for marketplace to 25 MB 2024-11-08 17:11:08 -06:00
MotorTruck1221
0d1d6e5490
Switch to bare client for omnibox, remove libcurl as a dep 2024-11-08 03:10:16 -07:00
MotorTruck1221
32a7cc3b7c
Catalog: better mobile support... 2 2024-11-08 03:10:16 -07:00
MotorTruck1221
35f212056f
Catalog: better mobile support 2024-11-08 03:10:15 -07:00
MotorTruck1221
70bca2737c
Fix firefox, thanks @ading2210 2024-11-08 03:10:15 -07:00
rifting
3d57ffe3c2
Merge pull request #283 from 3kho/main
Grammar fixes and stuff
2024-11-07 08:11:14 -06:00
Echo
267432bb28
Fix naming 2024-11-07 09:03:31 -05:00
Echo
9a97b7937e
Grammar fixes 2024-11-07 09:02:52 -05:00
MotorTruck1221
0c2011f070
Bump version to 9.0.1 2024-11-06 21:08:45 -07:00
MotorTruck1221
d662a38ac7
It was fucking ASTROS fault 2024-11-06 21:04:30 -07:00
MotorTruck1221
826d37a374
AUGHGHG 2024-11-06 20:47:45 -07:00
MotorTruck1221
c1b9432a2b
Ok, let's seee 2024-11-06 20:42:19 -07:00
MotorTruck1221
366eca019d
HMMM 2024-11-06 20:36:39 -07:00
MotorTruck1221
fcf0bbb1d9
Yeahh I think I know what's going on... 2024-11-06 20:32:25 -07:00
MotorTruck1221
2519ed3d8c
OH MY HELLL 2024-11-06 20:05:32 -07:00
MotorTruck1221
feb8f6d0f5
Could CI just like... work? 2024-11-06 20:04:50 -07:00
MotorTruck1221
8a1a8abae7
MORE CI 2024-11-06 20:03:22 -07:00
MotorTruck1221
105b58a5c4
Hell 2024-11-06 19:59:53 -07:00
MotorTruck1221
382d5d0030
Whats breaking here? 2024-11-06 19:56:53 -07:00
MotorTruck1221
50a33d4f8d
Changelog.md 2024-11-04 23:30:03 -07:00
MotorTruck1221
e0899932b1
Font stuff & CI 2024-11-04 23:26:58 -07:00
MotorTruck1221
b077371d1f
Ignore everything but the ones we want there 2024-11-04 23:14:18 -07:00
MotorTruck1221
037d9cf26c
Purge non-needed assets 2024-11-04 23:12:27 -07:00
MotorTruck1221
064a868d62
Whoops, forgot to pass that param 2024-11-04 22:58:56 -07:00
MotorTruck1221
bf52d776ff
Fix the plugin stuff 2024-11-04 22:21:08 -07:00
MotorTruck1221
fc1a07b129
Remove all instances or mention of rammerhead 2024-11-04 16:21:17 -07:00
rift
19a3856768 fix up some rammerhead removal things 2024-11-03 20:24:09 -06:00
rift
fc414951d1 fix font 2024-11-03 20:05:10 -06:00
MotorTruck1221
835cb237d7
. 2024-10-29 22:45:41 -06:00
MotorTruck1221
af9494ecce
Docs on themes 2024-10-29 02:15:58 -06:00
MotorTruck1221
eabf4254b1
TYPPEESS 2024-10-29 01:31:40 -06:00
MotorTruck1221
e05f146b28
God, this codebase is getting COMPLICATED 2024-10-29 00:49:39 -06:00
MotorTruck1221
a0cd959a93
I HATE the normal scrollbar 2024-10-28 23:55:59 -06:00
MotorTruck1221
4e398bc9fd
Document the page plugin 2024-10-27 05:23:20 -06:00
MotorTruck1221
0eb1582f7d
Remove the test dbstuff 2024-10-27 05:14:56 -06:00
MotorTruck1221
c5124db29f
Whoops, forgot that shit 2024-10-27 05:03:17 -06:00
MotorTruck1221
e2566121d9
BRO gimme seperate lines 2024-10-27 04:42:45 -06:00
MotorTruck1221
2dac102f3e
The run on sentences go crazzzy 2024-10-27 04:41:49 -06:00
MotorTruck1221
26255f8995
I swear... 2024-10-27 04:39:19 -06:00
MotorTruck1221
bc23ccc1aa
Github, I am going to murder you 2024-10-27 04:38:15 -06:00
MotorTruck1221
b2ca3f6c0b
Switch from note to warning 2024-10-27 04:37:40 -06:00
MotorTruck1221
fc2f38543c
Plugin docs 2024-10-27 04:36:14 -06:00
MotorTruck1221
154eda0aa2
Plugin handling, done 2024-10-27 03:48:48 -06:00
MotorTruck1221
095908302f
The great format 2024-10-26 04:19:46 -06:00
MotorTruck1221
30509de370
BRUh 2024-10-26 04:18:03 -06:00
MotorTruck1221
0fae05e33a
Workerware 2024-10-26 04:13:33 -06:00
MotorTruck1221
5dc222a0df
Time to worker on marketplace proxying & hostname switching
This will be HELL
2024-10-25 17:03:27 -06:00
MotorTruck1221
202b9946e2
--recursive 2024-10-25 17:01:28 -06:00
MotorTruck1221
5d4397d38b
Switch workerware to a submodule 2024-10-25 16:59:50 -06:00
MotorTruck1221
7a0695ac9c
Remove the correct elements from the plugins array 2024-10-25 16:39:25 -06:00
MotorTruck1221
ff7eb81e87
I need to push whatever I have done 2024-10-25 15:16:15 -06:00
MotorTruck1221
4d4ebf2d09
Actually have the damn build work 2024-10-24 03:09:23 -06:00
MotorTruck1221
aae0bd2420
Switch to bare mux v2, libcurl is now default 2024-10-24 02:23:51 -06:00
MotorTruck1221
952337be6e
Page plugin handling (uv.config.inject)
Next up, workerwear for SW plugin handling
2024-10-21 23:58:52 -06:00
MotorTruck1221
fff4d0b286
Some plugin logic (still kinda broken) 2024-10-21 05:30:12 -06:00
MotorTruck1221
4f1a8960f1
proper noscript syntax 2024-10-19 04:57:11 -06:00
MotorTruck1221
4c35560f6c
Chore: format 2024-10-19 04:48:07 -06:00
MotorTruck1221
b456823df3
Just a bunch of changes 2024-10-19 04:47:18 -06:00
MotorTruck1221
4cbc02a2d3
Navigation: this shit is actually mobile & iPad friendly now! 2024-10-19 02:35:35 -06:00
MotorTruck1221
bd39e6fba7
Settings page: fix mobile nav, so users can like use it 2024-10-19 01:58:20 -06:00
MotorTruck1221
d9d7e79f0e
Make sure this shit actually builds 2024-10-18 04:32:18 -06:00
MotorTruck1221
b4e4252d5c
Setup the UI for marketplace Hostname & Proxying 2024-10-18 04:29:36 -06:00
MotorTruck1221
ab37a135af
Gyattt 2024-10-18 03:17:14 -06:00
MotorTruck1221
bd28f8590b
Docker 2024-10-18 02:58:35 -06:00
MotorTruck1221
162a2fbac3
I forgot to add a seperator 2024-10-17 04:18:45 -06:00
MotorTruck1221
4d66649ff8
Add note about marketplace 2024-10-17 04:18:22 -06:00
MotorTruck1221
a2e67033c8
Add loading to iFrame 2024-10-17 04:03:18 -06:00
MotorTruck1221
d6ff02f284
Put the catalog in the [lang] folder.
Still no clue on how to i18n translations for that
2024-10-17 03:43:57 -06:00
MotorTruck1221
187859b1c9
We don't need this block anymore 2024-10-17 03:08:03 -06:00
MotorTruck1221
4887562cc7
Allow the ability to completely disable the marketplace. 2024-10-17 03:07:17 -06:00
MotorTruck1221
643fbbe90d
Update config section of README 2024-10-17 02:33:17 -06:00
MotorTruck1221
5c45c17992
Marketplace: retro theme 2024-10-17 01:56:14 -06:00
MotorTruck1221
7616e93dae
Marketplace: change up the light/oled theme 2024-10-17 01:00:53 -06:00
MotorTruck1221
155051c5fe
Marketplace: light theme 2024-10-16 04:49:50 -06:00
MotorTruck1221
82edb6b284
Apparently sharp didn't exist 2024-10-16 04:10:45 -06:00
MotorTruck1221
c18f175b08
Chore: format 2024-10-16 03:12:18 -06:00
MotorTruck1221
7d325d424a
We don't need this file 2024-10-16 03:11:45 -06:00
MotorTruck1221
6d2ab6e0f9
Marketplace: handle the new stuff! 2024-10-16 03:10:47 -06:00
MotorTruck1221
71ec6f76cc
Marketplace: change directory structure 2024-10-15 23:00:21 -06:00
MotorTruck1221
a385089fe8
A little bit of structure re-organization 2024-10-15 05:31:40 -06:00
MotorTruck1221
05051ea9f9
A shit ton of compression 2024-10-15 05:14:41 -06:00
MotorTruck1221
d495678ac2
Oled theme (rift, you might wanna chnage this idk if you'll like it) 2024-10-15 04:45:03 -06:00
MotorTruck1221
06dbe99cae
Add gruvbox theme 2024-10-15 03:33:38 -06:00
MotorTruck1221
0b5bc42587
Setup the DB properly 2024-10-15 02:10:49 -06:00
MotorTruck1221
35680e719b
Wisp logging bs 2024-10-13 05:17:21 -06:00
MotorTruck1221
620ad25c61
Server: switch to Fastify
Switch config to TOML over JSON (it's just nicer TBH)
2024-10-13 04:33:25 -06:00
MotorTruck1221
deda273eda
Chore: remove all uneeded files 2024-10-12 02:28:19 -06:00
MotorTruck1221
fd8aaf543e
Chore: format... 2! 2024-10-12 02:20:39 -06:00
MotorTruck1221
8cb2513610
Chore: format 2024-10-12 02:19:02 -06:00
MotorTruck1221
a68f0c7e42
Settings: revamp into seperate files. 2024-10-12 02:16:32 -06:00
MotorTruck1221
c63662f602
Marketplace: change the way we deal with themes (no refresh) 2024-10-12 01:17:41 -06:00
MotorTruck1221
6b227f241b
2024-10-09 03:11:18 -06:00
MotorTruck1221
1a9e4097fb
Fix the initial index page 2024-10-09 03:09:55 -06:00
MotorTruck1221
f16ae279e2
Chore: format 2024-10-09 02:39:44 -06:00
MotorTruck1221
c4d2c5b408
Feat: automatic proxy detection
Docs on how to add more later
2024-10-09 02:38:58 -06:00
MotorTruck1221
70bff6156a
Like seriously 2024-10-09 01:54:18 -06:00
MotorTruck1221
5fe93963f3
Rift, whatever autoformatter you are using is giving me cancer 2024-10-09 01:50:23 -06:00
MotorTruck1221
2425f07d6b
Feat: chango games 2024-10-08 03:48:17 -06:00
MotorTruck1221
66ba178ea7
2024-10-08 03:27:38 -06:00
MotorTruck1221
5f8c941d0b
%s/incognito/nebula 2024-10-08 03:26:20 -06:00
MotorTruck1221
f6026c6977
Oggity boogity boo 2024-10-08 03:22:45 -06:00
MotorTruck1221
a10592a031
Fix epoxy 2024-10-08 03:18:36 -06:00
MotorTruck1221
e571cc301c
Add a decent README (not totally correct currently) 2024-10-08 01:08:08 -06:00
MotorTruck1221
ce5c4e5345
Feat: Rammerhead, See description
Currently can only be run with SSL
2024-10-06 03:52:01 -06:00
MotorTruck1221
3fd603667d
Update transports (epoxy is effing broken) 2024-10-06 03:14:00 -06:00
rift
df96ced6d9 css changes 2024-10-04 21:41:04 -05:00
MotorTruck1221
8f1feb8cff
Run a format 2024-10-04 00:49:10 -06:00
MotorTruck1221
8d726133bc
Add a formatter 2024-10-04 00:46:34 -06:00
MotorTruck1221
10992aad3c
We don't need libcurl on EVERY page 2024-10-04 00:29:37 -06:00
MotorTruck1221
88b24b55e6
Libcurl doesn't include types 2024-10-02 19:30:58 -06:00
MotorTruck1221
22b0c1ebf9
Switch to libcurl for omnibox 2024-10-02 19:28:28 -06:00
MotorTruck1221
ac3154e334
why tf did I make this optional??? 2024-10-02 18:45:18 -06:00
MotorTruck1221
d313ac55d9
See description
Feat: add open in settings

Feat: add search engine settings

Feat: add wisp server changing

Feat: add transport switching
2024-10-01 02:51:39 -06:00
MotorTruck1221
e96af1f6fb
fix my scuffed toast notifs 2024-09-30 03:09:05 -06:00
MotorTruck1221
f0c9b7eb82
Feat: A:B cloak, Blob cloaking 2024-09-30 01:19:41 -06:00
MotorTruck1221
c654694603
Make sure the cloak is set upon page reload too 2024-09-29 04:45:24 -06:00
MotorTruck1221
8817a12ede
Feat: Tab cloaking 2024-09-29 04:41:28 -06:00
MotorTruck1221
b38dcc09aa
Fix: perf being shit 2024-09-29 00:40:30 -06:00
MotorTruck1221
dcbde420a4
This is stupid bruh 2024-09-29 00:34:19 -06:00
MotorTruck1221
c8a07a5777
Feat: Omnibox
But now it isn't fucked!
2024-09-28 15:16:31 -06:00
MotorTruck1221
9a2306a9a8
Revert "It builds, but now the page crashes 🔥"
This reverts commit b716dc5b35.
2024-09-28 15:12:27 -06:00
MotorTruck1221
b716dc5b35
It builds, but now the page crashes 🔥 2024-09-28 06:04:03 -06:00
MotorTruck1221
4a4a430b47
Dude, what did I breakkk 2024-09-28 05:23:40 -06:00
MotorTruck1221
c5a73a13ea
Dude, the formatting 😭 2024-09-28 01:15:37 -06:00
MotorTruck1221
3511d7b32f
Why were these formatted terribly???? 2024-09-28 01:13:18 -06:00
MotorTruck1221
6854ba70e2
Omnibox: fix the styling for the last element... 2024-09-27 01:47:09 -06:00
MotorTruck1221
b5e9bdb1d5
Actually allow build 2024-09-27 01:38:27 -06:00
MotorTruck1221
68b1b4c2e2
When clicking on phrase in Omnibox, actually do something 2024-09-27 01:36:57 -06:00
MotorTruck1221
9b6caebfa6
Feat: Omnibox
Now fetched all on the client!
2024-09-27 01:20:59 -06:00
MotorTruck1221
b3947909a0
Omnibox styling... 2024-09-26 23:54:13 -06:00
MotorTruck1221
709c2f3f7b
Damn TypeScript 2024-09-26 03:42:32 -06:00
rift
344fbdea9f Fix a wacky bug 2024-08-22 20:49:02 -05:00
rift
26fb0486fd Video uploads 2024-08-22 16:37:09 -05:00
rift
c9a02c2351 some backend updates 2024-08-22 16:23:13 -05:00
rift
e0805868a6 Fix config 2024-08-21 00:07:18 -05:00
rift
69a86b5a14 Add video, style, and script storage 2024-08-20 23:47:46 -05:00
rift
e78eb63e4e add authentication 2024-08-20 23:42:02 -05:00
rift
948611f434 Image upload API 2024-08-20 19:38:43 -05:00
rift
52d47b4247 fix broken pagnation 2024-08-20 16:25:56 -05:00
MotorTruck1221
6c6452c126
Whoops, forgot to remove that file 2024-08-18 00:22:31 -06:00
MotorTruck1221
3b00a749b5
Add UV 2024-08-18 00:21:03 -06:00
rift
5ae0aad1d6 Merge count and assets API endpoint, and fix pagnation after page transition 2024-08-16 16:27:48 -05:00
rift
1979bae370 do some things 2024-08-15 20:30:52 -05:00
rift
bdea8efb53 Fix overflow 2024-08-15 18:04:06 -05:00
rift
315204e5d7 Pagnation sytem (I have no idea how im going to get the catalog ready for Japanese users 2024-08-15 15:30:44 -05:00
rift
053f2c1e66 Uninstall button 2024-08-14 23:33:16 -05:00
rift
088071fa38 Style package page better 2024-08-14 23:17:51 -05:00
rift
607adcf737 the hell of finishing the inventory system 2024-08-14 23:00:45 -05:00
rift
d3b3f1f676 guh 2024-08-14 01:02:36 -05:00
rift
441248f737 Full theme support! 2024-08-14 00:08:32 -05:00
rift
ad195b22db SSR and marketplace shit 2024-08-13 18:01:18 -05:00
rift
99efa86c58 dev server and basic marketplace 2024-08-13 16:31:26 -05:00
rift
c8a88b837f change db schema 2024-08-04 16:36:17 -05:00
rift
a2b21a141a add some more apis and make a file storage folder 2024-08-04 15:58:13 -05:00
rift
634c88d8d1 Convert to Express, add catalog-pages API and pagnation 2024-08-04 15:12:28 -05:00
rift
a38f1b20ec re add the databse to gitignore 2024-08-02 00:57:57 -05:00
rift
6014409d3d delete the database 2024-08-02 00:57:44 -05:00
rift
ee0306cda8 add the db to gitignore 2024-08-02 00:57:14 -05:00
rift
5c492410be more database shit 2024-08-02 00:56:34 -05:00
rift
e606fc9985 add sequelize and init nebula catalog 2024-08-01 22:48:40 -05:00
rift
471dca4661 Add Nebula Catalog button 2024-07-29 00:37:59 -05:00
rift
5d6b7b74c4 Basic settings 2024-07-29 00:05:06 -05:00
rift
e91a913b62 Make settings layout 2024-07-24 23:22:05 -05:00
rift
f8a6d2bc3d Get started on homepage 2024-07-24 17:07:52 -05:00
rift
0738579074 I centered a div 2024-07-24 16:11:15 -05:00
rift
7909244e95 Fix mobile glitches 2024-07-24 16:01:02 -05:00
rift
7f6b5638de Replace hyphen with underscore for american english locale 2024-07-24 15:53:30 -05:00
rift
68a8be1427 Remove i18n leftovers from experimenting 2024-07-24 15:42:11 -05:00
rift
0262ee9ff0 Fix the dev server???? 2024-07-24 15:38:59 -05:00
rift
721fa7bcda home button 2024-07-23 21:16:55 -05:00
rift
98cf07b676 fix stupid view transition shit and make basic server 2024-07-23 20:55:18 -05:00
rift
2b7380ba57 broken header shit 2024-07-23 20:07:55 -05:00
rift
6162b3e27f Start on games page and move mobile navigation to the layout 2024-07-23 19:27:38 -05:00
rift
8d7cc2cec1 Remove useless keyframes 2024-07-23 18:55:23 -05:00
rift
e52c45b345 sliding animation! 2024-07-23 18:51:05 -05:00
rift
ed919b2f21 pain 2024-07-22 22:58:16 -05:00
rift
781a31d3bb i18n is so weird brooo 2024-07-22 14:52:42 -05:00
rifting
d82bee3150
Merge pull request #264 from MotorTruck1221/e
Bump deps & Fix transport garbage
2024-07-01 13:09:34 -05:00
MotorTruck1221
9c01c9f65c
Don't set the transport until the user clicks suggestions or hits enter 2024-07-01 01:07:27 -06:00
MotorTruck1221
a341b1dcbe
Default to epoxy 2024-07-01 00:27:31 -06:00
MotorTruck1221
776507703a
Bump deps 2024-07-01 00:26:44 -06:00
rift
215d24252e
Merge pull request #260 from MotorTruck1221/main
Bump dependencies
2024-05-11 11:11:13 -05:00
MotorTruck1221
fd2b79a884
Bump deps (fixes errors and other things) 2024-05-11 00:48:03 -06:00
rift
ab73ec684c basic video support, not usable by end user yet 2024-05-09 21:01:47 -05:00
rift
4da0e8675f Significant performance improvements 2024-05-09 19:32:13 -05:00
rift
5ba3cf247a
Merge pull request #254 from MotorTruck1221/main
Bump Dependencies
2024-04-29 13:49:49 -05:00
MotorTruck1221
50ba1b5ecb
Bump Deps 2024-04-29 11:40:20 -06:00
rift
981c5bee82
Merge pull request #251 from Notplayingallday383/patch-4
patch: fix scaling on mobile
2024-04-24 18:21:55 -05:00
John
5f50b5c4ce make using it on mobile better 2024-04-23 16:11:52 -04:00
rift
eda3b464d8 Fix more annoying bullshit 2024-04-20 12:35:21 -05:00
rift
b12c75fe21 Fix annoying bullshit 2024-04-20 12:29:43 -05:00
rift
89b93549cb
Merge pull request #250 from MotorTruck1221/tgt
Fix Stupid Shit
2024-04-18 16:39:30 -05:00
MotorTruck1221
4a47b5c987
Fix that bullshit too 2024-04-18 14:57:32 -06:00
MotorTruck1221
426c86a451
Format 2024-04-18 14:41:56 -06:00
MotorTruck1221
7c88e0bc5d
Ignore package.json for prettier 2024-04-18 14:41:40 -06:00
MotorTruck1221
86793fd675
bump dependencies 2024-04-18 14:40:29 -06:00
MotorTruck1221
3121dd8e5d
Fix the stupid overflow error 2024-04-18 14:39:11 -06:00
rift
d3d4736bae
Merge pull request #249 from MotorTruck1221/mental-breakdown
Mental breakdown (Fix Bare Clients 😭)
2024-04-17 14:42:54 -05:00
MotorTruck1221
65d104538a
Format goes brrr 2024-04-17 08:56:34 -06:00
MotorTruck1221
b4dba4d5bb
In the wise words of @riftriot 'GUH' 2024-04-17 08:56:15 -06:00
rift
19635704c8
Merge pull request #248 from IncognitoTGT/main
fix flicker
2024-04-16 22:29:03 -05:00
incognitotgt
c2268be997
fix issue for last 2024-04-16 23:23:56 -04:00
tgt
e0282962d6
Merge branch 'NebulaServices:main' into main 2024-04-16 22:22:52 -04:00
rift
06ce2d0177 Revert "Merge pull request #247 from NebulaServices/revert-245-main"
This reverts commit cb9b15fccc, reversing
changes made to 0073a1121f.
2024-04-16 21:22:01 -05:00
incognitotgt
3833559cec
particles 2024-04-16 07:44:10 -04:00
rift
cb9b15fccc
Merge pull request #247 from NebulaServices/revert-245-main
Revert "revamp themes"
2024-04-15 21:00:02 -05:00
rift
e6736db056
Revert "revamp themes" 2024-04-15 20:59:53 -05:00
rift
0073a1121f
Merge pull request #245 from IncognitoTGT/main
revamp themes
2024-04-15 20:58:49 -05:00
incognitotgt
82ca99aa5d
fix insanely annoying flash 2024-04-15 20:47:47 -04:00
incognitotgt
6b5e863461
fix background issue 2024-04-15 19:48:16 -04:00
incognitotgt
7117e67e0a
use hook for background 2024-04-15 16:22:16 -04:00
incognitotgt
217d3a40db
format code and fix a tiny issue 2024-04-15 01:16:45 -04:00
incognitotgt
d7bb56b815
use normal css for bg image 2024-04-15 01:13:50 -04:00
incognitotgt
c0272a798d
theme backgrounds 2024-04-14 19:08:34 -04:00
tgt
30efd8c990
Merge branch 'NebulaServices:main' into main 2024-04-14 00:55:57 -04:00
rift
f7e596c628
Merge pull request #246 from MotorTruck1221/bare-clients
Bare clients fix (permanently)
2024-04-12 12:50:25 -05:00
MotorTruck1221
94236a36dc The bare clients now exist 2024-04-12 10:59:17 -06:00
MotorTruck1221
bd4d20ba38 Start fixing... 2024-04-12 10:42:09 -06:00
incognitotgt
7201d7120e
revamp themes 2024-04-11 17:02:53 -04:00
rift
b152154cf0 There ARE bare clients !? 2024-04-07 16:01:41 -05:00
rift
aba3153c4f Switch away from AES to 3 key XOR 2024-04-06 17:59:30 -05:00
rift
a6473f3e77 update bare-mux 2024-04-06 17:39:08 -05:00
rift
eb94911a4d add suzumiya39 to credits page 2024-03-28 13:53:05 -05:00
rift
142767738a
Merge pull request #239 from suzumiya39/main
Revison Languege file (Japanese)
2024-03-28 13:47:19 -05:00
suzumiya39
5bd5e07169
revision ja.json (2) 2024-03-29 03:07:50 +09:00
suzumiya39
e70f77819c
Update ja.json 2024-03-29 02:56:39 +09:00
rift
9e4f84cf09 credits, clean up css, add more translations 2024-03-27 21:16:45 -05:00
rift
9abb1dfc97 add particles translation and icons for dropdowns 2024-03-25 19:13:54 -05:00
rift
a48af7d00e
Merge pull request #237 from Percslol/main
make nebula use latest version of libcurl
2024-03-23 21:00:12 -05:00
Percs
07f6c70dbe make nebula use latest version of libcurl 2024-03-23 19:35:22 -05:00
rift
237c783382
Merge pull request #236 from MotorTruck1221/fastify
Switch Back to fastify
2024-03-23 14:06:58 -05:00
MotorTruck1221
12a7ac0b06
Update README accordingly 2024-03-23 02:16:25 -06:00
MotorTruck1221
1ee0a620a7
Remove express from deps 2024-03-23 02:15:53 -06:00
MotorTruck1221
460aa64634
Format 2024-03-23 01:48:06 -06:00
MotorTruck1221
0e6ee114e5
Comment masqr out 2024-03-23 01:47:48 -06:00
MotorTruck1221
e9a88bc1cd
Add masqr! 2024-03-23 01:45:47 -06:00
MotorTruck1221
fd8424242e
Update deps 2024-03-23 00:40:38 -06:00
MotorTruck1221
0ffd145633
Rename file 2024-03-23 00:37:59 -06:00
MotorTruck1221
c5d60be069
Start the switch BACK to fastify 2024-03-23 00:35:25 -06:00
rift
657d597d84 update libcurl 2024-03-22 09:40:36 -05:00
rift
c2c4116e58 update wisp server 2024-03-22 09:28:00 -05:00
rift
2f3beca70b 'Fix' random package not found errors 2024-03-21 21:02:15 -05:00
rift
a46908389c
Merge pull request #235 from MotorTruck1221/bugfixes
Bugfixes
2024-03-21 15:28:37 -05:00
MotorTruck1221
218ab89113
End with a trailing / 2024-03-21 11:47:59 -06:00
MotorTruck1221
8c895090c8
Format code for the 4th time 2024-03-21 00:31:47 -06:00
MotorTruck1221
82f4bd1c63
Mobile menu: fix text size 2024-03-21 00:30:01 -06:00
MotorTruck1221
8d63bf5e11
Fix borked tab cloaking page 2024-03-21 00:26:51 -06:00
MotorTruck1221
b47e0f4ec7
Fix 404 text color 2024-03-21 00:13:46 -06:00
MotorTruck1221
307eedaca1
Pin node version in docker 2024-03-21 00:10:05 -06:00
MotorTruck1221
c1b1f92b80
Make sure docker and code works 2024-03-21 00:04:52 -06:00
MotorTruck1221
817069ae2e
Add docker 2024-03-20 23:54:37 -06:00
MotorTruck1221
9b2a85bb4c
Deps 2024-03-20 23:46:17 -06:00
MotorTruck1221
4ba5a7215a
Deps 2024-03-20 23:44:37 -06:00
MotorTruck1221
17a05d4461
Fix SW registration errors 2024-03-20 23:43:53 -06:00
MotorTruck1221
c7b158fd57
formatting 2024-03-16 01:22:23 -06:00
MotorTruck1221
8b99bcc6a8
Only needed once 2024-03-16 01:22:02 -06:00
MotorTruck1221
c4a3741542
MAKE sure a transport is there 2024-03-16 01:09:21 -06:00
MotorTruck1221
445e0b0acd
Fix most of the bare client issue 2024-03-16 00:03:34 -06:00
MotorTruck1221
63ad35ce18
update deps 2024-03-15 23:57:04 -06:00
MotorTruck1221
90e797be05
Merge pull request #3 from MotorTruck1221/main
Update branch
2024-03-15 23:43:54 -06:00
Riftriot
e23657144a Fix everything 2024-03-15 12:23:38 -05:00
Riftriot
750dac8d9d Revert "update libcurl and deps, bugfixes"
This reverts commit 5154da62ab.
2024-03-15 11:48:36 -05:00
Riftriot
420cacd8c9 Revert "Format"
This reverts commit 7e44d6cdb2.
2024-03-15 11:48:25 -05:00
rift
529f943646
Merge pull request #230 from MotorTruck1221/deps
bugfixes
2024-03-14 09:32:59 -05:00
MotorTruck1221
7e44d6cdb2
Format 2024-03-14 01:23:25 -06:00
MotorTruck1221
5154da62ab
update libcurl and deps, bugfixes
Fixes the 'no bare clients issue (fixes #228), upgrades libcurl to 0.5.3 and other deps too
2024-03-14 01:22:56 -06:00
rift
c9ce4b5d1a Revert "Set libcurl as default on ios and update libcurl"
This reverts commit 9357f2ed11.
2024-03-12 13:15:21 -05:00
rift
9357f2ed11 Set libcurl as default on ios and update libcurl 2024-03-11 22:20:53 -05:00
rift
3e77fdc4be iOS detection 2024-03-11 18:29:04 -05:00
rift
6a655c48d1
Merge pull request #227 from MotorTruck1221/bare
Add the option to use a Bare Server
2024-03-11 13:36:07 -05:00
MotorTruck1221
10fa42830a https not http 💀 2024-03-11 06:00:04 +00:00
MotorTruck1221
342e8e264f
upgrade libcurl to v0.5.2 2024-03-10 23:52:59 -06:00
MotorTruck1221
f92b059604
Format (again) 2024-03-10 22:33:33 -06:00
MotorTruck1221
d2dff8ce09
Update dependencies (again) 2024-03-10 22:32:19 -06:00
MotorTruck1221
5692dd9909
Only allow bare-change if using bare transport 2024-03-10 22:28:03 -06:00
MotorTruck1221
799e8979b2
Default to libcurl over epoxy 2024-03-10 21:56:24 -06:00
MotorTruck1221
3ab4394376
Remove comment 2024-03-10 03:56:20 -06:00
MotorTruck1221
bb26ff2e98
Format 2024-03-10 03:55:28 -06:00
MotorTruck1221
df25d7882d
Finalize adding bare server as a transport 2024-03-10 03:54:57 -06:00
MotorTruck1221
a3094b3923
Whoops 2024-03-10 03:42:22 -06:00
MotorTruck1221
11dce272a4
Remove bareswitcher on UV (not needed due to bare-mux), add bareTransport to sw 2024-03-10 03:37:56 -06:00
MotorTruck1221
c55f67ad58
Add BareTransport code 2024-03-10 03:34:28 -06:00
MotorTruck1221
56ed5a9455
Update dependencies 2024-03-10 03:29:48 -06:00
rift
441ab183b7
Merge pull request #226 from MotorTruck1221/libcurl
Add Libcurl as a transport
2024-03-09 09:22:04 -06:00
MotorTruck1221
b8bc307fe7
Format 2024-03-09 02:52:11 -07:00
MotorTruck1221
bf24bf53c0
Add libcurl 2024-03-09 02:51:29 -07:00
MotorTruck1221
c5e05997dd
Add masqr bs back to index.html 2024-03-09 02:09:15 -07:00
MotorTruck1221
f7a49e47bf
Add libcurl to dependencies 2024-03-09 02:07:12 -07:00
MotorTruck1221
7b0d3b710a
Update dependencies 2024-03-09 01:55:19 -07:00
rift
d3282c7212 Remove http proxy feature 2024-03-08 19:50:04 -06:00
Riftriot
35cb912e28 Particles.js and crismas 2024-03-08 13:17:03 -06:00
Riftriot
2b0292a614 Translations and css improvements 2024-03-08 11:51:37 -06:00
Riftriot
e7fcc91133 hacker theme 2024-03-08 11:46:47 -06:00
rift
e391ea693f
Fix epoxypath on windows 2024-03-07 12:19:12 -06:00
rift
6c1ce96036
Merge pull request #223 from MotorTruck1221/wisp
TLS
2024-03-07 12:18:28 -06:00
MotorTruck1221
8f531aff11
Formatting 2024-03-06 01:19:16 -07:00
MotorTruck1221
69823802f5
Finalize 2024-03-06 01:14:00 -07:00
MotorTruck1221
af88c5475b
Epoxy Transport setup and working (mostly0 2024-03-06 01:02:13 -07:00
MotorTruck1221
fd4c4f6fcb
Transports are now able to be used and registered 2024-03-06 00:48:32 -07:00
MotorTruck1221
69a2cd5b61
OK 2024-03-04 01:53:51 -07:00
MotorTruck1221
289cd7ccec
Update server (with types) 2024-03-04 00:57:42 -07:00
MotorTruck1221
be8dc47f29
Update dependencies, start to add wisp stuff 2024-03-04 00:47:39 -07:00
rift
fb682c799d
Update rammerhead dependancy 2024-02-21 12:13:58 -06:00
rift
ba3d83e09c
Merge pull request #219 from IncognitoTGT/main
readd compression
2024-02-13 21:20:16 -06:00
incognitotgt
de6b155c55 fastify is gone 2024-02-13 17:24:42 -05:00
incognitotgt
c14c7971aa fix: readme (osama) 2024-02-13 16:52:03 -05:00
incognitotgt
9d9432bfd5 chore: readd compression
fix: express wasn't listed as a dependency?!
style: prettier
2024-02-13 16:49:56 -05:00
rift
8fc5553b52 fix autofill 2024-02-12 16:48:20 -06:00
Riftriot
0813d6bfd9 server improvements and actually fix masqr 2024-02-12 13:18:37 -06:00
rift
d36fc0fceb Fix masqr (thanks blumiere) 2024-02-08 22:08:21 -06:00
rift
521c2b8cdf Add wisp server node 2024-02-08 19:46:02 -06:00
rift
d213843bbf
Merge pull request #213 from IncognitoTGT/seo
better lighthouse scores!?!?!??!?!!?!?!?!?!?!?!?
2024-01-30 22:00:24 -06:00
incognitotgt
ef06e6e6a3 fix: text color on some pages
chore: add compression for lighthouse, meta tags
feat: near perfect lighthouse scores????
2024-01-30 22:48:26 -05:00
incognitotgt
9593a0e46b chore: add seo tags, prettier was also ran 🐳 2024-01-30 21:29:06 -05:00
rift
1c54765c77 Add masqrbation abilities 2024-01-22 21:19:31 -06:00
rift
ad3d231d16 localizations 2024-01-15 13:36:54 -06:00
rift
d5c720775f Change npm package for BSN 2024-01-15 12:55:57 -06:00
rift
eeed30dd32 temporaily update BSN dependancy 2024-01-15 10:44:59 -06:00
rift
fbff40d7f8 Reset button for HTTP proxy 2024-01-15 10:30:21 -06:00
rift
2c22a6afc6 Feat: Http proxy support. (Bare server still must be updated) 2024-01-15 10:23:50 -06:00
rift
666ca92547 Get started on HTTP proxy UI and add FAQ 2024-01-14 12:46:19 -06:00
rift
a62534618b Basic tab UI (NOT MOBILE READY) 2024-01-12 13:51:14 -06:00
rift
b38a597b7e
Merge pull request #209 from NebulaServices/main
q
2024-01-12 12:22:15 -06:00
rift
060d69e652 enter key 2024-01-07 17:37:42 -06:00
rift
c2fe2b980f Validate that bare servers can actually function and fix CSS. 2024-01-07 16:59:28 -06:00
rift
26ff6820f0 Re-add navbar buttons and add toast translations 2024-01-07 09:34:45 -06:00
rift
476c65a82c Fix japanese settings from having a seizure 2024-01-07 08:58:11 -06:00
rift
14d1a9fb54 Fix overflow on mobile. 2024-01-06 13:56:32 -06:00
rift
682c892f53 Fix dev server 2024-01-06 13:24:59 -06:00
rift
4ea772ba18 remove invisible text on mobile 2024-01-06 13:16:32 -06:00
rift
7d483c4aab Add share button (UV only) 2024-01-06 12:33:28 -06:00
rift
e098f1eb08 Add favicon and title in embed mode + comment out refresh/un/re/do buttons 2024-01-06 11:45:16 -06:00
rift
9c06cb2962 Feat: Find closest bare server in prod instances 2024-01-05 22:27:22 -06:00
Riftriot
cc429fd8cb forgot to delete that 2024-01-04 14:32:39 -06:00
Riftriot
6c6c6626cf Localize bare switcher and add button 2024-01-04 14:31:52 -06:00
rift
5c632642d4
Merge pull request #201 from MotorTruck1221/bareSwitch
Implement Bare Server Switching
2024-01-03 18:40:52 -06:00
MotorTruck1221
79d65953a7 Formatting 2024-01-03 17:36:42 -07:00
MotorTruck1221
c821d86362 Final touches 2024-01-03 17:35:34 -07:00
MotorTruck1221
52f901c6c4
Merge branch 'NebulaServices:main' into bareSwitch 2024-01-03 17:11:12 -07:00
rift
c18c2267b0 De-localize language settings 2024-01-03 17:35:09 -06:00
MotorTruck1221
5caba447ab Switch to NPM version of localforage 2024-01-03 14:26:31 -07:00
MotorTruck1221
38b404d453 Export get (for use later) 2024-01-02 23:44:02 -07:00
MotorTruck1221
75beb0e282 Bare Server Switching done (almost) 2024-01-02 23:41:05 -07:00
rift
400070dcb5 Revert "made title text and iframeheader icons not bland, fixed text readbility in Latte"
This reverts commit 323086c19d.
2024-01-02 21:05:56 -06:00
rift
a08add1bfa
Merge pull request #200 from IncognitoTGT/main
fix: text properly themed; discord invite through proxy now works.
2024-01-02 18:00:11 -06:00
incognitotgt
323086c19d made title text and iframeheader icons not bland, fixed text readbility in Latte 2024-01-02 18:57:46 -05:00
tgt
53d6c486ef
Merge branch 'NebulaServices:main' into main 2024-01-02 18:27:48 -05:00
incognitotgt
a98fe44063 Revert "syntax error go brrr"
This reverts commit dc32e1d142.
2024-01-02 18:21:43 -05:00
incognitotgt
beefe7ab44 Revert "Catppuccin theming was inconsistent"
This reverts commit d8a975d531.
2024-01-02 18:21:31 -05:00
incognitotgt
38231f4eaa Revert "prettier"
This reverts commit c27ccc043c.
2024-01-02 18:21:20 -05:00
rift
9bcfb359c5
Merge pull request #199 from r58Playz/fix-catppuccin
Fix catppuccin theme
2024-01-02 17:05:37 -06:00
incognitotgt
d636022898 Fixed discord invite through proxy 2024-01-02 17:56:44 -05:00
incognitotgt
c27ccc043c prettier 2024-01-02 17:52:40 -05:00
incognitotgt
d8a975d531 Catppuccin theming was inconsistent 2024-01-02 17:51:56 -05:00
incognitotgt
270a87d03a Merge branch 'main' of https://github.com/IncognitoTGT/Nebula 2024-01-02 17:44:25 -05:00
incognitotgt
dc32e1d142 syntax error go brrr 2024-01-02 17:44:17 -05:00
Toshit Chawda
85b933e339
remove generator script 2024-01-02 13:02:09 -08:00
Toshit Chawda
61da89c1a9
fix catppuccin theme 2024-01-02 12:59:17 -08:00
Cohen Erickson
59bad794e5
Merge pull request #197 from Nebelung-Dev/patch-1
fix typo
2024-01-01 18:16:54 -06:00
Cohen Erickson
c920eac3fe
Merge pull request #198 from IncognitoTGT/main
fix: css, broken links, prettier
2024-01-01 18:16:05 -06:00
incognitotgt
d0ef235c24 Prettier and replace class with ClassName 2024-01-01 19:00:00 -05:00
incognitotgt
ddc2f47f97 Games fixed 2024-01-01 18:34:01 -05:00
tgt
f45fe3e089
Merge branch 'NebulaServices:main' into main 2024-01-01 18:08:11 -05:00
incognitotgt
c82da4a4e7 fixed planet not rotating, fixed responsive text size 2024-01-01 18:07:50 -05:00
Nebelung
cece5aea91
fix typo 2024-01-01 13:37:57 -08:00
rift
89229d95e5 AES encryption for dynamic 2024-01-01 13:21:48 -06:00
rift
ccb9f7e6e9
Merge pull request #196 from cohenerickson/main
bump UV
2024-01-01 12:02:40 -06:00
cohenerickson
5943accc9f bump UV 2024-01-01 11:56:26 -06:00
Cohen Erickson
996bb4cdc9
Merge pull request #195 from IncognitoTGT/main
feat: Improved about:blank, ironing out css
2024-01-01 11:09:16 -06:00
incognitotgt
bf85598b21 whitespace? 2024-01-01 11:32:22 -05:00
incognitotgt
326e196bc3 Hides logo text on mobile, removed nonexistent css class 2024-01-01 11:24:17 -05:00
incognitotgt
69a478006a Fixed Japanese being borked in mobile 2024-01-01 10:43:02 -05:00
incognitotgt
5088a33f14 grammer 2023-12-31 23:38:19 -05:00
incognitotgt
dbe076e801 about:blank for entire nebula 2023-12-31 23:36:21 -05:00
tgt
3058151d55
Merge branch 'NebulaServices:main' into main 2023-12-31 22:34:43 -05:00
rift
4b3ddcab1b Ultraviolet AES 2023-12-31 21:31:09 -06:00
incognitotgt
3f3afd9307 No more annoying borders. 2023-12-31 21:50:05 -05:00
incognitotgt
a1b1dfd99a No more annoying borders. 2023-12-31 21:45:45 -05:00
rift
146ef7dc21 Fix invalid themes 2023-12-31 20:13:57 -06:00
rift
dd988979cf Re-add JP logo styling 2023-12-31 18:33:36 -06:00
rift
979afeedff
Merge pull request #193 from IncognitoTGT/main
Changed the default search engine
2023-12-31 17:46:17 -06:00
incognitotgt
8b76d26555 Thought this was not important 💀 2023-12-31 18:43:33 -05:00
incognitotgt
e4e7a69280 Changed the default search engine 2023-12-31 18:37:44 -05:00
rift
e9b95c8e49
Merge pull request #192 from cohenerickson/main
Move dynamic to npm package
2023-12-31 14:59:09 -06:00
cohenerickson
cd2ef3d630 move dynamic to npm package 2023-12-31 14:56:13 -06:00
rift
6c46bea1bd
Merge pull request #191 from IncognitoTGT/main
Themes and css improvements
2023-12-31 13:53:43 -06:00
incognitotgt
dd0dd77898 Improved colors of ALL of the catppuccin icons in settings 2023-12-31 14:41:20 -05:00
incognitotgt
7fc56a5f71 Removed redundant class, weird thing is that it didn't work before wth 2023-12-31 14:15:57 -05:00
incognitotgt
e02c7c7732 Got latte working, also added option for schoology cloaking 2023-12-31 14:07:21 -05:00
incognitotgt
afd295a276 Latte since cohen wanted it bruh 2023-12-31 13:01:36 -05:00
tgt
1acf4544e3
Merge branch 'NebulaServices:main' into main 2023-12-31 01:11:43 -05:00
incognitotgt
1d00f21500 Catppuccin done??!! 2023-12-31 01:11:08 -05:00
incognitotgt
94cc720ee4 Frappe;tabs in settings iffy 2023-12-31 00:59:22 -05:00
rift
de2de61642 Hide URL in embed mode 2023-12-30 22:44:47 -06:00
incognitotgt
6b034d0eeb Fixed typo 2023-12-30 20:50:10 -05:00
incognitotgt
ec5aa81092 Changed Eruda default theming 2023-12-30 18:55:24 -05:00
rift
cb934dba31 Translations and fix typo 2023-12-30 16:10:41 -06:00
rift
c4007c8436 Add theme feature 2023-12-30 16:05:57 -06:00
rift
0c6bdf66f0
Merge pull request #189 from Riftriot/main
Unfuck everything
2023-12-30 14:43:20 -06:00
rift
4603ee4fa5 Fix shit 2023-12-30 14:41:41 -06:00
rift
9203e93d80 Revert "Starting point since I don't want to break something later on"
This reverts commit b4c759eded.
2023-12-30 14:38:31 -06:00
rift
d33e0df2b4 Revert "So it loads, but when I try to set a different theme using localstorage, its broken?"
This reverts commit afbcb52286.
2023-12-30 14:38:22 -06:00
rift
79fca20943 Revert "Dumb ahh left a thing in css, removed and ow works yay"
This reverts commit a934cfc4fd.
2023-12-30 14:38:15 -06:00
rift
962dc1b52e
Merge pull request #188 from IncognitoTGT/main
Got theme backend working, eruda also has a theme that matches with nebula more
2023-12-30 12:06:41 -06:00
incognitotgt
a934cfc4fd Dumb ahh left a thing in css, removed and ow works yay 2023-12-30 13:03:10 -05:00
incognitotgt
afbcb52286 So it loads, but when I try to set a different theme using localstorage, its broken? 2023-12-30 12:08:34 -05:00
incognitotgt
b4c759eded Starting point since I don't want to break something later on 2023-12-30 12:05:48 -05:00
incognitotgt
53912cf730 Merge branch 'main' of https://github.com/IncognitoTGT/Nebula 2023-12-29 19:38:06 -05:00
rift
bfab819827 Finish autofill 2023-12-29 18:29:36 -06:00
tgt
869602ce00
Merge branch 'NebulaServices:main' into main 2023-12-29 18:27:16 -05:00
incognitotgt
92d234ce01 AHHH 2023-12-29 18:26:47 -05:00
rift
00c482aac5
Merge pull request #186 from IncognitoTGT/main
Made code prettier, also tried css for search suggestions. Themes are…
2023-12-29 17:25:40 -06:00
incognitotgt
aa86e2a4d1 fixed corners kinds 2023-12-29 18:22:01 -05:00
incognitotgt
3ba2d8ba06 Made code prettier, also tried css for search suggestions. Themes are coming tommorrow <@578375908247863296> 2023-12-29 18:11:37 -05:00
rift
ab9d7f8096 autofill 2023-12-29 14:09:52 -06:00
rift
6937e7c993 Autofill backend 2023-12-29 11:20:07 -06:00
rift
125878676f Downgrade UV 2023-12-28 20:20:42 -06:00
rift
1b750df0f1
Merge pull request #185 from NebulaServices/dev
Merge UV and Dynamic SW files
2023-12-28 13:55:54 -06:00
cohenerickson
ebb6a436a6 Merge Dynamic and UV sw 2023-12-28 13:53:00 -06:00
Cohen Erickson
2ea3f4e0f7
Merge pull request #184 from NebulaServices/main
Fix dev -> main workflow
2023-12-28 13:43:37 -06:00
rift
5ed9819c4f Make AES more random 2023-12-28 11:50:58 -06:00
rift
89064c7e15
Merge pull request #183 from IncognitoTGT/main 2023-12-28 11:29:18 -06:00
rift
554dd33007 aes 2023-12-28 11:28:32 -06:00
incognitotgt
a359d5ec21 Update IframeHeader and localization files 2023-12-28 12:06:19 -05:00
incognitotgt
f374a77881 <@578375908247863296>
Fixed the iframe selecting when you click navbar, fixed navbar css, and fixed file extensions.
2023-12-28 10:45:31 -05:00
rift
5377d71c1f
Merge pull request #182 from NebulaServices/rewrite
Rewrite
2023-12-27 19:13:34 -06:00
rift
559211ea2c Merge branch 'rewrite' of https://github.com/NebulaServices/Nebula into rewrite 2023-12-27 19:10:24 -06:00
rift
c8e8fe6311 give package.json a name 2023-12-27 19:10:12 -06:00
rift
610e03a974
Update README.md 2023-12-27 19:06:22 -06:00
rift
b81e686fc2 radon games and discord emebed tags 2023-12-27 18:55:14 -06:00
rift
bc73f5d3f3 about blank mode 2023-12-27 18:44:35 -06:00
rift
4f8f18f0ff
Merge pull request #181 from IncognitoTGT/rewrite
Nav buttons and some polish
2023-12-27 18:28:56 -06:00
incognitotgt
1d360430a6 Merge branch 'rewrite' of https://github.com/IncognitoTGT/Nebula into rewrite 2023-12-27 19:13:20 -05:00
incognitotgt
fc6c4a1c6d Got navigation buttons, haha merge conflict 2023-12-27 19:13:09 -05:00
incognitotgt
949e922606 Got navigation buttons, haha merge conflict 2023-12-27 19:12:47 -05:00
tgt
4f7ed25e99
Merge branch 'NebulaServices:rewrite' into rewrite 2023-12-27 18:53:14 -05:00
rift
e14f84d1bb Search engines 2023-12-27 17:14:12 -06:00
rift
04cf73e84a Use LoadSuspense for proxy router 2023-12-27 16:58:41 -06:00
tgt
5fdd61587e
Merge branch 'NebulaServices:rewrite' into rewrite 2023-12-27 16:21:02 -05:00
rift
5c256323dc FINAL touch up I swear 2023-12-27 15:16:59 -06:00
rift
5e71f49325 accidently pushed broken code 2023-12-27 15:15:50 -06:00
rift
24068f354d overflow fix 2023-12-27 15:13:30 -06:00
rift
c954fab097 add suspense 2023-12-27 15:09:49 -06:00
rift
6db77d4785 Coming soon locales 2023-12-27 14:40:51 -06:00
rift
7c295529ac forgot to completely remove buggy warning 2023-12-27 14:34:49 -06:00
rift
1c48eb2a65 basic suspense 2023-12-27 14:19:48 -06:00
incognitotgt
1b2f57e7d0 Merge branch 'rewrite' of https://github.com/IncognitoTGT/Nebula into rewrite 2023-12-27 15:10:09 -05:00
incognitotgt
03130a415d fixed the nebula link, why the hell is it w-1/2 2023-12-27 15:02:08 -05:00
rift
4281edb7a7 spotify added to sitesupport.json 2023-12-27 13:50:42 -06:00
rift
2520dbfa44 Remove dynamic buggy warning 2023-12-27 13:47:09 -06:00
rift
99aa37675e Fix type errors and naming 2023-12-27 13:28:54 -06:00
rift
5ba1c539ce
Merge pull request #180 from IncognitoTGT/rewrite
Added Eruda support for iframe view.
2023-12-27 13:12:51 -06:00
incognitotgt
d51b9bfc25 Added Eruda support for iframe view. ts-ignore is since typescript can't tell the iframe is not in the same file as IframeHeader.tsx 2023-12-27 13:39:06 -05:00
rift
4d7c8449d8 Tab cloaking 2023-12-27 10:46:42 -06:00
rift
78635d2671
Merge pull request #178 from MotorTruck1221/rewrite
Fix up Mobile support
2023-12-27 09:09:09 -06:00
MotorTruck1221
c4debda932 Fixup searchbar for mobile 2023-12-27 03:41:33 -07:00
MotorTruck1221
76163c96d3 Fixup settings for mobile and niceness 2023-12-27 03:32:56 -07:00
MotorTruck1221
38a4e86eff Mobile nav update 2023-12-27 03:17:17 -07:00
rift
196e19714d Discord logo 2023-12-26 23:36:48 -06:00
rift
9a7991c982 Title translations and touch-ups 2023-12-26 23:04:26 -06:00
rift
1aa4da81cf Forgot to delete these; these are gonna be a pain to maintain so they're going 2023-12-26 22:26:52 -06:00
rift
3821c227da Fix discord, make embeded default proxy mode 2023-12-26 22:16:58 -06:00
rift
c771252e78 SiteSupport.json for automatic mode 2023-12-26 21:44:15 -06:00
rift
2b1e62c830 The hackiest workaround in the history of hacky workarounds 2023-12-26 20:14:33 -06:00
rift
1865161d73 Revert "Basic search engine shit"
This reverts commit 6372debdff.
2023-12-26 17:59:08 -06:00
rift
950c60ba62 Revert "Im gonna push before I break anything"
This reverts commit b5b1a2848a.
2023-12-26 17:58:59 -06:00
rift
b5b1a2848a Im gonna push before I break anything 2023-12-26 17:37:57 -06:00
rift
6372debdff Basic search engine shit 2023-12-26 17:12:13 -06:00
rift
b0ed0359a9
Merge pull request #177 from MotorTruck1221/rewrite
Add Iframe
2023-12-26 16:15:28 -06:00
MotorTruck1221
198fb1ea5e Finishing touches 2023-12-26 15:13:01 -07:00
MotorTruck1221
f36e0c328d start command 2023-12-26 15:00:19 -07:00
MotorTruck1221
935f029485 Add exit button 2023-12-26 14:59:32 -07:00
MotorTruck1221
ad67368a45 Prettier Format 2023-12-26 03:51:37 -07:00
MotorTruck1221
3a9024d1e0 Add embed option and component
Other fixes: tiles in proxy page for settings, updated search function, fixed defaults
2023-12-26 03:38:24 -07:00
rift
6235ebfe24
Merge pull request #176 from flufferyomada/rewrite
Add: German, Dutch, and Greek translation Locales
2023-12-24 20:03:56 -06:00
Fluffery
e56d7d678d
Update de.json
Nebula -> Nebel 
German translation for Nebula
2023-12-25 01:52:57 +00:00
Fluffery
83e67be465
Create gr.json 2023-12-25 01:49:08 +00:00
Fluffery
6a84dac2f8
Update es.json 2023-12-25 01:11:26 +00:00
Fluffery
a1a0d22524
Update ja.json 2023-12-25 01:11:13 +00:00
Fluffery
0e995129e4
Update en.json 2023-12-25 01:10:51 +00:00
Fluffery
34bfa8bbfc
Update de.json 2023-12-25 01:09:13 +00:00
Fluffery
34acb03fb6
Update de.json
forgot this,
this isn't links because Links in german means Left not URL 
made it URL-Address
2023-12-25 01:08:11 +00:00
Fluffery
05d56020f0
Create de.json
i probs fucked up german articles but like :woozy:
2023-12-25 01:01:08 +00:00
rift
f11c377294 proxyframe dev (WIP) 2023-12-22 16:55:43 -06:00
rift
5f27a4bc92 add open in settings (no functionality) 2023-12-22 16:07:45 -06:00
rift
e029578798
Merge pull request #173 from cohenerickson/rewrite
Spanish translations & move some files around
2023-12-22 15:44:39 -06:00
Cohen Erickson
d16d842fa3 Add spanish translations 2023-12-22 15:29:32 -06:00
Cohen Erickson
20feb65b80 Move some things around to be more consistent 2023-12-22 15:15:39 -06:00
Cohen Erickson
da7edfe3e4 gitignore package lock (redundant from pnpm lock) 2023-12-22 15:02:08 -06:00
rift
db2b7a6c2f Add dynamic, finishing basic proxy functionality 2023-12-21 13:04:59 -06:00
rift
6d99559768 Revert "Add Dynamic Support"
This reverts commit e74459ecb9.
2023-12-21 11:43:40 -06:00
rift
0738ec8547
Merge pull request #172 from Notplayingallday383/rewrite
Add Dynamic Support
2023-12-21 11:27:45 -06:00
John
e74459ecb9
Add Dynamic Support 2023-12-21 12:23:50 -05:00
rift
c28d823d7c Submission validation 2023-12-21 10:53:46 -06:00
rift
d72028ce78 Fix name UV config is not defined 2023-12-21 10:30:49 -06:00
rift
5270ad40ab Add ultraviolet 2023-12-21 10:24:16 -06:00
rift
ae499f760c adjust UV scope 2023-12-21 09:39:49 -06:00
rift
c7dde37754
Merge pull request #171 from MotorTruck1221/rewrite
Fixes
2023-12-21 09:15:16 -06:00
MotorTruck1221
4f67411488 Fixes
This fixes the service worker not registering, and the config for UV
2023-12-21 01:22:57 -07:00
rift
e1064e82ad Merge branch 'rewrite' of https://github.com/NebulaServices/Nebula into rewrite 2023-12-20 22:25:08 -06:00
rift
765f27f4f3 footer 2023-12-20 22:20:13 -06:00
rift
b499f73db6 simple form submission 2023-12-20 21:59:51 -06:00
rift
aa095c4cac
Create README.md 2023-12-20 21:31:24 -06:00
rift
4f13c42b6e FEAT: ADD RAMMER(HELL)HEAD 2023-12-20 21:26:58 -06:00
Riftriot
af18beb134 Set up backend 2023-12-20 14:02:34 -06:00
rift
83fb885e8b More settings styles 2023-12-17 21:06:08 -06:00
rift
a8ed8e55c2 Dropdown styling and init react helmet 2023-12-17 17:57:17 -06:00
rift
4e03679c70 Dropdown style improvements 2023-12-17 15:00:59 -06:00
rift
e8dc26de91 WIP: Dropdown css 2023-12-17 12:03:26 -06:00
rift
9e2b7993a8 language switcher 2023-12-17 11:40:41 -06:00
rift
0f7297aa70 Translation support for dropdown.tsx component 2023-12-16 14:13:04 -06:00
rift
fe85a1c33a
Merge pull request #168 from FireStreaker2/rewrite
dropdown
2023-12-16 12:09:05 -06:00
FireStreaker2
2358e327b4 dropdown 2023-12-16 10:02:11 -08:00
rift
90a858d1e3 feat: framer motion settings 2023-12-15 21:36:00 -06:00
rift
83f1083d75 Set up ProxyFrame.tsx for later use 2023-12-15 19:00:06 -06:00
rift
8a26062442 Add input expand animation and fix Japanese header on mobile 2023-12-15 17:17:52 -06:00
rift
83d85a037e
Merge pull request #166 from cohenerickson/rewrite
Reset UV naming & route specific headers
2023-12-15 09:44:42 -06:00
cohenerickson
6c5a0f33ae Header/Headerless routes 2023-12-15 09:35:42 -06:00
rift
9ddc933d7e
Merge pull request #165 from FireStreaker2/rewrite
mobile navbar support
2023-12-14 23:33:12 -06:00
FireStreaker2
50b1050b20 mobile navbar support 2023-12-14 21:19:19 -08:00
cohenerickson
396e1f7233 change to traditional UV file naming 2023-12-14 17:25:35 -06:00
Riftriot
07b205ee31 clean up discord import 2023-12-14 14:22:44 -06:00
rift
186d24b1b1
Merge pull request #164 from cohenerickson/rewrite
Fix prettier and reconfigure UV with npm package
2023-12-14 12:15:06 -06:00
cohenerickson
118c3d8949 configure UV & bare 2023-12-14 10:13:05 -06:00
cohenerickson
4aae71dbdb Basic vscode settings to make development more efficient 2023-12-14 08:51:59 -06:00
cohenerickson
2fe742f3f0 run npm run format 2023-12-14 08:45:54 -06:00
cohenerickson
99b08aff08 delete ultraviolet files 2023-12-14 08:45:23 -06:00
cohenerickson
6a76eee11f Fix prettier config & dependencies 2023-12-14 08:44:24 -06:00
rift
ea8bcdfc72
Merge pull request #161 from FireStreaker2/rewrite
hover effect
2023-12-13 20:55:16 -06:00
FireStreaker2
2f86f1c004 hover effect 2023-12-13 18:51:07 -08:00
rift
25c4a1e9ce Major header and routing improvments 2023-12-13 19:38:01 -06:00
rift
226560dc52 fix incosistensy in Japanese header (..i think?) 2023-12-13 17:40:01 -06:00
rift
9f89ba3c48 Fix japanese ver of header and add translations for the discord page 2023-12-13 17:28:10 -06:00
rift
aa2edd9ab6
Merge pull request #159 from Notplayingallday383/v8-dev
Add Links and a simple Discord page
2023-12-13 17:14:15 -06:00
John
910e20575d Gonna work on TB anyways init UV 2023-12-13 16:19:29 -05:00
John
0ff7c2c385 Simple Discord Page 2023-12-13 16:03:09 -05:00
John
d8c3eb8380 Add Links 2023-12-13 15:45:53 -05:00
illusionTBA
0e113e57e3 import EN -> en 2023-12-13 15:25:47 -05:00
rift
cb8d6ff7c5 I forgot what I changed 2023-12-12 19:45:35 -06:00
rift
d98d988b7b Input and fix font / TODO: Input placeholder translation 2023-12-12 18:01:16 -06:00
rift
533376a592 Japanese translations for header (probably incorrect) 2023-12-11 17:34:18 -06:00
rift
57c7cda58b header 2023-12-10 21:19:24 -06:00
rift
bb68711a48 this timer is stupud im not doing it 2023-12-10 19:44:18 -06:00
rift
ddfb2ec900 working clock 2023-12-10 19:36:45 -06:00
rift
71d65f2cda Hell (working) 2023-12-10 19:01:34 -06:00
rift
8a7b7d69a7 raaah get basic css done 2023-12-10 17:41:54 -06:00
rift
9256abebb1 inital commit 2023-12-10 13:22:17 -06:00
Green!
7c4c9bcfa5
Merge pull request #133 from NebulaServices/dependabot/npm_and_yarn/semver-6.3.1
Bump semver from 6.3.0 to 6.3.1
2023-08-21 10:18:43 -04:00
Green!
7540494cb2
Merge pull request #135 from Greenlio/patch-1
CVE-2022-2309
2023-07-25 12:47:22 -04:00
Gavin
a448293c61
CVE-2022-2309
fixes old node version which is vulnerable to https://www.cve.org/CVERecord?id=CVE-2022-2309

Introduced through: node@18 -> libxml2@2.9.14+dfsg-1.2
Fix: Upgrade to libxml2@2.9.14+dfsg-1.3~deb12u1 <- node:20.4-bookworm-slim
2023-07-25 03:58:10 -05:00
Green!
1866eec91a
Merge pull request #134 from Nailington/patch-1
Update package.json
2023-07-15 22:30:31 -04:00
Nailington
526e781823
Update package.json
Node version is now 18 or greater
2023-07-15 19:20:06 -04:00
dependabot[bot]
679ee2f17e
Bump semver from 6.3.0 to 6.3.1
Bumps [semver](https://github.com/npm/node-semver) from 6.3.0 to 6.3.1.
- [Release notes](https://github.com/npm/node-semver/releases)
- [Changelog](https://github.com/npm/node-semver/blob/v6.3.1/CHANGELOG.md)
- [Commits](https://github.com/npm/node-semver/compare/v6.3.0...v6.3.1)

---
updated-dependencies:
- dependency-name: semver
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-12 22:50:45 +00:00
Cohen Erickson
b81147ed0c
Merge pull request #124 from NebulaServices/snyk-upgrade-94873d6c3459d975e729e89fc45f2400 2023-06-08 00:00:33 -05:00
snyk-bot
0e97d0bba1
fix: upgrade nodemailer from 6.9.1 to 6.9.2
Snyk has created this PR to upgrade nodemailer from 6.9.1 to 6.9.2.

See this package in npm:
https://www.npmjs.com/package/nodemailer

See this project in Snyk:
https://app.snyk.io/org/greenydev/project/d2cc9035-af19-487f-bbb7-3d864ce3a3c3?utm_source=github&utm_medium=referral&page=upgrade-pr
2023-06-02 01:17:06 +00:00
142 changed files with 14019 additions and 6098 deletions

12
.changeset/config.json Normal file
View file

@ -0,0 +1,12 @@
{
"$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json",
"changelog": ["@changesets/changelog-github", { "repo": "nebulaservices/nebula" }],
"commit": false,
"fixed": [],
"linked": [],
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": [],
"privatePackages": { "version": true, "tag": true }
}

View file

@ -1,12 +0,0 @@
FROM node:18
# Install basic development tools
RUN apt update && apt install -y less man-db sudo
# Ensure default `node` user has access to `sudo`
ARG USERNAME=node
RUN echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
&& chmod 0440 /etc/sudoers.d/$USERNAME
# Set `DEVCONTAINER` environment variable to help with orientation
ENV DEVCONTAINER=true

View file

@ -1,9 +0,0 @@
// See https://containers.dev/implementors/json_reference/ for configuration reference
{
"name": "Nebula",
"build": {
"dockerfile": "Dockerfile"
},
"remoteUser": "node",
"postCreateCommand": "npm install"
}

17
.dockerignore Normal file
View file

@ -0,0 +1,17 @@
node_modules/
.vscode
npm-debug.log
yarn-error.log
.github/
.env.example
.env
dist/
.git/
.astro/
~/
.gitignore
biome.json
docker-compose.yml
Dockerfile
README.md
db/

4
.github/FUNDING.yml vendored
View file

@ -1,4 +0,0 @@
# These are supported funding model platforms
patreon: nebuladevs
ko_fi: nebulaa

View file

@ -1,11 +0,0 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "weekly"

50
.github/workflows/docker.yml vendored Normal file
View file

@ -0,0 +1,50 @@
name: Build Docker image
on:
push:
tags:
- v*
workflow_dispatch:
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-push:
name: Build and push Docker image to registry
runs-on: ubuntu-latest
if: github.repository_owner == 'nebulaservices'
permissions:
contents: write
packages: write
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
submodules: true
- name: Setup docker buildx
uses: docker/setup-buildx-action@v3
- name: Login To registry ${{ env.REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ github.token }}
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v3
with:
images: ${{ env.REGISTRY }}/nebulaservice/nebula
- name: Build and push
id: build-and-push
uses: docker/build-push-action@v4
with:
context: .
platforms: linux/amd64,linux/arm64
file: ./Dockerfile
name: nebula
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max

50
.github/workflows/release.yml vendored Normal file
View file

@ -0,0 +1,50 @@
name: Release
on:
push:
branches:
- main
workflow_dispatch:
defaults:
run:
shell: bash
env:
FORCE_COLOR: true
jobs:
changelog:
name: Release TAG
if: ${{ github.repository_owner == 'nebulaservices' }}
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write
steps:
- uses: actions/checkout@v4
- name: Setup PNPM
uses: pnpm/action-setup@v3
with:
version: 9.1.1
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 18
cache: "pnpm"
- name: Install dependencies
run: pnpm install --no-frozen-lockfile
- name: Create Release Pull Request or Publish
id: changesets
uses: changesets/action@v1
with:
version: pnpm run version
publish: pnpm exec changeset publish
commit: "[ci] release"
title: "[ci] release"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

45
.gitignore vendored
View file

@ -1,10 +1,43 @@
# build output
dist/
server/*.js
# generated types
.astro/
# dependencies
/node_modules
node_modules/
package-lock.json
# System Files
#external assets
database_assets/*
!database_assets/com.nebula.gruvbox/
!database_assets/com.nebula.lightTheme/
!database_assets/com.nebula.oled/
!database_assets/com.nebula.retro/
# logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# environment variables
.env
.env.production
# macOS-specific files
.DS_Store
Thumbs.db
.breakpoints
memory.txt
old.app.js
# jetbrains setting folder
.idea/
# nebula catalog database
database.sqlite
# YOUR config
config.toml
# Goofy PNPM problem
~/

3
.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "workerware"]
path = workerware
url = https://github.com/mercuryworkshop/workerware

View file

@ -1 +0,0 @@
node_modules

View file

@ -1,6 +0,0 @@
{
"tabWidth": 2,
"useTabs": false,
"singleQuote": false,
"trailingComma": "none"
}

4
.vscode/extensions.json vendored Normal file
View file

@ -0,0 +1,4 @@
{
"recommendations": ["astro-build.astro-vscode"],
"unwantedRecommendations": []
}

11
.vscode/launch.json vendored Normal file
View file

@ -0,0 +1,11 @@
{
"version": "0.2.0",
"configurations": [
{
"command": "./node_modules/.bin/astro dev",
"name": "Development server",
"request": "launch",
"type": "node-terminal"
}
]
}

10
.vscode/settings.json vendored
View file

@ -1,10 +0,0 @@
{
"editor.tabSize": 2,
"editor.insertSpaces": true,
"editor.formatOnSave": true,
"editor.formatOnPaste": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[javascript]": {
"editor.defaultFormatter": "vscode.typescript-language-features"
}
}

36
CHANGELOG.md Normal file
View file

@ -0,0 +1,36 @@
# v9.0.0
- The first release of Nebula V9! And with it bring a whole host of changes:
- More stable the V8
- Adds a Marketplace where users can create their own themes & plugins
- Switches to Astro for speed
- Other general bug fixes
# v9.0.1
- Bumps dependencies
- Fixes bugs
# 9.0.2
- Adds the ability for a custom wisp server back
- Increases upload fileSize capacity in hopes that bigger files can now be uploaded
# 9.0.3
- Bugfix: themes with caps don't uninstall - fixed
- Rewrite: InstalledThemes and InstalledPlugins are now in Astro instead of Svelte
# 9.0.4
- General Bugfixes
- Removes Svelte except for 2 componenents
- Scramjet :rocket:
# 9.1.0
- Rewrites everything in the [utils/](./src/utils) folder
- Bugfixes
- Better logging
- Mobile nav jank is gone
- Component cleanup

View file

@ -1,7 +1,19 @@
FROM node:18
WORKDIR /usr/src/app
FROM node:22-alpine
WORKDIR /app
COPY package*.json .
COPY . .
RUN npm install
RUN npm ci
EXPOSE 3000
CMD ["npm", "start"]
RUN apk update
RUN apk add python3 py3-pip alpine-sdk openssl-dev build-base python3-dev
RUN python3 -m pip install setuptools --break-system-packages
RUN cp -n config.example.toml config.toml
RUN npm i -g pnpm
RUN pnpm install
RUN pnpm run build
RUN export TERM=xterm-256color
VOLUME /app
EXPOSE 8080
ENTRYPOINT ["pnpm"]
CMD ["start", "--color"]

View file

@ -1,7 +1,7 @@
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
Copyright (C) 2022 Nebula Services
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@ -658,4 +658,4 @@ specific requirements.
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
<https://www.gnu.org/licenses/>.
<https://www.gnu.org/licenses/>.

537
README.md
View file

@ -1,214 +1,371 @@
# Nebula
<div align="center">
<img src="https://socialify.git.ci/nebulaservices/nebula/image?description=1&font=Inter&forks=1&issues=1&language=1&name=1&owner=1&pattern=Circuit%20Board&pulls=1&stargazers=1&theme=Dark" alt="ruby" width="640" height="320" />
NebulaWeb is an official flagship of Nebula Services and Nebula Developer Labs. NebulaWeb is a stunning, sleek, and functional web-proxy with support for thousands of popular sites. With NebulaWeb, the sky is the limit.
<img alt="repo size" src="https://img.shields.io/github/repo-size/nebulaservices/nebula?style=for-the-badge"></img>
<img alt="website status" src="https://img.shields.io/website?url=https%3A%2F%2Fnebulaproxy.io&style=for-the-badge"></img>
<img alt="commit a week" src="https://img.shields.io/github/commit-activity/w/nebulaservices/nebula?style=for-the-badge"></img>
Quick note: If you are a system administrator, and have questions, our email is always open `chloe@nebulaproxy.io`
</div>
<div align="center">
<h2>Get Started</h2>
<a>To get started, press one of the buttons below to deploy Nebula</a>
<br />
<br />
<a href="#terminal">
<img src="https://img.shields.io/badge/terminal-%23121011.svg?style=for-the-badge&logo=gnu-bash&logoColor=white" alt="Terminal">
</img>
</a>
<a href="#docker">
<img src="https://img.shields.io/badge/docker-%230db7ed.svg?style=for-the-badge&logo=docker&logoColor=white" alt="Docker">
</img>
</a>
</div>
## NOTE:
![license](https://img.shields.io/badge/License-GNU%20AGPL%20v3-blue)
- This will **NOT** deploy on GitHub Pages, Netlify, Vercel, Gitlab Pages, or any other _static_ host
- This will **NOT** work on Render
---
![chat](https://img.shields.io/badge/chat-1139%20online-brightgreen)
## How to get links
[![Nebula Services Discord](https://invidget.switchblade.xyz/unblocker?theme=darl)](https://discord.gg/unblocker)
[![Titanium Network Discord](https://invidget.switchblade.xyz/unblock?theme=dark)](https://discord.gg/unblock)
---
## Features
- Stunning and highly functional UI with multiple themes
- XOR/b64 encoding all traffic
- Hides your IP from sites
- [List of officially supported sites](https://github.com/NebulaServices/Nebula/blob/dev/docs/officially-supported-sites.md)
- _limited_ mobile support
- Stealth Mode (buffed `about:blank` cloaking)
- **NEW** Clickoff cloaking
- **NEW** Email OTP verification
# Deployment
Table of contents
- Quick & easy deployment
- Deployment configuration explaination
- how to use email OTP Verification mode
- Advanced Deployment
- Filesystem
## Quick & Easy Deployment Options
## PLEASE READ THIS NOTICE: IF YOU ARE USING NODE VERSION 20 (HEROKU, RAILWAY), YOU WILL NEED TO TEMPORARILY DOWNGRADE TO 19 OR EARLIER.
[![Deploy to IBM Cloud](https://raw.githubusercontent.com/BinBashBanana/deploy-buttons/master/buttons/remade/ibmcloud.svg)](https://cloud.ibm.com/devops/setup/deploy?repository=https://github.com/NebulaServices/Nebula)
<br>
[![Deploy to Amplify Console](https://raw.githubusercontent.com/BinBashBanana/deploy-buttons/master/buttons/remade/amplifyconsole.svg)](https://console.aws.amazon.com/amplify/home#/deploy?repo=https://github.com/NebulaServices/Nebula)
<br>
[![Run on Google Cloud](https://raw.githubusercontent.com/BinBashBanana/deploy-buttons/master/buttons/remade/googlecloud.svg)](https://deploy.cloud.run/?git_repo=https://github.com/NebulaServices/Nebula)
<br>
[![Deploy on Railway](https://binbashbanana.github.io/deploy-buttons/buttons/remade/railway.svg)](https://railway.app/new/template/pBzeiN)
<br>
[![Deploy To Koyeb](https://binbashbanana.github.io/deploy-buttons/buttons/remade/koyeb.svg)](https://app.koyeb.com/deploy?type=git&repository=github.com/NebulaServices/Nebula&branch=main&name=NebulaProxy)
- Multiple Proxy "Backends":
- [Ultraviolet](https://github.com/titaniumnetwork-dev/ultraviolet)
- [RammerHead](https://github.com/binary-person/rammerhead)
---
## Deployment Configuration Guide
(Example configuration with none-json notes)
```json
{
"sendgrid_verification": false,
"sendgrid_options": {
"api_key": "YOUR_SENDGRID_API_KEY",
"sendFromEmail": "THE EMAIL THE CODES WILL BE SENT FROM (MUST BE VERIFIED IN SENDGRID)",
"to_email": "THE EMAIL YOU WANT THE CODES SENT TO"
},
"discord_verification": false,
"webhook_url": "YOUR DISCORD WEBHOOK URL",
"smtp_verification": false,
"smtp_options": {
"to_email": "THE EMAIL YOU WANT THE CODES SENT TO",
"sendFromEmail": "THE EMAIL THE CODES ARE SENT FROM",
"host": "YOUR SMTP HOST",
"port": 465,
"auth": {
"user": "SMTP USER",
"pass": "YOUR PASSWORD"
}
}
}
```
## Email Verification OTP
### What is this?
Email verification is a new and unique feature that we've implemented in the event that someone wants to keep their deployment of Nebula private and secure.
### What does it do
When a user tries to access the website, before allowed access they will be asked for a One time password sent to an email set in the deployment configuration. Once verified, they will have 15 day access to the site.
#### SendGrid Setup Instructions
- Firstly, We need to enable verification within the deployment configuration
- change `"sendgrid_verification":false,` to `"sendgrid_verification":true,` above the SendGrid Section
- _Note: You have to reboot the node app for any changes to take place._
- Now, we need to use an api to send a message
- Make an account at Sendgrid (https://app.sendgrid.com/)
- _Note: It is likely that other versions of Nebula will use a different package to send emails._
- Verify the email you want to recieve emails from (Create a sender identity)
- Go to settings -> Sender authentication and click Verify a Single Sender
- Now, We need to get the API key to connect to the API
- Go to settings -> API Keys -> and make an API key.
- Complete the information in the deployment config `deployment.config.json` under the `sendgrid_options` section such as: sendFromEmail, to_email and api_key
#### Discord Webhook Setup Instructions
- Set discord_verification to true in the deployment configuration.
- Create a channel in a discord server you have admin in.
- Click the Edit Channel button.
- Click Integrations
- Click create web hook and copy the URL.
- Paste it under the `webhook_url` section in the deployment configuration.
#### SMTP Setup Instructions
- Set `smtp_verification` to true.
- Change `to_email` to the email address you want the codes to be sent to.
- Change `sendFromEmail to the email address that is going to send the codes.
- Get the host and port from your email provider's documentation.
- Fill in your username and password under the `user` and `pass` section under auth.
## Advanced Deployment
### Initial configuration
credits to @ProgrammerIn-wonderland for writing this wonderful tutorial (which can also be found in the docs :)
- Create an account at https://www.cloudflare.com/
- Create an account at https://www.freenom.com/ (or any registrars)
- Find a free domain name at Freenom
- Click checkout
- Select (12 Months @ FREE)
- Select "Use DNS"
- Select Use your own DNS
- Go to cloudflare, click add new site, and enter the free domain name
- Select "Free Plan"
- Click continue, ignore DNS
- Copy the name servers cloudflare gives you
- Go back to your Freenom tab, enter in the name servers which cloudflare gave you
- You can keep IP blank
- Click continue
- Click complete order
- Go back to cloudflare tab, click "Check Nameservers"
- Select DNS on your right bar
- Enter in the IP of the server which will be hosting Nebula
- Target will be `@`
- Click Enable proxy (little gray cloud icon, if active its orange)
- Select SSL/TLS in your right bar
- Click "Flexible"
## Contributors
- [Rifting](https://github.com/rifting) - Owner & Maintainer
- [MotorTruck1221](https://motortruck1221.com) - Maintainer
---
### Server configuration
- SSH into the server you'll be using, I'll assume its running Ubuntu 22.04 (though the commands are the same for debian 10+ versions, and Ubuntu versions 20.04+)
- run
```
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - \ &&
sudo apt-get install -y nodejs npm
git clone https://github.com/NebulaServices/Nebula.git
cd Nebula
npm i
npm ci
sudo nohup PORT=80 node . &
```
**Make sure your firewall is configured to let through port 80 traffic!** \
_Note: Server will need to run` cd Nebula && sudo nohup PORT=80 node . &` on reboot_
## File Structure
| **File** | Purpose | |
| -------------------------------- | -------------------------------------------------------------------------------------------------------- | --- |
| `src/index.html` | The main frontend visuals for NebulaWEB. | |
| `src/unv.html` | The verification-required frontend/visuals. | |
| `src/options.html` | The frontend for Nebula's options, settings, and preferences. | |
| `public/resources/v.js` | Client verification system for the OTP system. | |
| `public/resources/nebulamain.js` | All of the DOM/client code for NebulaWEB. Includes options, themeSystem, cloak, stealthengine, and more. | |
| `app.js` | The backend server for Nebula. Contains Nodestatic, Bare, HTTP, and more. | |
## Tech Stack
- HTML, JS, CSS
- Partical.JS (Specifically v4, 5, 6.1 &< only)
- Ultraviolet (proxy)
- Osana (proxy)
- TompHTTP Bare Server Node
- ExpressJS
- [Astro](https://astro.build)
- [Fastify](https://fastify.dev)
- [Ultraviolet](https://github.com/titaniumnetwork-dev/ultraviolet)
- [RammerHead](https://github.com/binary-person/rammerhead)
- [Epoxy](https://github.com/mercuryworkshop/epoxy-tls)
- [Libcurl.js](https://github.com/ading2210/libcurl.js)
- HTML, CSS, and JavaScript (DUH)
---
## Support
## Catalog/Marketplace
For support, email chloe@nebula.bio or join our discord: discord.gg/unblocker
- By default, the marketplace is enabled and uses SQLite
- If you would like to disable the catalog, see [#config](#config)
- For big production instances, I recommend using PostgreSQL rather than SQLite. To do this see [#config](#config)
- To use PostgreSQL via the provided docker-compose files, see [#docker](#docker)
## Demo
### How to make a theme
[Click here to see a demo of Nebula](https://nebulaproxy.io/)
- Themes allow you to customize Nebula's *look*.
## Acknowledgements
#### Prerequisites:
- Make sure you have our [Discord server](https://discord.gg/unblocker) so you can submit your theme
- [UV (one of the proxies use)](https://github.com/titaniumnetwork-dev/Ultraviolet)
- [Osana (one of the proxies we use)](https://github.com/NebulaServices/Osana)
- [Bare Server Node](https://github.com/tomphttp/bare-server-node)
- [Partical.JS (v4, 5, 6.1 &< only)](https://github.com/VincentGarreau/particles.js)
##### Making the themes:
## License
1. Firstly, copy the CSS vars:
```css
:root {
--background-primary: /*Your stuff here */;
--background-lighter: ;
--navbar-color: ;
--navbar-text-color: ;
--navbar-link-color: ;
--navbar-link-hover-color: ;
--input-text-color: ;
--input-placeholder-color: ;
--input-background-color: ;
--input-border-color: ;
--tab-color: ;
--border-color: ;
}
```
(Nebula's license is now GNU AGPL V3 as of v7.10)
Copyright Nebula Services 2021 - Present
<br>
This project uses the AGLP GNU V3 license.
> [!NOTE]
>
> You can add a custom font as well! To do so, add this to your `:root`
>
> ```css
> --font-family: /* Font family name */;
> ```
>
> And this to the bottom of your CSS file/submission:
> ```css
> @font-face {
> font-family: /* Name */;
> src: url(/* Where the font is located! Local or external work! */);
> }
> ```
>
> A good example of using a custom font is the built-in `retro` theme [here](./database_assets/com.nebula.retro)
2. Add your colors and test! (Either with a self-hosted version of Nebula OR via a live preview (no clue when this will happen)
3. Once you're satisfied with the colors, submit your theme to the [Discord Server](https://discord.gg/unblocker)!
---
### How to make a plugin
- Plugins extend the functionality of either the proxied page(s) or the service worker.
- This guide provides an incredibly basic example of how to make either.
#### Prerequisites:
- Make sure you have joined our [Discord server](https://discord.gg/unblocker) so you can submit your plugin.
- Some knowledge of JS/TS
##### Serviceworker plugin:
- These plugins are handled by Workerware see [here](https://github.com/mercuryworkshop/workerware) for docs.
1. Create an index.js (or other file name) file:
```bash
touch index.js
```
2. Edit that file to include either of these:
- Code encased in a string:
```js
function setup() {
// This function MUST return the following attributes:
return {
function: `console.log('Example code.')`,
name: 'com.example', // Technically, it could be named anything. It is recommended to use the same name for everything (name when submitting and this)
events: ['fetch'] // See: https://github.com/mercuryworkshop/workerware for the event types you can use. (Also typed if you are using typescript)
}
}
//This can be named anything. However, it's recommended to use `entryFunc` (with types, the naming IS enforced)
self.entryFunc = setup; //DO NOT call the function here. Only assign the reference otherwise, it will error.
```
- Code in an arrow function:
```js
const example = () => {
console.log('Example code')
}
function setup() {
//This function MUST return the following attributes:
return {
function: example, //Do not call the function, only assign the reference to the function.
name: 'com.example', // Technicall could be name anything. Recommended to use the same name for everything (name when submitting and this)
event: ['fetch'] // Se https://github.com/mercuryworkshop/workerware for the event types you can use. (Also typed if using typescript)
}
}
//This can be named anything. However, it's recommended to use `entryFunc` (with types, the naming IS enforced)
self.entryFunc = setup; //DO NOT call the function here. Only assign the reference; otherwise, it will result in an error.
```
> [!WARNING]
> The only *allowed* way to pass code to the `function` param is either a string or an arrow function. Named functions ***WILL NOT WORK***.
>
> Example of a named function: `function example() {/* Some form of code */}`.
>
> If a named function is used where it shouldn't be, your plugin will not be approved, nor will it work properly.
3. Submit your plugin in the [Discord](https://discord.gg/unblocker)!
##### Proxied page plugins
- They allow modification of websites that UV proxies, (EX: you could add Vencord to Discord with this)
1. Create an index.js file (or another file name)
```bash
touch index.js
```
2. Edit that file with your code and the following:
```js
//Name this whatever.
function example() {
//You MUST return the following
return {
host: "example.com", //The host to match (so if the user visits example.com it will inject the html below.
html: "<script>console.log('Example')</script>", //Must return a string (and be valid HTML or your plugin will break). How you get that string is up to you
injectTo: "head" // Can be "head" or "body"
}
}
// Technically, this could be named anything, it is recommended to call it `entryFunc`
self.entryFunc = example; //DO NOT run the function here. That will cause errors. Only assign the reference to the function here.
```
3. Submit it in our [Discord](https://discord.gg/unblocker)!
---
## Deployment
### Terminal
Prerequisites:
- Node & npm
- Git
1. Clone the repo:
```bash
git clone https://github.com/nebulaservices/nebula --recursive && cd nebula
```
2. Install all of the dependencies:
```bash
npm i
```
3. Create a `config.toml` file
```bash
cp config.example.toml config.toml
```
4. Modify the `config.toml` file to your liking (docs [here](#environment))
```
nano config.toml
```
5. Build the front end & server:
```bash
npm run build
```
6. Start the server
```bash
npm start
```
> [!NOTE]
> You can run `npm run bstart` to build and start together
---
### Docker
- There are two ways to deploy with docker:
- [Normal docker](#normal-docker)
- [Docker Compose](#docker-compose)
#### Normal Docker
Prerequisites:
- Git
- Docker
1. Clone the repo (skip if using a prebuilt image):
```bash
git clone https://github.com/nebulaservices/nebula --recursive && cd nebula
```
2. Create an `config.toml` file (if using prebuilt image, copy the example from the repo):
```bash
cp config.example.toml config.toml
```
3. Modify the `config.toml` file to your liking (docs [here](#environment))
```bash
nano config.toml
```
4. Build the docker image (skip if using prebuilt):
```bash
docker build nebula:latest
```
5. Run the docker images:
- Prebuilt:
```bash
docker run -v ./config.toml:/app/config.toml ghcr.io/nebulaservices/nebula:latest
```
- Image you built yourself:
```bash
docker run -v ./config.toml:/app/config.toml nebula:latest
```
#### Docker Compose
Prerequisites:
- Git
- Docker w/compose
1. Clone the repo (skip if using a prebuilt image):
```bash
git clone https://github.com/nebulaservices/nebula --recursive
```
2. Create an `config.toml` file (if using prebuilt image, copy the example from the repo):
```bash
cp config.example.toml config.toml
```
3. Modify the `config.toml` file to your liking (docs on that [here](#environment)]
```bash
nano config.toml
```
4. Build the docker image (skip if using prebuilt):
```bash
docker compose -f ./docker-compose.build.yml build
```
5. Run the docker image:
- Prebuilt:
```bash
docker compose up
```
- Image you built yourself:
```bash
docker compose -f ./docker-compose.build.yml up
```
#### Extra (Postgres)
- To use Postgres over SQLite, uncomment the DB section in the `docker-compose` file (or use your own Postgres DB!). Then, modify the `config.toml` (See: [#config](#config) for knowledge on how to do this)
- To use Postgres over SQLite in a normal docker environment (no compose), you'll have to set one up and then modify the `config.toml` to use it. (See: [#config](#config) for knowledge on how to do this)
---
## Config
There are a couple of configuration options for Nebula. The defaults are fine most of the time, but there are instances where you may not want certain options enabled or certain things running.
- An example config file is located [here](./config.example.toml).
- Config format is in TOML
| Variable | Description | Type | Default |
|:----------:|:-------------:|:------:|:---------:|
| `marketplace` | The options below are for the marketplace section | `object` | N/A |
| `enabled` | Enable marketplace functionality | `boolean` | `true` |
| `psk` | The password and authentication key for the marketplace. ***CHANGE FROM DEFAULT*** | `string` | `CHANGEME` |
|----------------------------| ----------------------------------------------------------------------------|------------|--------------|
| `db` | The below options are for the db (database) section | `object` | N/A |
| `name` | The database name to use | `string` | `database` |
| `username` | The username for the DB | `string` | `username` |
| `password` | The database password. ***CHANGE FROM DEFAULT VALUE*** | `string` | `password` |
| `postgres` | Whether to use postgres over sqlite *(recommended for large production instances)* | `boolean` | `false` |
|----------------------------| ----------------------------------------------------------------------------|------------|--------------|
| `postgres` | The below options are for the postgres section. (Only worry about this if you enabled postgres in the db section.) | `object` | N/A |
| `domain` | Either the TLD or the IP address of your postgres server. | `string` | `''` |
| `port` | The port your postgres server is listening on | `number` | `5432` |
|----------------------------| ----------------------------------------------------------------------------|------------|--------------|
| `server.server` | The below options are to configure the server. | `object` | N/A |
| `port` | What port the server should listen on. *(Note: Can also be configured via environment variable `PORT`)* | `number` | `8080` |
| `wisp` | Whether the server should use the inbuilt wisp server. (Disabled if your using an external wisp server) | `boolean` | `true` |
| `logging` | Whether or not to enable logging. *Note: Logs are massive* | `boolean` | `true` |
|----------------------------| ----------------------------------------------------------------------------|------------|--------------|
## Deploying
### Koyeb
- First setup the config.toml file with the docker-compose instructions!
- Fork this repo
- Create new koyeb service, and select webservice
- Select import from github and import your forked repo
- Change package to dockerfile and press deploy!

249
app.js
View file

@ -1,249 +0,0 @@
import express from "express";
import cookieParser from "cookie-parser";
import http from "node:http";
import createBareServer from "@tomphttp/bare-server-node";
import { uvPath } from "@titaniumnetwork-dev/ultraviolet";
import path from "node:path";
import config from "./deployment.config.json" assert { type: "json" };
import sgMail from "@sendgrid/mail";
import nodemailer from "nodemailer";
import * as uuid from "uuid";
import fs from "node:fs";
import bcrypt from "bcrypt";
// fx
const PORT = process.env.PORT || 3000;
const __dirname = process.cwd();
const ACTIVE_CODES = new Set();
if (!fs.existsSync("./tmp/memory.txt")) {
fs.writeFileSync("./tmp/memory.txt", "", "utf-8");
}
let TOKENS = fs
.readFileSync("./tmp/memory.txt", "utf-8")
.trim()
.split("\n")
.map((token) => {
const parts = token.split(":");
return {
id: parts[0],
token: parts[1],
expiration: parts[2]
};
});
const server = http.createServer();
const app = express(server);
const bareServer = createBareServer("/bare/");
// Middleware
app.use(cookieParser());
app.use(express.json());
app.use(
express.urlencoded({
extended: true
})
);
// Verification
app.patch("/generate-otp", async (req, res) => {
if (
config.sendgrid_verification ||
config.discord_verification ||
config.smtp_verificaton
) {
const OTP = generateCode();
ACTIVE_CODES.add(OTP);
setTimeout(() => {
ACTIVE_CODES.delete(OTP);
}, 1000 * 60 * 5);
let email = {
to: "",
from: "",
subject: `NebulaWEB personal access code ${OTP}`,
text: `
####### ACCESS CODE (OTP) ${OTP} #######
####### DO NOT SHARE THIS CODE! #######
(this message is automated)`
};
if (config.sendgrid_verification) {
sgMail.setApiKey(config.sendgrid_options.api_key);
email.to = config.sendgrid_options.to_email;
email.from = config.sendgrid_options.sendFromEmail;
try {
await sgMail.send(msg);
} catch {
return res.status(504).end();
}
}
if (config.smtp_verification) {
const smtpMailerAgent = nodemailer.createTransport(config.smtp_options);
email.to = config.smtp_options.to_email;
email.from = config.smtp_options.sendFromEmail;
try {
smtpMailerAgent.sendMail(email);
} catch {
return res.status(504).end();
}
}
if (config.discord_verification) {
try {
await fetch(config.webhook_url, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
content: `Your NebulaWEB access code is \`${OTP}\``
})
});
} catch {
return res.status(500).end();
}
}
res.status(200).end();
} else {
res.status(404).end();
}
});
function generateCode() {
const code = Math.floor(Math.random() * 1000000);
return code.toString().padStart(6, "0");
}
app.post("/validate-otp", (req, res) => {
if (
config.sendgrid_verification ||
config.discord_verification ||
config.smtp_verificaton
) {
const OTP = req.body.otp;
if (ACTIVE_CODES.has(OTP)) {
ACTIVE_CODES.delete(OTP);
const token = uuid.v4();
TOKENS.push({
id: OTP,
token: hash(token),
expiration: Date.now() + 1000 * 60 * 60 * 24 * 30
});
fs.writeFileSync(
"./tmp/memory.txt",
TOKENS.map((token) => {
return `${token.id}:${token.token}:${token.expiration}`;
}).join("\n"),
"utf-8"
);
res.status(200).json({
success: true,
validation: `${OTP}:${token}`
});
} else {
res.status(401).json({
success: false
});
}
} else {
res.status(404).end();
}
});
// Static files
app.use(express.static(path.join(__dirname, "public")));
app.use("/uv/", express.static(uvPath));
// Login route
app.get("/login", (req, res) => {
if (
config.sendgrid_verification ||
config.discord_verification ||
config.smtp_verificaton
) {
res.sendFile(path.join(__dirname, "src", "unv.html"));
} else {
res.redirect("/");
}
});
// General Routes
app.use((req, res, next) => {
if (
config.sendgrid_verification ||
config.discord_verification ||
config.smtp_verificaton
) {
const verification = req.cookies["validation"];
if (!verification || !validateToken(verification)) {
return res.redirect("/login");
}
}
next();
});
app.get("/", (req, res) => {
res.sendFile(path.join(__dirname, "src", "index.html"));
});
app.get("/options", (req, res) => {
res.sendFile(path.join(__dirname, "src", "options.html"));
});
app.get("/privacy", (req, res) => {
res.sendFile(path.join(__dirname, "src", "privacy.html"));
});
// Bare Server
server.on("request", (req, res) => {
if (bareServer.shouldRoute(req)) {
bareServer.routeRequest(req, res);
} else {
app(req, res);
}
});
server.on("upgrade", (req, socket, head) => {
if (bareServer.shouldRoute(req)) {
bareServer.routeUpgrade(req, socket, head);
} else {
socket.end();
}
});
server.on("listening", () => {
console.log(`Server running at http://localhost:${PORT}/.`);
});
server.listen({
port: PORT
});
function hash(token) {
const salt = bcrypt.genSaltSync(10);
return bcrypt.hashSync(token, salt);
}
function validateToken(verification) {
const [id, token] = verification.split(":");
const tokenData = TOKENS.find((token) => token.id == id);
if (!tokenData) {
return false;
}
if (tokenData.expiration < Date.now()) {
return false;
}
return bcrypt.compareSync(token, tokenData.token);
}

View file

@ -1,7 +0,0 @@
{
"name": "NebulaWEB",
"description": "Explore the web. Freely. ",
"repository": "https://github.com/NebulaServices/Nebula",
"logo": "https://avatars.githubusercontent.com/u/86420004?v=4",
"keywords": ["educational", "science", "math"]
}

133
astro.config.ts Normal file
View file

@ -0,0 +1,133 @@
import { fileURLToPath } from "node:url";
import node from "@astrojs/node";
import svelte from "@astrojs/svelte";
import tailwind from "@astrojs/tailwind";
import { baremuxPath } from "@mercuryworkshop/bare-mux/node";
import { epoxyPath } from "@mercuryworkshop/epoxy-transport";
import { libcurlPath } from "@mercuryworkshop/libcurl-transport";
import playformCompress from "@playform/compress";
import { uvPath } from "@titaniumnetwork-dev/ultraviolet";
import { scramjetPath } from "@mercuryworkshop/scramjet";
import icon from "astro-icon";
import { defineConfig, envField } from "astro/config";
import { viteStaticCopy } from "vite-plugin-static-copy";
import { version } from "./package.json";
import { parsedDoc } from "./server/config.js";
const workerwarePath = fileURLToPath(new URL("./workerware/src", import.meta.url));
export default defineConfig({
site: parsedDoc.seo.enabled ? parsedDoc.seo.domain || process.env.SITE : 'http://localhost:4321',
env: {
schema: {
VERSION: envField.string({
context: "client",
access: "public",
optional: true,
default: version
}),
MARKETPLACE_ENABLED: envField.boolean({
context: "client",
access: "public",
optional: true,
default: parsedDoc.marketplace.enabled
}),
SEO: envField.string({
context: "client",
access: "public",
optional: true,
default: JSON.stringify({
enabled: parsedDoc.seo.enabled,
domain: new URL(parsedDoc.seo.domain).host
})
})
}
},
integrations: [
tailwind(),
//sitemap(),
icon(),
svelte(),
playformCompress({
CSS: false,
HTML: true,
Image: true,
JavaScript: true,
SVG: true
})
],
vite: {
plugins: [
viteStaticCopy({
targets: [
{
src: `${uvPath}/**/*`.replace(/\\/g, "/"),
dest: "uv",
overwrite: false
},
{
src: `${epoxyPath}/**/*`.replace(/\\/g, "/"),
dest: "epoxy",
overwrite: false
},
{
src: `${libcurlPath}/**/*`.replace(/\\/g, "/"),
dest: "libcurl",
overwrite: false
},
{
src: `${scramjetPath}/**/*`.replace(/\\/g, "/"),
dest: "scram",
overwrite: false
},
{
src: `${baremuxPath}/**/*`.replace(/\\/g, "/"),
dest: "baremux",
overwrite: false
},
{
src: `${workerwarePath}/**/*`.replace(/\\/g, "/"),
dest: "workerware",
overwrite: false
}
]
})
],
server: {
proxy: {
"/api/catalog-stats": {
target: "http://localhost:8080/api/catalog-stats",
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api\/catalog-stats/, "")
},
"/api/catalog-assets": {
target: "http://localhost:8080/api/catalog-assets",
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api\/catalog-assets/, "")
},
"/api/packages": {
target: "http://localhost:8080/api/packages",
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api\/packages/, "")
},
"/packages": {
target: "http://localhost:8080",
changeOrigin: true
},
"/wisp/": {
target: "ws://localhost:8080/wisp/",
changeOrigin: true,
ws: true,
rewrite: (path) => path.replace(/^\/wisp\//, "")
},
"/styles": {
target: "http://localhost:8080",
changeOrigin: true
}
}
}
},
output: "server",
adapter: node({
mode: "middleware"
})
});

32
biome.json Normal file
View file

@ -0,0 +1,32 @@
{
"$schema": "https://biomejs.dev/schemas/1.9.3/schema.json",
"files": {
"ignore": ["~/", "**/dist/**", ".github/**"],
"include": ["**/**", "server/**"]
},
"formatter": {
"indentStyle": "space",
"indentWidth": 4,
"lineWidth": 100,
"ignore": ["pnpm-lock.yaml", "package.json"]
},
"organizeImports": { "enabled": true },
"linter": { "enabled": false },
"javascript": {
"formatter": {
"trailingCommas": "none",
"quoteStyle": "double",
"semicolons": "always"
}
},
"json": {
"parser": {
"allowComments": true,
"allowTrailingCommas": true
},
"formatter": {
"indentStyle": "space",
"trailingCommas": "none"
}
}
}

23
config.example.toml Normal file
View file

@ -0,0 +1,23 @@
[marketplace]
enabled = false # Turn on or off the marketplace entirely
psk = "CHANGEME" # Change this to something more secure.
level = 1
[seo]
enabled = false
domain = "https://nebulaproxy.io"
[db]
name = "database" # Your database name
username = "username" # The username of your DB (SQLITE just ignores this)
password = "password" # The password to your DB (SQLITE ignores this)
postgres = false # Enable to use postgres over sqlite (recommended for large prod instances)
[postgres] # Set the "domain" to either and ip address or a actual domain
domain = ""
port = 5432
[server.server]
port = 8080
wisp = true
logging = true # Disable for the tons & tons of logs to go away (useful for debugging but otherwise eh)

View file

@ -0,0 +1,22 @@
:root {
--background-primary: #282828;
--background-lighter: #3c3836;
--navbar-color: #504945;
--navbar-height: 60px;
--navbar-text-color: #fbf1c7;
--navbar-link-color: #ebdbb2;
--navbar-link-hover-color: #fabd2f;
--navbar-font: "Roboto", sans-serif;
--input-text-color: #b8bb26;
--input-placeholder-color: #928374;
--input-background-color: #1d2021;
--input-border-color: #b8bb26;
--input-border-size: 1.3px;
--navbar-logo-filter: none;
--dropdown-option-hover-color: #665c54;
--tab-color: #1d2021;
--border-color: #b8bb26;
--highlight-color: #fe8019;
--accent-color: #83a598;
--secondary-text-color: #d3869b;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

View file

@ -0,0 +1,18 @@
:root {
--background-primary: hsl(310 50% 90%);
--background-lighter: hsl(310 50% 90%);
--navbar-color: hsl(310 50% 100%);
--navbar-height: 60px;
--navbar-text-color: hsl(310 50% 15%);
--navbar-link-color: hsl(310 50% 15%);
--navbar-link-hover-color: hsl(310 50% 90%);
--navbar-font: "Roboto";
--input-text-color: hsl(310 50% 15%);
--input-placeholder-color: white;
--input-background-color: hsl(310 50% 100%);
--input-border-color: hsl(310 50% 25%);
--input-border-size: 1.3px;
--navbar-logo-filter: none;
--tab-color: var(--black);
--border-color: hsl(310 50% 25%);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

View file

@ -0,0 +1,19 @@
:root {
--background-primary: #000000;
--background-lighter: #000000;
--navbar-color: #00000f;
--navbar-height: 60px;
--navbar-text-color: #4763ff;
--navbar-link-color: #4763ff;
--navbar-link-hover-color: gray;
--navbar-font: "Roboto";
--input-text-color: #4763ff;
--input-placeholder-color: white;
--input-background-color: #000000;
--input-border-color: #4763ff;
--input-border-size: 1.3px;
--navbar-logo-filter: none;
--dropdown-option-hover-color: #000000;
--tab-color: #000000;
--border-color: #4763ff;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -0,0 +1,24 @@
:root {
--background-primary: #000000;
--background-lighter: #000000;
--navbar-color: #020805;
--navbar-height: 60px;
--navbar-text-color: #3cb371;
--navbar-link-color: #3cb371;
--navbar-link-hover-color: white;
--input-text-color: #3cb371;
--input-placeholder-color: white;
--input-background-color: #000000;
--input-border-color: #3cb371;
--input-border-size: 1.3px;
--navbar-logo-filter: none;
--dropdown-option-hover-color: #000000;
--tab-color: #000000;
--border-color: #3cb371;
--font-family: "terminal";
}
@font-face {
font-family: terminal;
src: url("./terminal.ttf");
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

View file

@ -1,23 +0,0 @@
{
"sendgrid_verification": false,
"sendgrid_options": {
"api_key": "YOUR_SENDGRID_API_KEY",
"sendFromEmail": "THE EMAIL THE CODES WILL BE SENT FROM (MUST BE VERIFIED IN SENDGRID)",
"to_email": "THE EMAIL YOU WANT THE CODES SENT TO"
},
"discord_verification": false,
"webhook_url": "YOUR DISCORD WEBHOOK URL",
"smtp_verification": false,
"smtp_options": {
"to_email": "THE EMAIL YOU WANT THE CODES SENT TO",
"sendFromEmail": "THE EMAIL THE CODES ARE SENT FROM",
"host": "YOUR SMTP HOST",
"port": 465,
"auth": {
"user": "SMTP USER",
"pass": "YOUR PASSWORD"
}
}
}

21
docker-compose.build.yml Normal file
View file

@ -0,0 +1,21 @@
services:
nebula:
image: ghcr.io/nebulaservices/nebula:latest
container_name: nebula
build: .
restart: unless-stopped
ports:
# HOST:CONTAINER (DO NOT CHANGE THE CONTAINER PORT, UNLESS EDITED IN THE config.toml FILE)
- 8080:8080
volumes:
- ./config.toml:/app/config.toml
# Uncomment the the below stuff to use POSTGRES!
# db:
# image: postgres
# restart: unless-stopped
# environment:
# POSTGRES_PASSWORD: password #CHANGE THIS
# POSTGRES_USER: username
# POSTGRES_DB: db
# volumes:
# - ./db:/var/lib/postgresql/data

View file

@ -1,10 +1,20 @@
version: "3"
services:
nebula:
image: nebula:latest
build: .
image: ghcr.io/nebulaservices/nebula:latest
container_name: nebula
restart: unless-stopped
ports:
# DO NOT CHANGE 3000!
- your port here:3000
# HOST:CONTAINER (DO NOT CHANGE THE CONTAINER PORT, UNLESS EDITED IN THE config.toml FILE)
- 8080:8080
volumes:
- ./config.toml:/app/config.toml
# Uncomment the the below stuff to use POSTGRES!
# db:
# image: postgres
# restart: unless-stopped
# environment:
# POSTGRES_PASSWORD: password #CHANGE THIS
# POSTGRES_USER: username
# POSTGRES_DB: db
# volumes:
# - ./db:/var/lib/postgresql/data

View file

@ -1,8 +0,0 @@
module.exports = {
apps: [
{
name: "Site",
script: "proxysocks node app.js"
}
]
};

2551
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,28 +1,66 @@
{
"name": "nebula-web",
"version": "7.11.6",
"description": "Explore the web. Freely.",
"name": "nebula",
"type": "module",
"main": "app.js",
"version": "9.1.0",
"private": true,
"scripts": {
"start": "node app.js"
"dev": "astro dev --host 0.0.0.0 & tsx --watch server/server.ts",
"start": "node server/server.js",
"build:server": "tsc -p server",
"build:client": "astro check && astro build",
"build": "npm run build:server & npm run build:client",
"bstart": "npm run build && npm run start",
"preview": "astro preview",
"astro": "astro",
"format:code": "biome format . --write",
"format:imports": "biome check . --write",
"format": "npm run format:code && npm run format:imports",
"version": "changeset version"
},
"keywords": [
"proxy"
],
"author": "Nebula Services",
"license": "AGPL-3.0-only",
"dependencies": {
"@sendgrid/mail": "^7.7.0",
"@tomphttp/bare-server-node": "^1.2.5",
"@titaniumnetwork-dev/ultraviolet": "^1.0.11",
"bcrypt": "^5.1.0",
"cookie-parser": "^1.4.6",
"express": "^4.18.2",
"nodemailer": "^6.9.1",
"uuid": "^9.0.0"
"@astrojs/check": "^0.9.4",
"@astrojs/node": "^9.0.0",
"@astrojs/sitemap": "^3.2.1",
"@astrojs/svelte": "^7.0.2",
"@astrojs/tailwind": "^5.1.4",
"@fastify/compress": "^8.0.1",
"@fastify/helmet": "^13.0.0",
"@fastify/middie": "^9.0.2",
"@fastify/multipart": "^9.0.1",
"@fastify/static": "^8.0.3",
"@iconify-json/ph": "^1.2.2",
"@mercuryworkshop/bare-mux": "^2.1.7",
"@mercuryworkshop/epoxy-transport": "^2.1.27",
"@mercuryworkshop/libcurl-transport": "^1.3.15",
"@playform/compress": "^0.1.6",
"@titaniumnetwork-dev/ultraviolet": "^3.2.10",
"@mercuryworkshop/scramjet": "https://github.com/MercuryWorkshop/scramjet/releases/download/latest/mercuryworkshop-scramjet-1.0.2-dev.tgz",
"@types/node": "^22.10.2",
"@types/sequelize": "^4.28.20",
"astro": "^5.1.1",
"astro-icon": "^1.1.5",
"astro-seo": "^0.8.4",
"chalk": "^5.4.1",
"fastify": "^5.2.0",
"gradient-string": "^3.0.0",
"pg": "^8.13.1",
"pg-hstore": "^2.3.4",
"sequelize": "^6.37.5",
"smol-toml": "^1.3.1",
"sqlite3": "^5.1.7",
"svelte": "^5.16.0",
"svelte-french-toast": "^1.2.0",
"tailwindcss": "^3.4.17",
"typescript": "^5.7.2",
"vite-plugin-static-copy": "^2.2.0",
"wisp-server-node": "^1.1.7"
},
"engines": {
"node": "19.x"
"devDependencies": {
"@biomejs/biome": "^1.9.4",
"@changesets/cli": "^2.27.11",
"bufferutil": "^4.0.9",
"ora": "^8.1.1",
"sharp": "^0.33.5",
"tsx": "^4.19.2"
}
}

8870
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load diff

BIN
public/classic_theme.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
public/cloaks/canvas.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
public/cloaks/classroom.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
public/cloaks/google.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 615 B

BIN
public/cloaks/ps.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
public/cloaks/wikipedia.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

16
public/favicon.svg Normal file
View file

@ -0,0 +1,16 @@
<svg
version="1.2"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 400 400"
width="400"
height="400"
fill="#7967dd"
style="width: 100%; height: 100%;"
><title>nebula</title><g id="svgg"
><path
id="path0"
fill="#7967dd"
d="m213.6 84c1 0.3 3.4 0.7 5.1 1 1.8 0.2 4.1 0.7 5.2 1 13.2 4.1 20.3 6.8 24.5 9.1 0.6 0.3 2.3 1.2 3.8 2 2.8 1.4 13.1 8 14.4 9.2 0.5 0.3 2.3 1.9 4.2 3.5 6.7 5.5 15.5 14.9 19.2 20.4 1 1.4 2 2.7 2.2 2.8 0.3 0.1 0.5 0.5 0.5 0.8 0 0.3 1.2 2.2 2.5 4.3 2.3 3.4 7.8 14.3 9.8 19.3 0.8 2.1 0.9 2.2 10 4.9 5.6 1.6 11.1 3.4 11.7 3.8 0.3 0.2 2.4 1.1 4.7 1.9 11.1 4.1 23 12.5 27.3 19.4 5.5 8.7 3.6 20.5-4.5 28.5-3.1 3-7.5 6.4-8.4 6.4-0.3 0-0.7 0.2-0.8 0.5-1.1 2.3-23.3 11.2-35.9 14.3-3.2 0.9-3.5 1.2-5.7 6.8-7.5 19-25.5 40.6-42.3 51.1-1.6 1-3.1 2-3.3 2.2-0.1 0.2-0.9 0.7-1.7 1.2-0.8 0.4-2.2 1.2-2.9 1.6-0.8 0.4-1.6 1-1.8 1.1-0.5 0.5-4.1 2.2-8.1 3.9-1.8 0.8-3.8 1.6-4.5 2-0.7 0.3-3.1 1.1-5.2 1.8-8.3 2.6-9.8 3-21 4.9-6.4 1.1-25.3 1.3-30.5 0.3-1.9-0.3-5.8-1.1-8.6-1.6-6.8-1.3-12.7-3-20-5.7-3.3-1.2-18-8.8-19.7-10.1-0.9-0.7-4.1-3.1-7.1-5.2-5.7-4.1-17.9-15.9-20.7-20-0.9-1.2-2-2.7-2.5-3.2-3.2-3.3-13.7-21.7-13.7-24.1 0-0.6-0.2-1.2-0.6-1.4-0.3-0.2-0.8-1.2-1-2.3-0.4-1.9-1.7-2.7-6.5-3.8-23.2-5.6-43.1-17.2-48.6-28.5-7.1-14.4 4.5-31.3 27.3-39.7 1.8-0.7 4.1-1.6 5.2-2 3.7-1.5 8-2.9 19.5-6.2 1.6-0.5 2.8-1.2 2.8-1.7 0-2.4 9.8-21.6 13.1-25.7 0.2-0.4 1.4-1.8 2.5-3.2 13.8-18.1 30.2-30.6 50.6-38.8 4.3-1.7 6-2.3 14.3-4.5 5.5-1.6 11.2-2.4 18.4-2.9 7.9-0.5 24-0.2 26.8 0.6zm-29.7 17.3c-0.2 0.1-7.3 1.7-12.9 2.7-1.7 0.4-4.3 1.2-5.8 1.9-1.5 0.6-3.9 1.5-5.5 2-1.5 0.4-3.3 1.3-4 2-0.7 0.7-1.7 1.2-2.3 1.2-1.2 0-9.5 4.5-9.8 5.3-0.2 0.3-0.5 0.6-0.9 0.6-1.9 0-19.6 16-23.8 21.6-9.3 12.2-16.1 27.4-19.2 42.7-2 10.1-1.1 37.5 1.4 41.4 0 0.1 3.7 0.9 8.1 1.8 9.5 1.9 12.8 2.4 34.6 4.9 38.5 4.5 107.9 2.2 138.3-4.5 1.4-0.3 4.1-0.9 6.1-1.3 4.2-0.8 3.4 0.2 4.9-7.1 1.6-8.3 1.7-27 0.1-34.6-1.5-7.1-3.2-13.4-3.7-14.2-0.3-0.4-0.7-1.5-0.9-2.6-2.8-12.1-19.2-34.1-33-44.3-2.9-2.1-5.5-4-5.8-4.3-2.8-2.2-4.9-3.1-7.2-3.1-2.1 0-2.6-0.2-2.7-1.3-0.2-1.5-5.7-4.5-6.3-3.5-0.7 1.1-2.4 0.6-2.7-0.7-0.4-1.3-1.2-1.6-5.8-2.1-1.6-0.2-4-0.9-5.5-1.6-3.9-1.8-5.3-2.2-10.2-2.6-4.6-0.4-25.2-0.7-25.5-0.3zm74.3 42.2c7.4 9.8 4.8 23.5-4.6 24.9-6.9 1-20.9-5.8-21-10.2 0-0.2-0.3-0.8-0.8-1.3-6.4-6.8-5-20.8 2.4-24.1 6.7-2.9 17.2 1.8 24 10.7zm-176.4 36.4c-0.1-0.1-4.6 1.1-5.9 1.6-0.7 0.3-3 1.2-5.1 2-9.9 3.8-15.1 6.8-19.6 11.5-3.4 3.5-3.3 4.5 0.5 8.7 1 1 11.3 7.6 12 7.6 0.2 0 1.7 0.6 3.4 1.3 1.6 0.8 3.6 1.6 4.3 1.9 1.8 0.8 9.3 3.3 9.9 3.3 0.3 0 0.3-2 0-4.4-0.6-5.6-0.6-24.5 0.1-29.6 0.3-2.1 0.5-3.9 0.4-3.9zm229.3-0.3c-0.2 0 0 1 0.2 2.1 0.6 2.8 0.6 31.3 0 34-0.5 2.2-0.4 2.2 1.3 1.8 3.1-0.7 12.9-4.5 18.3-7 8.5-4 14.3-10.1 12.6-13.3-1.1-2.1-6.7-7.2-7.9-7.2-0.4 0-0.9-0.2-1-0.5-0.4-1.1-11.8-6.1-19.2-8.5-2.3-0.7-4.2-1.4-4.3-1.4zm-199.4 63.4l-3.1-0.4 1.8 3.2c0.9 1.8 1.9 3.4 2.2 3.5 0.3 0.1 0.5 0.6 0.5 1.1 0 0.4 0.6 1.5 1.3 2.3 0.7 0.9 1.5 1.9 1.8 2.2 0.3 0.4 0.8 1.2 1.1 1.7 6.2 10.7 35.6 33.5 43.3 33.5 0.2 0 1.3 0.4 2.5 0.9 2.5 1.2 10.6 3.4 15.3 4.2 9.5 1.8 11.6 2.1 17.4 2.1 6.6 0 16.4-1.3 22.9-3 2.2-0.5 5.2-1.3 6.8-1.7 1.6-0.3 3.2-0.9 3.5-1.2 0.4-0.3 1.1-0.6 1.6-0.6 2.3 0 22-10.6 24-12.9 0.2-0.2 2.2-1.9 4.5-3.7 5.7-4.5 11.8-11 17.1-18.4 1.6-2.3 3.2-4.5 3.6-4.9 0.4-0.4 0.7-1 0.7-1.2 0-0.2 0.8-1.9 1.9-3.6 1.1-1.7 1.9-3.2 1.9-3.4 0-0.2-3.8 0.4-11 1.6-31.7 5.4-85.1 6.7-126.9 3.1-9.6-0.8-23.1-2.3-27.8-3.2-2.2-0.4-5.3-0.9-6.9-1.2z"
class="s0"></path></g
></svg
>

After

Width:  |  Height:  |  Size: 3.4 KiB

View file

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

19
public/nebula.css Normal file
View file

@ -0,0 +1,19 @@
:root {
--background-primary: #191724;
--background-lighter: #16121f;
--navbar-color: #26233a;
--navbar-height: 60px;
--navbar-text-color: #7967dd;
--navbar-link-color: #e0def4;
--navbar-link-hover-color: gray;
--navbar-font: "Roboto";
--input-text-color: #e0def4;
--input-placeholder-color: white;
--input-background-color: #1f1d2e;
--input-border-color: #eb6f92;
--input-border-size: 1.3px;
--navbar-logo-filter: none;
--dropdown-option-hover-color: #312a49;
--tab-color: var(--black);
--border-color: #16121f;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,2 +0,0 @@
(()=>{"use strict";self.__osana$config={bare:`${location.origin}/bare/`,prefix:"/service/~osana/",codec:self.__osana$bundle.codecs.none,files:{config:"/osana/osana.config.js",client:"/osana/osana.client.js",bundle:"/osana/osana.bundle.js",worker:"/osana/osana.worker.js"},blacklist:[/^(www\.)?netflix\.com/,/^accounts\.google\.com/]}})();
//# sourceMappingURL=osana.config.js.map

View file

@ -1 +0,0 @@
{"version":3,"file":"osana.config.js","mappings":"mBAAAA,KAAKC,eAAiB,CAClBC,KAAM,GAAGC,SAASC,eAClBC,OAAQ,WACRC,MAAON,KAAKO,eAAeC,OAAOC,KAClCC,MAAO,CACHC,OAAQ,mBACRC,OAAQ,mBACRC,OAAQ,mBACRC,OAAQ,oBAEZC,UAAW,CACP,wBACA,0B","sources":["webpack://osana/./src/config.ts"],"sourcesContent":["self.__osana$config = {\n bare: `${location.origin}/bare/`,\n prefix: \"/~osana/\",\n codec: self.__osana$bundle.codecs.none,\n files: {\n config: \"/osana.config.js\",\n client: \"/osana.client.js\",\n bundle: \"/osana.bundle.js\",\n worker: \"/osana.worker.js\"\n },\n blacklist: [\n /^(www\\.)?netflix\\.com/,\n /^accounts\\.google\\.com/,\n ]\n};\nexport {};\n"],"names":["self","__osana$config","bare","location","origin","prefix","codec","__osana$bundle","codecs","none","files","config","client","bundle","worker","blacklist"],"sourceRoot":""}

View file

@ -1,2 +0,0 @@
(()=>{"use strict";importScripts("/osana/osana.bundle.js?1"),importScripts("/osana/osana.config.js?1"),self.OsanaServiceWorker=class{constructor(){this.config=self.__osana$config,this.bundle=self.__osana$bundle,this.bareClient=new this.bundle.BareClient(this.config.bare)}fetch(t){return s=this,n=void 0,r=function*(){const s=this.config.codec.decode(new URL(t.request.url).pathname.replace(this.config.prefix,""))+new URL(t.request.url).search;if(!/^https?:\/\//.test(s))return fetch(t.request.url);const n=new URL(s),i=this.bundle.rewrite.headers.request(Object.fromEntries(t.request.headers.entries()),n);if(this.config.blacklist&&this.config.blacklist.some((e=>e.test(n.host))))return new e;const r={method:t.request.method,headers:i};["GET","HEAD"].includes(t.request.method)||(r.body=yield t.request.blob());const o=yield this.bareClient.fetch(n,r);let a=o.rawResponse.status;const c=this.bundle.rewrite.headers.response(o.rawHeaders,n);let l="";return/text\/html/.test(c["Content-Type"])?(l=`<head><script src="${this.config.files.bundle}?1"><\/script><script src="${this.config.files.config}?1"><\/script><script src="${this.config.files.client}?1"><\/script><link rel="icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAA1JREFUGFdjYGBkZAAAAAoAAx9k7/gAAAAASUVORK5CYIIA"><link rel="icon" href="${n.origin}/favicon.ico">`+(301===a&&c.location?`<meta http-equiv="refresh" content="0; url=${this.bundle.rewrite.url(c.location)}">`:"")+"</head>",l+=this.bundle.rewrite.html(yield o.text(),n.origin+n.pathname)):l=/text\/css/.test(c["Content-Type"])||"style"===t.request.destination?this.bundle.rewrite.css(yield o.text(),n.origin+n.pathname):/application\/javascript/.test(c["Content-Type"])||"script"===t.request.destination?this.bundle.rewrite.js(yield o.text()):yield o.arrayBuffer(),new Response(l,{status:o.rawResponse.status,statusText:o.rawResponse.statusText,headers:c})},new((i=void 0)||(i=Promise))((function(e,t){function o(e){try{c(r.next(e))}catch(e){t(e)}}function a(e){try{c(r.throw(e))}catch(e){t(e)}}function c(t){var s;t.done?e(t.value):(s=t.value,s instanceof i?s:new i((function(e){e(s)}))).then(o,a)}c((r=r.apply(s,n||[])).next())}));var s,n,i,r}};class e extends Response{constructor(){super("Forbidden",{status:403,statusText:"Forbidden",headers:{"Content-Type":"text/plain"}})}}})();
//# sourceMappingURL=osana.worker.js.map

File diff suppressed because one or more lines are too long

View file

@ -1,154 +0,0 @@
{
"adjectives": [
"admiring",
"adoring",
"affectionate",
"agitated",
"amazing",
"angry",
"awesome",
"beautiful",
"blissful",
"bold",
"boring",
"brave",
"busy",
"charming",
"clever",
"cool",
"compassionate",
"competent",
"condescending",
"confident",
"cranky",
"crazy",
"dazzling",
"determined",
"distracted",
"dreamy",
"eager",
"ecstatic",
"elastic",
"elated",
"elegant",
"eloquent",
"epic",
"exciting",
"fervent",
"festive",
"flamboyant",
"focused",
"friendly",
"frosty",
"funny",
"gallant",
"gifted",
"goofy",
"gracious",
"great",
"happy",
"hardcore",
"heuristic",
"hopeful",
"hungry",
"infallible",
"inspiring",
"interesting",
"intelligent",
"jolly",
"jovial",
"keen",
"kind",
"laughing",
"loving",
"lucid",
"magical",
"mystifying",
"modest",
"musing",
"naughty",
"nervous",
"nice",
"nifty",
"nostalgic",
"objective",
"optimistic",
"peaceful",
"pedantic",
"pensive",
"practical",
"priceless",
"quirky",
"quizzical",
"recursing",
"relaxed",
"reverent",
"romantic",
"sad",
"serene",
"sharp",
"silly",
"sleepy",
"stoic",
"strange",
"stupefied",
"suspicious",
"sweet",
"tender",
"thirsty",
"trusting",
"unruffled",
"upbeat",
"vibrant",
"vigilant",
"vigorous",
"wizardly",
"wonderful",
"xenodochial",
"youthful",
"zealous",
"zen"
],
"surnames": [
"albattani",
"allen",
"almeida",
"antonelli",
"agnesi",
"archimedes",
"ardinghelli",
"aryabhata",
"austin",
"babbage",
"banach",
"banzai",
"bardeen",
"bartik",
"bassi",
"beaver",
"bell",
"benz",
"bhabha",
"bhaskara",
"black",
"blackburn",
"blackwell",
"bohr",
"booth",
"borg",
"bose",
"bouman",
"boyd",
"brahmagupta",
"brattain",
"brown",
"buck",
"burnell",
"cannon",
"carson",
"cartwright",
"carver",
"cerf",
"chandrasekhar"
]
}

View file

@ -1,46 +0,0 @@
// Get's the current day using the Date function built in.
// A dependency for displaying time - displayTime(void)
function getDayName(dateStr, locale) {
var date = new Date(dateStr);
return date.toLocaleDateString(locale, { weekday: "long" });
}
// The main function to show the time on the main page
// needs to be initialized by a call (only one)
// Dependent on getDayName function
function displayTime() {
var date = new Date();
var h = date.getHours(); // 0 - 23
var m = date.getMinutes(); // 0 - 59
var s = date.getSeconds(); // 0 - 59
var session = "AM";
h = h == 12 ? 24 : h;
if (h == 0) {
h = 12;
} else if (h >= 12) {
h = h - 12;
session = "PM";
}
h = h < 10 ? "0" + h : h;
m = m < 10 ? "0" + m : m;
s = s < 10 ? "0" + s : s;
// Repeat itself every second
setTimeout(displayTime, 1000);
// Get today's date
var today = new Date();
var dd = String(today.getDate()).padStart(2, "0");
var mm = String(today.getMonth() + 1).padStart(2, "0"); //January is 0!
var yyyy = today.getFullYear();
today = mm + "/" + dd + "/" + yyyy;
var time = h + "<span style='opacity:100%;' class='clockColon'>:</span>" + m;
try {
document.getElementById("digitalClock").innerHTML =
getDayName(today, "us-US") + ", " + time + " " + session + ".";
} catch {}
return time;
}
// initialize the time function
displayTime();

View file

@ -1,359 +0,0 @@
// Welcome to the main Nebula script
// This script handles all the tasks neccesary for a proxy.
// What this doesn't include is the actual proxies, just the neccesary tasks in order for the proxies to be able to preform, such as registering the service worker required by Interception proxies.
// Documentation Writers/Contributors:
// GreenWorld#0001 (Discord) / GreenyDev (Github)
// If you would like to contribute, feel free to open a pull request.
// These docs are not finished
// Navigation controls for smaller devices
// Executed in the inline HTML
function openNav() {
document.getElementById("sidenav").style.width = "260px";
}
function closeNav() {
document.getElementById("sidenav").style.width = "0px";
}
function setLoaderText() {
document.getElementById("connectorText").textContent =
"connecting to service";
const loader = document.getElementById("lpoader");
const loadConstructer = loader.style;
loadConstructer.display = "flex";
loadConstructer.justifyContent = "center";
// Changing the text over multiple periods of time creates character, and aliveness (is that even a word?)
setTimeout(() => {
document.getElementById("connectorText").style.fontSize = "12px";
document.getElementById("connectorText").textContent =
"Due to high server load, this may take a while.";
}, 3200);
setTimeout(() => {
document.getElementById("connectorText").style.fontSize = "14px";
document.getElementById("connectorText").textContent =
"Hmmm.. Something isn't right..";
}, 17000);
}
window.stealthEngineLoaded = false;
window.addEventListener("load", () => {
// Register the service workers for Osana and Ultraviolet proxy protocols
// This is a better method than registering onsubmit because this allows the ability to use proxied links on the main page.
navigator.serviceWorker.register("./sw.js", {
scope: "/service/"
});
// Link evaluation
// This functions' purpose is to check a string of text (the argument)
// it recognizes whether a string is a URL or not, and it returns a true or false value
function isUrl(val = "") {
if (
/^http(s?):\/\//.test(val) ||
(val.includes(".") && val.substr(0, 1) !== " ")
)
return true;
return false;
}
const proxy = localStorage.getItem("proxy") || "uv";
const inpbox = document.querySelector("form");
// Display the "loading" indicators on the main page, looks much better than a static/still screen.
const hasLoadedElement = document.createElement("div");
hasLoadedElement.id = "hasLoaded";
hasLoadedElement.style.display = "none";
document.body.appendChild(hasLoadedElement);
inpbox.addEventListener("submit", (event) => {
// Prevents the default event tasks
event.preventDefault();
console.log("Connecting to service -> loading");
setLoaderText();
});
// Form submission
const form = document.querySelector("form");
form.addEventListener("submit", (event) => {
event.preventDefault();
// Check if the service worker (commonly called SW) is registered
if (typeof navigator.serviceWorker === "undefined")
alert(
"An error occured registering your service worker. Please contact support - discord.gg/unblocker"
);
//
if (proxy === "uv" || proxy === "osana") {
// Re-register the service worker incase it failed to onload
navigator.serviceWorker
.register("./sw.js", {
scope: "/service/"
})
.then(() => {
const value = event.target.firstElementChild.value;
let url = value.trim();
if (!isUrl(url)) url = "https://www.google.com/search?q=" + url;
if (!(url.startsWith("https://") || url.startsWith("http://")))
url = "http://" + url;
// encode the URL for UltraViolet
let redirectTo =
proxy === "uv"
? __uv$config.prefix + __uv$config.encodeUrl(url)
: __osana$config.prefix + __osana$config.codec.encode(url);
const option = localStorage.getItem("nogg");
if (option === "on") {
if (window.stealthEngineLoaded !== false) {
stealthEngine(redirectTo);
} else {
console.error(
"Stealth Engine failed to load! Please contact support - discord.gg/unblocker"
);
}
} else {
setTimeout(() => {
// If StealthMode is off, this is the enabled option.
const _popout = window.open("/blob", "_self");
const blob = _popout.document;
// Write all of the neccesary page elements, and the Options including the cloak (if enabled)
// The blob writing is just the background elements, like the "Nebula is loading your content, please wait" screen. It does not carry proxied content, or even the iframe.
blob.write(`
<script>
function handleTabLeave(activeInfo) {
var link = document.querySelector("link[rel~='icon']");
if (localStorage.getItem('ADVcloak') == "on") {
if (document.title == "Nebula") {
document.title = "Google"
if (!link) {
link = document.createElement('link');
link.rel = 'icon';
document.getElementsByTagName('head')[0].appendChild(link);
}
link.href = 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQo7AE3IF34XPGyseQjkXIOsWXpkZiLlMjSAwySjcJSPAwlv3hnGKi1&usqp=CAU';
document.title = "Google"
} else if (document.title == "Google") {
document.title = "Nebula"
if (!link) {
link = document.createElement('link');
link.rel = 'icon';
document.getElementsByTagName('head')[0].appendChild(link);
}
} else {
return false;
}
}
}
document.addEventListener("visibilitychange", handleTabLeave)
</script>
<style>@import "https://fonts.googleapis.com/css2?family=Roboto:wght@700&display=swap"; body{background:#191724;color:#fff}div{margin-top:30px;font-size:100px;text-align:center;font-family:"Roboto";font-weight:700}.loader .b1{left:42%}.loader .b2{left:50%;animation-delay:100ms}.loader .b3{left:58%;animation-delay:200ms;color:#eb6f92}.loader .b1,.loader .b2,.loader .b3{width:10px;height:30px;position:absolute;top:50%;transform:rotate(0);animation-name:spinify;animation-duration:1600ms;animation-iteration-count:infinite;color:#eb6f92;background-color:#eb6f92}@keyframes spinify{0%{transform:translate(0px,0px)}33%{transform:translate(0px,24px);border-radius:100%;width:10px;height:10px}66%{transform:translate(0px,-16px)}88%{transform:translate(0px,4px)}100%{transform:translate(0px,0px)}}</style>
<div class="loader">
<div>Nebula is loading your content!</div>
<div style='font-size:35px;'>Please wait</div>
<div class="b1"></div>
<div class="b2"></div>
<div class="b3"></div>
</div>
`);
// inside of the blob, create and append the Iframe element which WILL carry the proxied content.
const iframe = blob.createElement("iframe");
const style = iframe.style;
const img = blob.createElement("link");
const link = location.href;
// We attach ARC because it supports us, keeping our arc link there would be greatly appreciated :)
const arcSrc = blob.createElement("script");
arcSrc.setAttribute(
"src",
"https://arc.io/widget.min.js#BgaWcYfi"
);
// Arc requires the Async attribute
// Async means not running parallel to other tasks, so it loads seperately to everything else (in a sense)
// Aysnchronous and Synchronous are somewhat difficult topics, so we recommend you
arcSrc.setAttribute("async", "");
blob.head.appendChild(arcSrc);
img.rel = "icon";
img.href =
"https://static.nebulacdn.xyz/content/images/nebula_logo_619x619.png";
blob.title = getRandomName();
// slice the link like some nice fruit :)
// Removing the '/' from 'whateverthislinkis.gay/'
// ^
var currentLink = link.slice(0, link.length - 1);
// To attribute the iframe to a source, we need to + the current link (post-slice) to the requested website, which is passed through the functions argument
iframe.src = currentLink + redirectTo;
// Style the Iframe to fill the entire screen and remove the bessels.
style.position = "fixed";
style.top = style.bottom = style.left = style.right = 0;
style.border = style.outline = "none";
style.width = style.height = "100%";
// finally, append the iframe to the blob's (window) body
blob.body.appendChild(iframe);
}, 1000);
}
});
}
});
});
// Set the option
var option = localStorage.getItem("nogg");
if (localStorage.getItem("theme") == null) {
localStorage.setItem("theme", "dark");
}
// Extra logging for support
function log() {
setTimeout(
console.log.bind(
console,
"%cWelcome To Nebula!",
"background: #3F51B5;color:#FFF;padding:5px;border-radius: 5px;line-height: 26px; font-size:24px;"
)
);
setTimeout(
console.log.bind(
console,
"%cIf you are seeing this, Nebula's main script has succesfully loaded!",
"background: green;color:#FFF;padding:5px;border-radius: 5px;line-height: 26px; font-size:16px;"
)
);
setTimeout(
console.log.bind(
console,
"%cIf you encounter an error, contact our support team on discord. Copy and paste the information below and send it in the ticket",
"background: red;color:#FFF;padding:5px;border-radius: 5px;line-height: 26px; font-size:12px;"
)
);
let online = navigator.onLine;
let userAgent = navigator.userAgent;
let browserName;
let diagnosticDomain = window.location.href;
if (userAgent.match(/chrome|chromium|crios/i)) {
browserName = "Chrome";
} else if (userAgent.match(/firefox|fxios/i)) {
browserName = "Firefox";
} else if (userAgent.match(/safari/i)) {
browserName = "Safari";
} else if (userAgent.match(/opr\//i)) {
browserName = "Opera";
} else if (userAgent.match(/edg/i)) {
browserName = "Edge";
} else {
browserName = "Browser not detected!";
}
setTimeout(
console.log.bind(
console,
`%c Information: \n Online: ${online} \n URL: ${diagnosticDomain} \n Browser: ${browserName} \n UA: ${userAgent}`,
"background: gray;color:#FFF;padding:5px;line-height: 26px; font-size:14px;"
)
)
}
log();
// Adjectives and surnames for a more advanced stealth engine.
// Used together to generate random names for the tab name
let adjectives;
let surnames;
async function surnameAdjectivesData() {
await fetch("/resources/adjectives_surnames.json")
.then((response) => response.json())
.then((data) => {
adjectives = data.adjectives;
surnames = data.surnames;
});
}
surnameAdjectivesData();
// Random number generator
// Dependency of getRandomName function
function getRandomNumber(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
// Random name generator
function getRandomName() {
const random1 = getRandomNumber(0, adjectives.length);
const random2 = getRandomNumber(0, surnames.length);
const adjective = adjectives[random1];
const surname = surnames[random2];
// Connect the adjective and surname together to create a random name
const randomName = adjective + "-" + surname;
return randomName;
}
// Clickoff cloaking
// This is used to cloak the tab when it is not active
function handleTabLeave() {
var link = document.querySelector("link[rel~='icon']");
if (localStorage.getItem("ADVcloak") == "on") {
if (document.title == "Nebula") {
if (!link) {
link = document.createElement("link");
link.rel = "icon";
document.getElementsByTagName("head")[0].appendChild(link);
}
link.href = "https://www.google.com/favicon.ico";
document.title = "Google";
} else if (document.title == "Google") {
document.title = "Nebula";
if (!link) {
link = document.createElement("link");
link.rel = "icon";
document.getElementsByTagName("head")[0].appendChild(link);
}
link.href =
"https://camo.githubusercontent.com/b565ae2e136e0ac6023e7099288a62382de7c2b8cdce86a8b90449b86649434c/68747470733a2f2f6e6562756c6170726f78792e6e6562756c612e62696f2f696d616765732f6c6f676f2e706e67";
} else {
return false;
}
}
}
// Create and Add the event listener
document.addEventListener("visibilitychange", handleTabLeave);
const stealthStored = localStorage.getItem("nogg");
function link(_link) {
if (stealthStored == "on") {
let inFrame;
try {
inFrame = window !== top;
} catch (e) {
inFrame = true;
}
setTimeout(() => {
if (!inFrame && !navigator.userAgent.includes("Firefox")) {
const popup = open("about:blank", "_blank");
if (!popup || popup.closed) {
alert("Popups are disabled!");
} else {
const doc = popup.document;
const iframe = doc.createElement("iframe");
const style = iframe.style;
const img = doc.createElement("link");
img.rel = "icon";
img.href =
"https://ssl.gstatic.com/images/branding/product/1x/drive_2020q4_32dp.png";
doc.title = getRandomName();
var currentLink = _link.slice(0, _link.length - 1);
iframe.src =
location.origin +
"/service/go/" +
__uv$config.encodeUrl(currentLink);
style.position = "fixed";
style.top = style.bottom = style.left = style.right = 0;
style.border = style.outline = "none";
style.width = style.height = "100%";
doc.body.appendChild(iframe);
}
}
}, 200);
} else {
location.href =
"service/go/" + __uv$config.encodeUrl("https://radon.games/");
}
}

View file

@ -1,124 +0,0 @@
// OPTIONS
const storedSetTheme = localStorage.getItem("theme");
function switchProxy() {
var selecter = document.getElementById("proxySwitcher");
var selectedOption = selecter.value;
localStorage.setItem("proxy", selectedOption);
var storedChoice = localStorage.getItem("proxy");
}
function setDefaultsIfUndefined() {
if (localStorage.ADVcloak == undefined) localStorage.setItem("ADVcloak", "off")
if (localStorage.nogg == undefined) localStorage.setItem("nogg", "off")
if (localStorage.ABtitle == undefined) localStorage.setItem("ABtitle", "")
if (localStorage.ABfaviconURL == undefined) localStorage.setItem("ABfaviconURL", "")
if (localStorage.theme == undefined) localStorage.setItem("theme", "dark")
if (localStorage.proxy == undefined) localStorage.setItem("proxy", "uv")
}
setDefaultsIfUndefined();
function resetViews() {
changeCSS("--background-primary", "#191724", true);
changeCSS("--navbar-color", "#26233a", true);
changeCSS("--navbar-height", "60px", true);
changeCSS("--navbar-text-color", "rgb(121 103 221)", true);
changeCSS("--navbar-link-color", "#e0def4", true);
changeCSS("--navbar-font", '"Roboto"', true);
changeCSS("--input-text-color", "#e0def4", true);
changeCSS("--input-placeholder-color", "#6e6a86", true);
changeCSS("--input-background-color", "#1f1d2e", true);
changeCSS("--input-placeholder-color", "white", true);
changeCSS("--input-border-color", "#eb6f92", true);
changeCSS("--input-border-size", "1.3px", true);
return "All views reset";
}
function saveIc() {
var notification = `
<div class="notification-container" id="notification-container">
<div class="notification notification-success">
<strong>Success!</strong> Your settings have been saved!
</div>
</div>
`;
document.getElementById("notifhere").innerHTML = notification;
setTimeout(() => {
var NotificationOBJ = document.getElementById("notifhere");
}, 2000);
}
function unsavedChanges() {
var notification = `
<div class="notification-container" id="notification-container">
<div class="notification notification-danger" id="notification-container">
<strong>Danger!</strong> You have unsaved changes!
</div>
</div>
`;
document.getElementById("notifhere").innerHTML = notification;
setTimeout(() => {
var NotificationOBJ = document.getElementById("notifhere");
}, 2000);
}
var option = localStorage.getItem("nogg");
function toggleNoGG() {
if (option === "on") {
option = "off";
localStorage.setItem("nogg", "off");
} else {
option = "on";
localStorage.setItem("nogg", "on");
}
}
var option2 = localStorage.ADVcloak;
function toggleClickoff() {
if (option2 == undefined) return console.error("ADVcloak key unset!")
if (option2 === "on") {
option2 = "off";
localStorage.setItem("ADVcloak", "off");
} else {
option2 = "on";
localStorage.setItem("ADVcloak", "on");
}
}
function toggleSetting(localStorageKey, value) {
localStorage.setItem(localStorageKey, value);
}
window.onload = function () {
if (localStorage.getItem("ABfaviconURL") === null) {
} else if (localStorage.getItem("ABfaviconURL") == "") {
} else {
document.querySelector("#faviconInput").value =
localStorage.getItem("ABfaviconURL");
}
if (localStorage.getItem("ABtitle") === null) {
} else if (localStorage.getItem("ABtitle") == "") {
} else {
document.querySelector("#titleInput").value =
localStorage.getItem("ABtitle");
}
};
function saveAbInfo() {
var faviconURL = document.getElementById("faviconInput").value;
var title = document.getElementById("titleInput").value;
localStorage.setItem("ABfaviconURL", faviconURL);
localStorage.setItem("ABtitle", title);
var notification = `
<div class="notification-container" id="notification-container">
<div class="notification notification-success">
<strong>Success!</strong> Your settings have been saved!
</div>
</div>
`;
document.getElementById("notifhere").innerHTML = notification;
setTimeout(() => {
var NotificationOBJ = document.getElementById("notifhere");
}, 2000);
}

View file

@ -1,33 +0,0 @@
window.onload = function () {
changeCSS(
"--background-primary",
localStorage.getItem("--background-primary")
);
changeCSS("--navbar-color", localStorage.getItem("--navbar-color"));
changeCSS("--navbar-height", localStorage.getItem("--navbar-height"));
changeCSS("--navbar-text-color", localStorage.getItem("--navbar-text-color"));
changeCSS("--input-text-color", localStorage.getItem("--input-text-color"));
changeCSS(
"--input-placeholder-color",
localStorage.getItem("--input-placeholder-color")
);
changeCSS(
"--input-background-color",
localStorage.getItem("--input-background-color")
);
changeCSS(
"--input-border-color",
localStorage.getItem("--input-border-color")
);
changeCSS("--input-border-size", localStorage.getItem("--input-border-size"));
changeCSS("--navbar-link-color", localStorage.getItem("--navbar-link-color"));
changeCSS("--navbar-font", localStorage.getItem("--navbar-font"));
changeCSS(
"--navbar-logo-filter",
localStorage.getItem("--navbar-logo-filter")
);
changeCSS(
"--text-color-primary",
localStorage.getItem("--text-color-primary")
);
};

View file

@ -1,103 +0,0 @@
// Stealth engine, a dependency for everything above.
// ensures that the js file is loaded
window.stealthEngineLoaded = true;
function stealthEngine(encodedURL) {
// Remember that the EncodedURL argument must be pre-encoded, or encoded before the function is called.
// This function does not encode the argument at all!
// Initialize the variable
let inFrame;
// make sure there isn't a window open already
try {
inFrame = window !== top;
} catch (e) {
inFrame = true;
}
setTimeout(() => {
// Basically, a checklist to make sure that an error won't occur.
// In this if statement, we're checking if an iframe is already being opened, if popups are disabled, and if the user agent IS NOT firefox (firefox sucks, sorry Moz)
if (!inFrame && !navigator.userAgent.includes("Firefox")) {
const popup = open("about:blank", "_blank");
if (!popup || popup.closed) {
alert(
"StealthEngine was unable to open a popup. (do you have popups disabled?)"
);
} else {
const doc = popup.document;
const iframe = doc.createElement("iframe");
const style = iframe.style;
popup.onload = () => {
document.getElementById("lpoader").style.display = "none";
document.getElementById("connectorText").textContent =
"connecting to service";
setTimeout(() => {
document.getElementById("connectorText").textContent =
"connecting to service";
}, 17500);
};
var isClosed = setInterval(function () {
if (popup.closed) {
clearInterval(isClosed);
document.getElementById("lpoader").style.display = "none";
document.getElementById("connectorText").textContent =
"connecting to service";
}
}, 1000);
// Favicon attachment
const img = doc.createElement("link");
const arcSrc = doc.createElement("script");
// We attach ARC because it supports us, keeping our arc link there would be greatly appreciated :)
arcSrc.setAttribute("src", "https://arc.io/widget.min.js#BgaWcYfi");
arcSrc.setAttribute("async", "");
doc.head.appendChild(arcSrc);
const link = location.href;
img.rel = "icon";
img.href =
ABFavicon ||
"https://ssl.gstatic.com/images/branding/product/1x/drive_2020q4_32dp.png";
if (localStorage.nogg == "on") {
doc.title = ABTitle || getRandomName();
} else {
doc.title = ABTitle || "Nebula";
}
var currentLink = link.slice(0, link.length - 1);
iframe.src = currentLink + encodedURL;
style.position = "fixed";
style.top = style.bottom = style.left = style.right = 0;
style.border = style.outline = "none";
style.width = style.height = "100%";
doc.body.appendChild(iframe);
doc.head.appendChild(img);
}
}
}, 1500);
}
let tryAbFavi = localStorage.getItem("ABfaviconURL");
let ABFavicon = "";
if (tryAbFavi === null) {
console.warn("ABfaviconURL is null, Defaulting");
ABFavicon = "";
} else if (tryAbFavi == "") {
console.warn("ABfaviconURL is empty, Defaulting");
ABFavicon = "";
} else {
ABFavicon = tryAbFavi;
}
let tryAbTitle = localStorage.getItem("ABtitle");
let ABTitle = "";
if (tryAbTitle === null) {
console.warn("ABtitle is null, Defaulting");
ABTitle = "";
} else if (tryAbTitle == "") {
console.warn("ABtitle is empty, Defaulting");
ABTitle = "";
} else {
ABTitle = tryAbTitle;
}

View file

@ -1,189 +0,0 @@
const THEME_OPTIONS = {
dark: {
"--background-primary": "#191724",
"--navbar-color": "#26233a",
"--navbar-height": "60px",
"--navbar-text-color": "#7967dd",
"--input-text-color": "#e0def4",
"--input-placeholder-color": "#6e6a86",
"--input-background-color": "#1f1d2e",
"--input-placeholder-color": "white",
"--input-border-color": "#eb6f92",
"--input-border-size": "1.3px",
"--navbar-link-color": "#e0def4",
"--navbar-font": '"Roboto"',
"--navbar-logo-filter": "invert(0%)",
"--text-color-primary": "#e0def4"
},
light: {
"--background-primary": "#d8d8d8",
"--navbar-color": "#a2a2a2",
"--navbar-height": "4em",
"--navbar-text-color": "#000000",
"--input-text-color": "#e0def4",
"--input-placeholder-color": "white",
"--input-background-color": "black",
"--input-border-color": "#eb6f92",
"--input-border-size": "1.3px",
"--navbar-link-color": "#000000",
"--navbar-font": '"Roboto"',
"--navbar-logo-filter": "invert(30%)",
"--text-color-primary": "#303030"
},
suit: {
"--background-primary": "#0c0c0c",
"--navbar-color": "#ff2e4e",
"--navbar-height": "4em",
"--navbar-text-color": "#000000",
"--input-text-color": "#e0def4",
"--input-placeholder-color": "white",
"--input-background-color": "#00000000",
"--input-border-color": "#ff346e",
"--input-border-size": "1.3px",
"--navbar-link-color": "#000000",
"--navbar-font": '"Roboto"',
"--navbar-logo-filter": "brightness(30)",
"--text-color-primary": "#00000"
},
metallic: {
"--background-primary": "#171717",
"--navbar-color": "#004953",
"--navbar-height": "4em",
"--navbar-text-color": "#ffffff",
"--input-text-color": "#e0def4",
"--input-placeholder-color": "white",
"--input-background-color": "#004953",
"--input-border-color": "#000000",
"--input-border-size": "1.3px",
"--navbar-link-color": "#e0def4",
"--navbar-font": '"Roboto"',
"--navbar-logo-filter": "invert(50%)",
"--text-color-primary": "#e0def4"
},
dante: {
"--background-primary": "#131313",
"--navbar-color": "#e4ff8b",
"--navbar-height": "3.5em",
"--navbar-text-color": "#000000",
"--input-text-color": "#000000",
"--input-placeholder-color": "000000",
"--input-background-color": "#e4ff8b",
"--input-border-color": "#00000000",
"--input-border-size": "1.3px",
"--navbar-link-color": "#000000",
"--navbar-font": '"Roboto"',
"--navbar-logo-filter": "brightness(0%)",
"--text-color-primary": "#000"
}
};
function changeCSS(property, value, isRoot = false) {
const root = document.documentElement;
isRoot
? root.style.setProperty(property, value)
: root.style.setProperty(property, value, "important");
}
function saveCSS(variable, value) {
localStorage.setItem(variable, value);
}
function applyTheme(theme) {
Object.entries(theme).forEach(([property, value]) => {
changeCSS(property, value);
localStorage.setItem(property, value);
});
}
function switchTheme() {
const selecter = document.getElementById("themeSwitcher");
const selectedOption = selecter.value;
console.log(selectedOption);
const theme = THEME_OPTIONS[selectedOption];
if (!theme) {
return;
}
applyTheme(theme);
localStorage.setItem("theme", selectedOption);
if (selectedOption == "custom") {
let startCustom = prompt(
"Would you like to have an interactive setup? Y/N",
""
);
if (startCustom == "Y" || startCustom == "y") {
alert(
"Welcome to the interactive setup. Please enter the following values. If you don't know what to enter, just press enter. They will default to Dark Mode."
);
let background = prompt(
"Background color || Possible Types: Keywords, RGB, RBBA, HSL, HSLA, Hexadecimal. || Default Value: #191724",
""
);
let navbar = prompt(
"Navbar color || Possible Types: Keywords, RGB, RBBA, HSL, HSLA, Hexadecimal. || Default Value: #26233a",
""
);
let navbarHeight = prompt(
"Navbar height || Possible Types: ABSOLUTE: cm, mm, Q, in, pc, pt, px RELATIVE: em, ex, ch, rem, lh, rlh, vw, vh, vb, vi || Default Value: 60px",
""
);
let navbarText = prompt(
"Navbar text color || Possible Types: Keywords, RGB, RBBA, HSL, HSLA, Hexadecimal. || Default Value: #7967dd",
""
);
let inputText = prompt(
"Input text color || Possible Types: Keywords, RGB, RBBA, HSL, HSLA, Hexadecimal. || Default Value: #e0def4",
""
);
let inputPlaceholder = prompt(
"Input placeholder color || Possible Types: Keywords, RGB, RBBA, HSL, HSLA, Hexadecimal. || Default Value: #6e6a86",
""
);
let inputBackground = prompt(
"Input background color || Possible Types: Keywords, RGB, RBBA, HSL, HSLA, Hexadecimal. || Default Value: #1f1d2e",
""
);
let inputBorder = prompt(
"Input border color || Possible Types: Keywords, RGB, RBBA, HSL, HSLA, Hexadecimal. || Default Value: #eb6f92",
""
);
let inputBorderSize = prompt(
"Input border size || Possible Types: ABSOLUTE: cm, mm, Q, in, pc, pt, px RELATIVE: em, ex, ch, rem, lh, rlh, vw, vh, vb, vi || Default Value: 1.3px",
""
);
let navbarFont = prompt(
'Navbar font || Enter a default font name, custom ones will likely not work. || Default Value: "Roboto"',
""
);
let navbarLink = prompt(
"Navbar link color || Possible Types: Keywords, RGB, RBBA, HSL, HSLA, Hexadecimal. || Default Value: #e0def4",
""
);
let navbarLogoFilter = prompt(
"Navbar logo filter || Adjust the NavBar-Logo-Filter. || Default Value: invert(0%)",
""
);
let textColorPrimary = prompt(
"Text color primary || Possible Types: Keywords, RGB, RBBA, HSL, HSLA, Hexadecimal. || Default Value: #e0def4",
""
);
localStorage.setItem("theme", "custom");
changeCSS("--background-primary", background, true);
changeCSS("--navbar-color", navbar, true);
changeCSS("--navbar-height", navbarHeight, true);
changeCSS("--navbar-text-color", navbarText, true);
changeCSS("--input-text-color", inputText, true);
changeCSS("--input-placeholder-color", inputPlaceholder, true);
changeCSS("--input-background-color", inputBackground, true);
changeCSS("--input-border-color", inputBorder, true);
changeCSS("--input-border-size", inputBorderSize, true);
changeCSS("--navbar-link-color", navbarLink, true);
changeCSS("--navbar-font", navbarFont, true);
changeCSS("--navbar-logo-filter", navbarLogoFilter, true);
changeCSS("--text-color-primary", textColorPrimary, true);
} else {
alert("Non-Interactive Setup Not supported yet.");
}
}
}

View file

@ -1,43 +0,0 @@
const generateOTP = document.getElementById("generate-otp");
generateOTP.onclick = () => {
fetch("/generate-otp", { method: "PATCH" });
};
const validateOTP = document.getElementById("validate-otp");
validateOTP.onclick = () => {
fetch("/validate-otp", {
method: "POST",
headers: {
"content-type": "application/json"
},
body: JSON.stringify({
otp: document.getElementById("otp").value
})
})
.then((response) => {
return response.json();
})
.then((data) => {
if (data.success) {
setCookie("validation", data.validation, 30);
location.href = "/";
} else {
alert("Invalid OTP.");
}
})
.catch(() => {
alert("An error occurred while validating your OTP.");
});
};
function setCookie(name, value, days) {
var expires = "";
if (days) {
var date = new Date();
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
expires = "; expires=" + date.toUTCString();
}
document.cookie = name + "=" + (value || "") + expires + "; path=/";
}

View file

@ -1,500 +0,0 @@
@import url("https://fonts.googleapis.com/css2?family=Dongle&family=Roboto:wght@100&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@1,100&display=swap");
:root {
--background-primary: #191724;
--navbar-color: #26233a;
--navbar-height: 60px;
--navbar-text-color: #7967dd;
--navbar-link-color: #e0def4;
--navbar-font: "Roboto";
--input-text-color: #e0def4;
--input-placeholder-color: white;
--input-background-color: #1f1d2e;
--input-border-color: #eb6f92;
--input-border-size: 1.3px;
--navbar-logo-filter: none;
}
::-webkit-input-placeholder {
text-align: center;
font-family: "Roboto";
}
:-moz-placeholder {
text-align: center;
}
#navbar {
height: var(--navbar-height);
text-align: center;
align-items: center;
display: flex;
position: fixed;
top: 0;
left: 0;
right: 0;
background-color: var(--navbar-color);
}
.sidenav-btn {
display: none;
}
.sidenav {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: #232133;
padding-top: 60px;
-webkit-transition: 0.5s;
transition: 0.5s;
overflow: hidden;
}
.sidenav a {
padding: 8px 16px 16px 32px;
text-decoration: none;
width: 100vw;
font-size: 24px;
color: #cfcfcf;
display: block;
transition: 0.3s;
}
.sidenav .closebtn {
position: absolute;
top: 0;
right: 25px;
font-size: 36px;
margin-left: 50px;
z-index: 2;
left: 140px;
}
@media only screen and (max-width: 690px) {
/* funny number */
#navbar > ul > li {
display: none;
}
.sidenav-btn {
display: flex;
align-items: center;
position: absolute;
left: 90vw;
width: var(--navbar-height);
height: var(--navbar-height);
}
.sidenav-btn > svg {
width: 50px;
height: 50px;
}
#digitalCLOContainerLI {
display: none;
}
#navbar > ul > li > a > svg {
min-width: 24px;
}
}
a {
color: var(--navbar-link-color);
text-decoration: none !important;
font-family: "Roboto";
}
a:hover {
color: grey;
transition: 0.5s;
cursor: pointer;
}
.down {
background-color: rgb(90, 24, 154);
left: inherit !important;
font-family: "Helvetica";
background-color: var(--navbar-color);
/* box-shadow: 2px 2px rgb(0 0 0 / 20%); */
color: white;
display: none;
visibility: hidden;
opacity: 0;
list-style-type: none;
position: fixed;
border-bottom-right-radius: 10px;
border-bottom-left-radius: 10px;
list-style-type: none;
}
#navbar ul:not(.down) {
font-family: "Helvetica";
/* box-shadow: 2px 2px rgb(0 0 0 / 20%); */
color: white;
margin-left: auto;
list-style-type: none;
float: right !important;
margin-right: 2.3%;
display: flex;
align-items: center;
}
#navbar ul li {
float: left;
padding-top: 1em;
padding-bottom: 1em;
padding-right: 1em;
padding-left: 1em;
padding: 1rem;
}
::placeholder,
input[type="text"] {
color: var(--input-placeholder-color);
font-size: 20px;
text-align: center;
font-family: "Roboto";
}
#navbar ul p,
ul a {
font-weight: bold;
display: flex;
align-items: center;
}
*/
/*
#navbar ul li p, ul li a {
font-weight: normal;
}
*/
#navbar ul li ul {
border-bottom-right-radius: 10px;
border-bottom-left-radius: 10px;
visibility: hidden;
opacity: 0;
margin-top: 1rem;
left: 0;
display: none;
}
#navbar ul li:hover ul,
ul li ul:hover {
visibility: visible;
opacity: 1;
display: block;
}
#navbar ul li p {
color: white;
font-family: "Calibri";
z-index: 3 !important;
}
#navbar ul li ul li {
clear: both;
width: 100%;
}
#content {
display: flex;
justify-content: center;
align-items: center;
height: 98%;
color: white;
flex-direction: column;
font-family: "Roboto";
}
#content h1 {
padding-bottom: 0.5em;
font-weight: 100;
text-align: center;
}
#content img {
padding-left: 0.5em;
filter: brightness(0) invert(1);
}
#content input {
font-size: 20px;
text-align: center;
font-family: "Calibri";
border-style: solid !important;
border: var(--input-border-size) solid var(--input-border-color);
border-width: 1px;
border-radius: 15px;
background-color: var(--input-background-color);
color: var(--input-text-color);
width: 300px;
height: 50px;
box-shadow: none !important;
outline: none;
text-align: center;
font-family: "Roboto";
}
#content input:focus {
outline: none;
box-shadow: none !important;
}
@keyframes inputwide {
0% {
width: 0px;
transition-duration: 0.5s;
}
100% {
width: 300px;
transition-duration: 0.5s;
}
}
.loader {
width: 283px;
text-align: center;
display: none;
justify-content: center;
align-items: center;
flex-direction: row;
transition: 0.1s;
}
svg path,
svg rect {
fill: #eb6f92;
}
.connector {
color: white;
margin-left: 10px;
font-size: 15px;
}
@keyframes popout {
0% {
height: -20px;
}
100% {
height: 0px;
}
}
.nebHeader {
font-family: var(--navbar-font);
color: var(--navbar-text-color);
display: flex;
align-items: center;
justify-content: center;
align-content: center;
flex-wrap: nowrap;
flex-direction: row;
margin-left: 0.5%;
}
html,
body {
margin: 0;
padding: 0;
height: 100%;
}
body {
background-color: var(--background-primary);
color: var(--text-color-primary);
animation: fadeInAnimation ease 1s;
animation-iteration-count: 1;
animation-fill-mode: forwards;
}
@keyframes fadeInAnimation {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
input:focus::placeholder {
color: transparent;
}
#navbar #thumbImg {
transition: width 2s, height 2s, transform 2s;
filter: var(--navbar-logo-filter);
}
#navbar #thumbImg:hover {
transform: rotate(360deg);
}
.stamp {
text-align: right;
position: fixed;
bottom: 0;
font-family: "Montserrat", sans-serif;
font-style: italic;
font-weight: lighter;
color: whitesmoke;
opacity: 90%;
user-select: none;
font-size: 13px;
padding-left: 5px;
padding-bottom: 1px;
cursor: default;
}
.stamp:hover {
text-align: right;
position: fixed;
bottom: 0;
font-family: "Montserrat", sans-serif;
font-style: italic;
font-weight: lighter;
color: whitesmoke;
opacity: 38%;
user-select: none;
font-size: 13px;
padding-left: 5px;
padding-bottom: 1px;
cursor: default;
}
.github {
position: fixed;
right: 0;
bottom: 0;
padding-right: 10px;
}
.tos {
position: fixed;
right: 67px;
bottom: 0;
padding-right: 15px;
}
.privacy {
position: fixed;
right: 114px;
bottom: 0;
padding-right: 15px;
}
.modal-window {
position: fixed;
background-color: rgba(255, 255, 255, 0.25);
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 999;
visibility: hidden;
opacity: 0;
pointer-events: none;
transition: all 0.3s;
font-family: "Montserrat", sans-serif;
}
.modal-window:target {
visibility: visible;
opacity: 1;
pointer-events: auto;
}
.modal-window > div {
width: 400px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: 2em;
background: white;
}
.modal-window header {
font-weight: bold;
}
.modal-window h1 {
font-size: 150%;
margin: 0 0 15px;
}
.modal-close {
color: #aaa;
line-height: 50px;
font-size: 80%;
position: absolute;
right: 0;
text-align: center;
top: 0;
width: 70px;
text-decoration: none;
}
.modal-close:hover {
color: black;
}
.modal-window > div {
border-radius: 1rem;
}
.modal-window div:not(:last-of-type) {
margin-bottom: 15px;
}
.logo {
max-width: 150px;
display: block;
}
small {
color: lightgray;
}
.btn {
background-color: white;
padding: 1em 1.5em;
border-radius: 0.5rem;
text-decoration: none;
}
.btn i {
padding-right: 0.3em;
}
@media only screen and (max-width: 1190px) {
#digitalClock {
display: none;
}
}
.clockColon {
opacity: 100%;
animation: blink 0.5s step-end infinite alternate;
transition: 0.2s;
}
@keyframes blink {
50% {
opacity: 0%;
}
}

View file

@ -1,556 +0,0 @@
@import url("https://fonts.googleapis.com/css2?family=Work+Sans:wght@300&display=swap");
:root {
--background-primary: #191724;
--sidebar-color: #191724;
--sidebar-text-color: #e0def4;
--text-color-primary: #e0def4;
--text-color-secondary: #6e6a86;
--focus-color: #eb6f92;
--header-height: 10vh;
--section-font-size: 20pt;
--section-font: 'Calibri';
--section-padding: 0.5em;
--setting-distance-from-sidebar: 1em;
--setting-distance-from-right: 1em;
--setting-name-font: 'Calibri';
--setting-desc-font: 'Calibri';
}
* {
user-select: none;
}
/*
body {
background-color: var(--background-primary);
}*/
.container {
display: flex;
flex-direction: row;
align-content: center;
flex-wrap: wrap;
justify-content: space-evenly;
align-items: flex-end;
margin-top: 75px;
}
#sidebar {
animation: fadeIn 700ms ease-in 30ms forwards;
-webkit-animation: fadeIn 700ms ease-in 300ms forwards;
position: absolute;
top: var(--header-height);
left: 0;
background-color: var(--sidebar-color);
transition: width 0.5s;
width: var(--sidebar-width);
}
.setting li a {
background-color: #2e2828;
padding: 10px 16px;
border-radius: 5px;
}
.settings-div li a ul {
border-bottom-right-radius: 10px;
border-bottom-left-radius: 10px;
visibility: hidden;
opacity: 0;
margin-top: 10px;
left: 0 !important;
display: none;
}
.settings-div li a:hover ul,
ul li:hover {
visibility: visible;
opacity: 1;
display: block;
}
/*
.settings-div ul li p{
color: white;
font-family: 'Calibri';
z-index: 3 !important;
}*/
li {
list-style-type: none;
}
.settings-div li a ul li {
clear: both;
width: 100%;
}
.section {
background-color: transparent;
color: var(--sidebar-text-color);
font-size: var(--section-font-size);
font-family: var(--section-font);
width: 100%;
transition: background-color 0.5s;
padding-top: var(--section-padding);
padding-bottom: var(--section-padding);
}
.section:hover {
background-color: #ffffff20;
}
.settings-div {
position: absolute;
left: calc(var(--sidebar-width) + var(--setting-distance-from-sidebar));
top: 0;
width: calc(100vw - var(--sidebar-width) - var(--setting-distance-from-sidebar));
padding-top: 5%;
}
.setting-input {
/* left: 100%; */
color: black !important;
position: relative;
/* right: 0; */
transform: translateY(-1.5em);
float: right;
margin-right: 5%;
}
.setting-input {
display: none;
}
@import url('https://fonts.googleapis.com/css2?family=Mulish:wght@300&display=swap');
.toogle-button {
font-weight: bold;
font-size: 10PX;
display: inline-block;
width: 75px;
height: 35px;
background-color: #dfddf3;
border-radius: 30px;
position: relative;
cursor: pointer;
}
.toogle-button::after {
content: 'Off';
width: 40px;
height: 40px;
color: #E7E2CD;
background-color: #e14343;
border: 2px solid #E7E2CD;
border-radius: 50%;
box-shadow: 0 0 5px rgb(0 0 0 / 25%);
position: absolute;
top: -3px;
left: 0;
line-height: 0;
display: grid;
place-content: center;
transition: all .5s;
transform: 1s ease-in;
font-family: 'Mulish', sans-serif;
}
.setting-input:checked+.toogle-button::after {
content: 'On';
background-color: #53b357;
transform: translateX(35px) rotate(360deg);
}
ul li {
float: left;
padding-top: 1em;
padding-bottom: 1em;
padding-right: 1em;
padding-left: 1em;
padding: 1rem;
}
.button {
width: 30px;
height: 30px;
transform: translateY(-30px);
font-family: var(--setting-desc-font);
color: white;
}
@-webkit-keyframes fadeIn {
0% {
opacity: 0.01;
}
100% {
opacity: 1;
}
}
@keyframes fadeIn {
0% {
opacity: 0.01;
}
100% {
opacity: 1;
}
}
@import url('https://fonts.googleapis.com/css?family=Roboto:400,500&display=swap');
.notification-container {
position: fixed;
top: 4px;
right: 5px;
width: 500px;
max-width: calc(100% - 30px);
font-family: 'Roboto', sans-serif;
}
.notification {
background-color: #fff;
border-radius: 5px;
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);
color: #fff;
font-size: 16px;
padding: 15px 20px;
line-height: 20px;
margin-bottom: 15px;
animation: grow 0.5s ease-in forwards;
}
@keyframes grow {
from {
opacity: 0;
transform: scale(0.8);
}
to {
opacity: 1;
transform: scale(1);
}
}
.notification.hide {
animation: shrink 0.3s ease-out forwards;
}
@keyframes shrink {
to {
opacity: 0;
transform: scale(0.8);
}
}
.notification strong {
font-size: 12px;
line-height: 20px;
letter-spacing: 0.5px;
text-transform: uppercase;
}
.notification-info {
background-color: #00cae3;
}
.notification-success {
background-color: #3d3571;
}
.notification-warning {
background-color: #ff9e0f;
}
.notification-danger {
background-color: #f55145;
}
.stamp {
position: fixed;
bottom: 0;
}
.bk-btn {
height: 52px;
width: 52px;
background-color: black;
border-radius: 50%;
}
.bk-btn .bk-btn-triangle {
position: relative;
top: 13px;
left: 10.4px;
width: 0;
height: 0;
border-top: 13px solid transparent;
border-bottom: 13px solid transparent;
border-right: 13px solid white;
}
.bk-btn .bk-btn-bar {
position: relative;
background-color: white;
height: 7.8px;
width: 13px;
top: -3.64px;
left: 22.88px;
}
@import url('https://fonts.googleapis.com/css2?family=Ubuntu:wght@300&display=swap');
.settings-cont {
background: #45454521;
box-sizing: border-box;
width: 300px;
height: 246px;
padding: 30px;
border: 2px solid rgb(0 0 0 / 64%);
border-radius: 9px;
margin-top: 20px;
display: flex;
align-items: center;
flex-wrap: wrap;
flex-direction: row;
justify-content: center;
}
.name {
color: var(--text-color-primary);
font-size: 27px;
margin: 0;
font-family: 'Ubuntu', sans-serif;
font-weight: 700;
font-style: bold;
}
.description {
color: var(--text-color-secondary);
margin: 0;
font-size: 17px;
font-family: 'Ubuntu', sans-serif;
font-weight: 300;
/* font-style: Italic; */
text-align: center;
}
.secondary-desc {
color: var(--text-color-primary);
margin: 0;
margin-top: 0.3em;
font-size: 18px;
font-family: 'Ubuntu', sans-serif;
font-weight: 300;
/* font-style: Italic; */
text-align: center;
}
@import url('https://fonts.googleapis.com/css2?family=Oxygen:wght@700&display=swap');
.new-tag {
font-size: 16px;
color: rgb(226, 68, 68);
font-family: 'Oxygen', sans-serif;
}
.square {
width: .7em;
height: .7em;
margin: .5em;
}
/* Custom dropdown */
.custom-dropdown {
position: relative;
display: inline-block;
vertical-align: middle;
margin: 10px;
/* demo only */
}
.custom-dropdown select {
background-color: rgb(121 103 221);
color: var(--text-color-primary);
font-size: inherit;
padding: .5em;
padding-right: 2.5em;
border: 0;
margin: 0;
border-radius: 3px;
text-indent: 0.01px;
text-overflow: '';
-webkit-appearance: button;
/* hide default arrow in chrome OSX */
-webkit-appearance: none;
}
.custom-dropdown::before,
.custom-dropdown::after {
content: "";
position: absolute;
pointer-events: none;
}
.custom-dropdown::after {
/* Custom dropdown arrow */
content: "\25BC";
height: 1em;
font-size: .625em;
line-height: 1;
right: 1.2em;
top: 50%;
margin-top: -.5em;
}
.custom-dropdown::before {
/* Custom dropdown arrow cover */
width: 2em;
right: 0;
top: 0;
bottom: 0;
border-radius: 0 3px 3px 0;
}
.custom-dropdown select[disabled] {
color: rgba(0, 0, 0, .3);
}
.custom-dropdown select[disabled]::after {
color: rgba(0, 0, 0, .1);
}
.custom-dropdown::before {
background-color: rgba(0, 0, 0, .15);
}
.custom-dropdown::after {
color: rgba(0, 0, 0, .4);
}
.button-save {
background-color: #5e18eb;
color: #fff;
font-size: inherit;
padding: 0.5em;
padding-right: -0.5em;
border: 0;
margin: 0;
border-radius: 3px;
text-indent: 0.01px;
text-overflow: '';
-webkit-appearance: button;
cursor: pointer;
}
.button-save-alt {
background-color: #5e18eb;
color: #fff;
font-size: inherit;
padding: 0.3em;
padding-right: -0.5em;
border: 0;
margin: 0.2vh;
border-radius: 3px;
text-indent: 0.01px;
text-overflow: '';
-webkit-appearance: button;
cursor: pointer;
}
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@100&display=swap');
.expiramental {
font-family: 'Roboto', sans-serif;
font-size: 10px;
color: rgb(184, 0, 0);
font-weight: 400;
text-decoration: underline;
}
input[type=checkbox] {
height: 0;
width: 0;
visibility: hidden;
}
label {
cursor: pointer;
/* text-indent: -10049px; */
width: 85px;
height: 37px;
background: #504e58;
display: block;
border-radius: 100px;
position: relative;
}
label:after {
content: '';
position: absolute;
top: 5px;
left: 5px;
width: 35px;
height: 28px;
background: #3d3571;
border-radius: 90px;
transition: 0.3s;
}
input:checked+label {
background: #7967dd;
}
input:checked+label:after {
left: calc(100% - 5px);
transform: translateX(-100%);
}
label:active:after {
width: 38px;
}
.bareLocationInput {
border-style: solid !important;
border: var(--input-border-size) solid #5e18eb;
border-width: 0px;
border-radius: 6px;
background-color: #191724;
color: var(--input-text-color);
width: auto;
height: auto;
box-shadow: none !important;
outline: none;
text-align: center;
width: 220px;
font-size: 16px;
font-family: 'Roboto';
height: 29px;
transition: 0.06s;
}
.bareLocationInput:hover {
border: var(--input-border-size) solid #5e18eb;
border-width: 1px;
border-radius: 6px;
}
.bareValidSignal {
margin-top: -13px;
color: #f45145bd;
font-family: 'Ubuntu', sans-serif;
font-weight: lighter;
font-size: 13px;
text-align: center;
}

View file

@ -1,5 +0,0 @@
body {
color: white;
font-family: "Roboto";
margin-left: 20px;
}

View file

@ -1,14 +1,75 @@
importScripts("./uv/uv.bundle.js");
importScripts("./uv/uv.config.js");
importScripts("./uv/uv.sw.js");
importScripts("./osana/osana.worker.js");
importScripts("/uv/uv.bundle.js");
importScripts("/uv/uv.config.js");
importScripts('/scram/scramjet.wasm.js');
importScripts('/scram/scramjet.shared.js');
importScripts('/scram/scramjet.worker.js');
importScripts("/workerware/workerware.js");
importScripts(__uv$config.sw || "/uv/uv.sw.js");
const uv = new UVServiceWorker();
const ww = new WorkerWare({ debug: false });
const sj = new ScramjetServiceWorker();
(async function () {
await sj.loadConfig();
})();
//me when Firefox (thanks vk6)
if (navigator.userAgent.includes("Firefox")) {
Object.defineProperty(globalThis, "crossOriginIsolated", {
value: true,
writable: true
});
}
const UV = new UVServiceWorker();
const Osana = new OsanaServiceWorker();
self.addEventListener("fetch", (event) => {
if (event.request.url.startsWith(location.origin + "/service/go/"))
event.respondWith(UV.fetch(event));
if (event.request.url.startsWith(location.origin + "/service/~osana/"))
event.respondWith(Osana.fetch(event));
//where we handle our plugins!!!
self.addEventListener("message", function (event) {
console.log(event.data);
uv.config.inject = [];
//loop over the required data (we don't verify here as types will take care of us :D)
event.data.forEach((data) => {
if (data.remove) {
if (data.type === "page") {
const idx = uv.config.inject.indexOf(data.host);
uv.config.inject.splice(idx, 1);
} else if (data.type === "serviceWorker") {
ww.deleteByName(data.name);
}
} else {
if (data.type === "page") {
uv.config.inject.push({
host: data.host,
html: data.html,
injectTo: data.injectTo
});
} else if (data.type === "serviceWorker") {
const wwFunction = eval(data.function);
ww.use({
function: wwFunction ? wwFunction : new Function(data.function),
name: data.name,
events: data.events
});
} else {
console.error("NO type exists for that. Only serviceWorker & page exist.");
return;
}
}
});
});
self.addEventListener("fetch", function (event) {
event.respondWith(
(async () => {
const wwRes = await ww.run(event)();
if (wwRes.includes(null)) {
return;
}
if (event.request.url.startsWith(location.origin + __uv$config.prefix)) {
return await uv.fetch(event);
}
else if (sj.route(event)) {
return await sj.fetch(event);
}
else {
return await fetch(event.request);
}
})()
);
});

View file

@ -1,10 +1,30 @@
self.__uv$config = {
prefix: "/service/go/",
bare: "/bare/",
encodeUrl: Ultraviolet.codec.xor.encode,
decodeUrl: Ultraviolet.codec.xor.decode,
handler: "/uv/uv.handler.js",
bundle: "/uv/uv.bundle.js",
config: "/uv/uv.config.js",
sw: "/uv/uv.sw.js"
prefix: "/~/uv/",
bare: "/bare/",
encodeUrl: function encode(str) {
if (!str) return str;
return encodeURIComponent(
str
.toString()
.split("")
.map((char, ind) => (ind % 2 ? String.fromCharCode(char.charCodeAt() ^ 3) : char))
.join("")
);
},
decodeUrl: function decode(str) {
if (!str) return str;
let [input, ...search] = str.split("?");
return (
decodeURIComponent(input)
.split("")
.map((char, ind) => (ind % 2 ? String.fromCharCode(char.charCodeAt(0) ^ 3) : char))
.join("") + (search.length ? "?" + search.join("?") : "")
);
},
handler: "/uv/uv.handler.js",
client: "/uv/uv.client.js",
bundle: "/uv/uv.bundle.js",
config: "/uv/uv.config.js",
sw: "/uv/uv.sw.js"
};

View file

@ -0,0 +1,171 @@
importScripts("/workerware/WWError.js");
const dbg = console.log.bind(console, "[WorkerWare]");
const time = console.time.bind(console, "[WorkerWare]");
const timeEnd = console.timeEnd.bind(console, "[WorkerWare]");
/*
OPTS:
debug - Enables debug logging.
randomNames - Generate random names for middlewares.
timing - Logs timing for each middleware.
*/
const defaultOpt = {
debug: false,
randomNames: false,
timing: false
};
const validEvents = [
"abortpayment",
"activate",
"backgroundfetchabort",
"backgroundfetchclick",
"backgroundfetchfail",
"backgroundfetchsuccess",
"canmakepayment",
"contentdelete",
"cookiechange",
"fetch",
"install",
"message",
"messageerror",
"notificationclick",
"notificationclose",
"paymentrequest",
"periodicsync",
"push",
"pushsubscriptionchange",
"sync"
];
class WorkerWare {
constructor(opt) {
this._opt = Object.assign({}, defaultOpt, opt);
this._middlewares = [];
}
info() {
return {
version: "0.1.0",
middlewares: this._middlewares,
options: this._opt
};
}
use(middleware) {
let validateMW = this.validateMiddleware(middleware);
if (validateMW.error) throw new WWError(validateMW.error);
// This means the middleware is an anonymous function, or the user is silly and named their function "function"
if (middleware.function.name == "function") middleware.name = crypto.randomUUID();
if (!middleware.name) middleware.name = middleware.function.name;
if (this._opt.randomNames) middleware.name = crypto.randomUUID();
if (this._opt.debug) dbg("Adding middleware:", middleware.name);
this._middlewares.push(middleware);
}
// Run all middlewares for the event type passed in.
run(event) {
const middlewares = this._middlewares;
const returnList = [];
let fn = async () => {
for (let i = 0; i < middlewares.length; i++) {
if (middlewares[i].events.includes(event.type)) {
if (this._opt.timing) console.time(middlewares[i].name);
// Add the configuration to the event object.
event.workerware = {
config: middlewares[i].configuration || {}
};
if (!middlewares[i].explicitCall) {
let res = await middlewares[i].function(event);
if (this._opt.timing) console.timeEnd(middlewares[i].name);
returnList.push(res);
}
}
}
return returnList;
};
return fn;
}
deleteByName(middlewareID) {
if (this._opt.debug) dbg("Deleting middleware:", middlewareID);
this._middlewares = this._middlewares.filter((mw) => mw.name !== middlewareID);
}
deleteByEvent(middlewareEvent) {
if (this._opt.debug) dbg("Deleting middleware by event:", middlewareEvent);
this._middlewares = this._middlewares.filter((mw) => !mw.events.includes(middlewareEvent));
}
get() {
return this._middlewares;
}
/*
Run a single middleware by ID.
This assumes that the user knows what they're doing, and is running the middleware on an event that it's supposed to run on.
*/
runMW(name, event) {
const middlewares = this._middlewares;
if (this._opt.debug) dbg("Running middleware:", name);
// if (middlewares.includes(name)) {
// return middlewares[name](event);
// } else {
// throw new WWError("Middleware not found!");
// }
let didCall = false;
for (let i = 0; i < middlewares.length; i++) {
if (middlewares[i].name == name) {
didCall = true;
event.workerware = {
config: middlewares[i].configuration || {}
};
if (this._opt.timing) console.time(middlewares[i].name);
let call = middlewares[i].function(event);
if (this._opt.timing) console.timeEnd(middlewares[i].name);
return call;
}
}
if (!didCall) {
throw new WWError("Middleware not found!");
}
}
// type middlewareManifest = {
// function: Function,
// name?: string,
// events: string[], // Should be a union of validEvents.
// configuration?: Object // Optional configuration for the middleware.
// }
validateMiddleware(middleware) {
if (!middleware.function)
return {
error: "middleware.function is required"
};
if (typeof middleware.function !== "function")
return {
error: "middleware.function must be typeof function"
};
if (
typeof middleware.configuration !== "object" &&
middleware.configuration !== undefined
) {
return {
error: "middleware.configuration must be typeof object"
};
}
if (!middleware.events)
return {
error: "middleware.events is required"
};
if (!Array.isArray(middleware.events))
return {
error: "middleware.events must be an array"
};
if (middleware.events.some((ev) => !validEvents.includes(ev)))
return {
error: "Invalid event type! Must be one of the following: " + validEvents.join(", ")
};
if (middleware.explicitCall && typeof middleware.explicitCall !== "boolean") {
return {
error: "middleware.explicitCall must be typeof boolean"
};
}
return {
error: undefined
};
}
}

95
server/config.ts Normal file
View file

@ -0,0 +1,95 @@
import { readFileSync } from "node:fs";
import { fileURLToPath } from "node:url";
import chalk from "chalk";
import { TomlPrimitive, parse } from "smol-toml";
interface TomlData {
marketplace: {
enabled: boolean;
psk: String;
};
server: {
server: {
port: number;
wisp: boolean;
logging: boolean;
};
};
seo: {
enabled: boolean;
domain: string;
};
db: {
name: string;
username: string;
password: string;
postgres: boolean;
};
postgres: {
domain: string;
port: number;
};
}
interface Verify {
name: string;
typeOF: any;
type: any;
verifyExtras?: () => boolean | Error;
}
let doc = readFileSync(fileURLToPath(new URL("../config.toml", import.meta.url))).toString();
const parsedDoc = parse(doc) as unknown as TomlData;
function verify(t: Verify[]) {
for (let i: number = 0; i !== t.length; i++) {
if (typeof t[i].typeOF !== t[i].type) {
throw new Error(`Invalid structure: "${t[i].name}" should be a(n) ${t[i].type}`);
}
if (t[i].verifyExtras) {
const extra = t[i].verifyExtras();
if (extra !== true) {
throw extra;
}
}
}
}
verify([
{ name: "marketplace", typeOF: parsedDoc.marketplace, type: "object" },
{ name: "marketplace.enabled", typeOF: parsedDoc.marketplace.enabled, type: "boolean" },
{ name: "marketplace.psk", typeOF: parsedDoc.marketplace.psk, type: "string" },
{ name: "server", typeOF: parsedDoc.server, type: "object" },
{ name: "server.server", typeOF: parsedDoc.server.server, type: "object" },
{ name: "server.server.port", typeOF: parsedDoc.server.server.port, type: "number" },
{ name: "server.server.wisp", typeOF: parsedDoc.server.server.wisp, type: "boolean" },
{ name: "server.server.logging", typeOF: parsedDoc.server.server.logging, type: "boolean" },
{ name: "seo", typeOF: parsedDoc.seo, type: "object" },
{ name: "seo.enabled", typeOF: parsedDoc.seo.enabled, type: "boolean" },
{ name: "seo.domain", typeOF: parsedDoc.seo.domain, type: "string", verifyExtras: () => {
try {
new URL(parsedDoc.seo.domain);
}
catch (e) {
return Error(e);
}
return true;
}},
{ name: "db", typeOF: parsedDoc.db, type: "object" },
{ name: "db.name", typeOF: parsedDoc.db.name, type: "string" },
{ name: "db.username", typeOF: parsedDoc.db.username, type: "string" },
{ name: "db.password", typeOF: parsedDoc.db.password, type: "string" },
{ name: "db.postgres", typeOF: parsedDoc.db.postgres, type: "boolean" },
{ name: "postgres", typeOF: parsedDoc.postgres, type: "object" },
{ name: "postgres.domain", typeOF: parsedDoc.postgres.domain, type: "string" },
{ name: "postgres.port", typeOF: parsedDoc.postgres.port, type: "number" }
]);
if (parsedDoc.marketplace.psk === "CHANGEME") {
console.warn(chalk.yellow.bold('PSK should be changed from "CHANGEME"'));
}
if (parsedDoc.db.password === "password") {
console.warn(chalk.red.bold("You should change your DB password!!"));
}
export { TomlData, parsedDoc };

98
server/dbSetup.ts Normal file
View file

@ -0,0 +1,98 @@
import { fileURLToPath } from "node:url";
import chalk from "chalk";
import ora from "ora";
import { ModelStatic } from "sequelize";
import { Catalog, CatalogModel } from "./marketplace.js";
interface Items extends Omit<Catalog, "background_video" | "background_image"> {
background_video?: string;
background_image?: string;
}
async function installItems(db: ModelStatic<CatalogModel>, items: Items[]) {
items.forEach(async (item) => {
await db.create({
package_name: item.package_name,
title: item.title,
image: item.image,
author: item.author,
version: item.version,
description: item.description,
tags: item.tags,
payload: item.payload,
background_video: item.background_video,
background_image: item.background_image,
type: item.type
});
});
}
async function setupDB(db: ModelStatic<CatalogModel>) {
//We have some packages that need to be installed if they aren't.
const items: Items[] = [
{
package_name: "com.nebula.gruvbox",
title: "Gruvbox",
image: "gruvbox.jpg",
author: "Nebula Services",
version: "1.0.0",
description: "The gruvbox theme",
tags: ["Theme", "Simple"],
payload: "gruvbox.css",
type: "theme"
},
{
package_name: "com.nebula.oled",
title: "Oled theme",
image: "oled.jpg",
author: "Nebula Services",
version: "1.0.0",
description: "A sleek & simple Oled theme for Nebula",
tags: ["Theme", "Simple", "Sleek"],
payload: "oled.css",
type: "theme"
},
{
package_name: "com.nebula.lightTheme",
title: "Light Theme",
image: "light.png",
author: "Nebula Services",
version: "1.0.0",
description: "A sleek light theme for Nebula",
tags: ["Theme", "Simple", "Light"],
payload: "light.css",
type: "theme"
},
{
package_name: "com.nebula.retro",
title: "Retro Theme",
image: "retro.png",
author: "Nebula Services",
version: "1.0.0",
description: "Give a retro look to Nebula",
tags: ["Theme", "Simple", "Dark", "Retro"],
payload: "retro.css",
type: "theme"
},
/* {
package_name: 'gyatt',
title: 'gyatt',
image: 'gyatt',
author: "nebuka",
version: "2",
description: "e",
tags: [ "e" ],
payload: "gyatt.js",
type: "plugin-page"
} */
//To add plugins: plugin types consist of plugin-sw (workerware) & plugin-page (uv.config.inject)
];
const dbItems = await db.findAll();
if (dbItems.length === 0) {
const spinner = ora(chalk.hex("#7967dd")("Performing DB setup...")).start();
await installItems(db, items);
spinner.succeed(chalk.hex("#eb6f92")("DB setup complete!"));
}
}
export { setupDB };

1
server/env.d.ts vendored Normal file
View file

@ -0,0 +1 @@
declare module "@rubynetwork/rammerhead/src/server/index.js";

229
server/marketplace.ts Normal file
View file

@ -0,0 +1,229 @@
import { createWriteStream } from "node:fs";
import { constants, access, mkdir } from "node:fs/promises";
import { pipeline } from "node:stream/promises";
import { fileURLToPath } from "node:url";
import { FastifyInstance, FastifyRequest } from "fastify";
import { DataTypes, InferAttributes, InferCreationAttributes, Model, Sequelize } from "sequelize";
import { parsedDoc } from "./config.js";
const db = new Sequelize(parsedDoc.db.name, parsedDoc.db.username, parsedDoc.db.password, {
host: parsedDoc.db.postgres ? `${parsedDoc.postgres.domain}` : "localhost",
port: parsedDoc.db.postgres ? parsedDoc.postgres.port : undefined,
dialect: parsedDoc.db.postgres ? "postgres" : "sqlite",
logging: parsedDoc.server.server.logging,
storage: "database.sqlite" //this is sqlite only
});
type CatalogType = "theme" | "plugin-page" | "plugin-sw";
interface Catalog {
package_name: string;
title: string;
description: string;
author: string;
image: string;
tags: object;
version: string;
background_image: string;
background_video: string;
payload: string;
type: CatalogType;
}
interface CatalogModel
extends Catalog,
Model<InferAttributes<CatalogModel>, InferCreationAttributes<CatalogModel>> {}
const catalogAssets = db.define<CatalogModel>("catalog_assets", {
package_name: { type: DataTypes.STRING, unique: true },
title: { type: DataTypes.TEXT },
description: { type: DataTypes.TEXT },
author: { type: DataTypes.TEXT },
image: { type: DataTypes.TEXT },
tags: { type: DataTypes.JSON, allowNull: true },
version: { type: DataTypes.TEXT },
background_image: { type: DataTypes.TEXT, allowNull: true },
background_video: { type: DataTypes.TEXT, allowNull: true },
payload: { type: DataTypes.TEXT },
type: { type: DataTypes.TEXT }
});
function marketplaceAPI(app: FastifyInstance) {
app.get("/api/catalog-stats/", (request, reply) => {
reply.send({
version: "1.0.0",
spec: "Nebula Services",
enabled: true
});
});
// This API returns a list of the assets in the database (SW plugins and themes).
// It also returns the number of pages in the database.
// It can take a `?page=x` argument to display a different page, with a limit of 20 assets per page.
type CatalogAssetsReq = FastifyRequest<{ Querystring: { page: string } }>;
app.get("/api/catalog-assets/", async (request: CatalogAssetsReq, reply) => {
try {
const { page } = request.query;
const pageNum: number = parseInt(page, 10) || 1;
if (pageNum < 1) {
reply.status(400).send({ error: "Page must be a positive number!" });
}
const offset = (pageNum - 1) * 20;
const totalItems = await catalogAssets.count();
const dbAssets = await catalogAssets.findAll({ offset: offset, limit: 20 });
const assets = dbAssets.reduce((acc, asset) => {
acc[asset.package_name] = {
title: asset.title,
description: asset.description,
author: asset.author,
image: asset.image,
tags: asset.tags,
version: asset.version,
background_image: asset.background_image,
background_video: asset.background_video,
payload: asset.payload,
type: asset.type
};
return acc;
}, {});
return reply.send({ assets, pages: Math.ceil(totalItems / 20) });
} catch (error) {
return reply.status(500).send({ error: "An error occured" });
}
});
type PackageReq = FastifyRequest<{ Params: { package: string } }>;
app.get("/api/packages/:package", async (request: PackageReq, reply) => {
try {
const packageRow = await catalogAssets.findOne({
where: { package_name: request.params.package }
});
if (!packageRow) return reply.status(404).send({ error: "Package not found!" });
const details = {
title: packageRow.get("title"),
description: packageRow.get("description"),
image: packageRow.get("image"),
author: packageRow.get("author"),
tags: packageRow.get("tags"),
version: packageRow.get("version"),
background_image: packageRow.get("background_image"),
background_video: packageRow.get("background_video"),
payload: packageRow.get("payload"),
type: packageRow.get("type")
};
reply.send(details);
} catch (error) {
reply.status(500).send({ error: "An unexpected error occured" });
}
});
type UploadReq = FastifyRequest<{ Headers: { psk: string; packagename: string } }>;
type CreateReq = FastifyRequest<{
Headers: { psk: string };
Body: {
uuid: string;
title: string;
image: string;
author: string;
version: string;
description: string;
tags: object | any;
payload: string;
background_video: string;
background_image: string;
type: CatalogType;
};
}>;
interface VerifyStatus {
status: number;
error?: Error;
}
async function verifyReq(
request: UploadReq | CreateReq,
upload: Boolean,
data: any
): Promise<VerifyStatus> {
if (request.headers.psk !== parsedDoc.marketplace.psk) {
return { status: 403, error: new Error("PSK isn't correct!") };
} else if (upload && !request.headers.packagename) {
return { status: 500, error: new Error("No packagename defined!") };
} else if (upload && !data) {
return { status: 400, error: new Error("No file uploaded!") };
} else {
return { status: 200 };
}
}
app.post("/api/upload-asset", async (request: UploadReq, reply) => {
const data = await request.file();
const verify: VerifyStatus = await verifyReq(request, true, data);
if (verify.error !== undefined) {
reply.status(verify.status).send({ status: verify.error.message });
} else {
try {
await pipeline(
data.file,
createWriteStream(
fileURLToPath(
new URL(
`../database_assets/${request.headers.packagename}/${data.filename}`,
import.meta.url
)
)
)
);
} catch (error) {
return reply.status(500).send({
status: `File couldn't be uploaded! (Package most likely doesn't exist)`
});
}
return reply.status(verify.status).send({ status: "File uploaded successfully!" });
}
});
app.post("/api/create-package", async (request: CreateReq, reply) => {
const verify: VerifyStatus = await verifyReq(request, false, undefined);
if (verify.error !== undefined) {
reply.status(verify.status).send({ status: verify.error.message });
} else {
const body: Catalog = {
package_name: request.body.uuid,
title: request.body.title,
image: request.body.image,
author: request.body.author,
version: request.body.version,
description: request.body.description,
tags: request.body.tags,
payload: request.body.payload,
background_video: request.body.background_video,
background_image: request.body.background_image,
type: request.body.type as CatalogType
};
await catalogAssets.create({
package_name: body.package_name,
title: body.title,
image: body.image,
author: body.author,
version: body.version,
description: body.description,
tags: body.tags,
payload: body.payload,
background_video: body.background_video,
background_image: body.background_image,
type: body.type
});
const assets = fileURLToPath(new URL("../database_assets", import.meta.url));
try {
await access(`${assets}/${body.package_name}/`, constants.F_OK);
return reply.status(500).send({ status: "Package already exists!" });
} catch (err) {
await mkdir(`${assets}/${body.package_name}/`);
return reply
.status(verify.status)
.send({ status: "Package created successfully!" });
}
}
});
}
export { marketplaceAPI, db, catalogAssets, Catalog, CatalogModel };

93
server/server.ts Normal file
View file

@ -0,0 +1,93 @@
import { createWriteStream } from "node:fs";
import { constants, access, mkdir } from "node:fs/promises";
import { pipeline } from "node:stream/promises";
import { fileURLToPath } from "node:url";
import fastifyCompress from "@fastify/compress";
import fastifyHelmet from "@fastify/helmet";
import fastifyMiddie from "@fastify/middie";
import fastifyMultipart from "@fastify/multipart";
import fastifyStatic from "@fastify/static";
import chalk from "chalk";
import Fastify, { FastifyReply, FastifyRequest } from "fastify";
import gradient from "gradient-string";
//@ts-ignore WHY would I want this typechecked AT ALL
import { handler as ssrHandler } from "../dist/server/entry.mjs";
import { parsedDoc } from "./config.js";
import { setupDB } from "./dbSetup.js";
import { catalogAssets, marketplaceAPI } from "./marketplace.js";
import { serverFactory } from "./serverFactory.js";
const app = Fastify({
logger: parsedDoc.server.server.logging,
ignoreDuplicateSlashes: true,
ignoreTrailingSlash: true,
serverFactory: serverFactory
});
await app.register(fastifyCompress, {
encodings: ["br", "gzip", "deflate"]
});
await app.register(fastifyMultipart, {
limits: {
fileSize: 25 * 1024 * 1024,
parts: Infinity
},
});
await app.register(fastifyHelmet, {
xPoweredBy: false,
crossOriginEmbedderPolicy: true,
crossOriginOpenerPolicy: true,
contentSecurityPolicy: false //Disabled because astro DOES NOT LIKE IT
});
await app.register(fastifyStatic, {
root: fileURLToPath(new URL("../dist/client", import.meta.url))
});
//Our marketplace API. Not middleware as I don't want to deal with that LOL. Just a function that passes our app to it.
if (parsedDoc.marketplace.enabled) {
await app.register(fastifyStatic, {
root: fileURLToPath(new URL("../database_assets", import.meta.url)),
prefix: "/packages/",
decorateReply: false
});
marketplaceAPI(app);
}
await app.register(fastifyMiddie);
app.use(ssrHandler);
const port: number =
parseInt(process.env.PORT as string) || parsedDoc.server.server.port || parseInt("8080");
const titleText = `
_ _ _ _ ____ _
| \\ | | ___| |__ _ _| | __ _ / ___| ___ _ ____ _(_) ___ ___ ___
| \\| |/ _ \\ '_ \\| | | | |/ _' | \\___ \\ / _ \\ '__\\ \\ / / |/ __/ _ \\/ __|
| |\\ | __/ |_) | |_| | | (_| | ___) | __/ | \\ V /| | (_| __/\\__ \\
|_| \\_|\\___|_.__/ \\__,_|_|\\__,_| |____/ \\___|_| \\_/ |_|\\___\\___||___/
`;
const titleColors = {
purple: "#7967dd",
pink: "#eb6f92"
};
console.log(gradient(Object.values(titleColors)).multiline(titleText as string));
app.listen({ port: port, host: "0.0.0.0" }).then(async () => {
console.log(
chalk.hex("#7967dd")(
`Server listening on ${chalk.hex("#eb6f92").bold("http://localhost:" + port + "/")}`
)
);
console.log(
chalk.hex("#7967dd")(
`Server also listening on ${chalk.hex("#eb6f92").bold("http://0.0.0.0:" + port + "/")}`
)
);
if (parsedDoc.marketplace.enabled) {
await catalogAssets.sync();
await setupDB(catalogAssets);
}
});

29
server/serverFactory.ts Normal file
View file

@ -0,0 +1,29 @@
import { createServer } from "node:http";
import { FastifyServerFactory, FastifyServerFactoryHandler, RawServerDefault } from "fastify";
import wisp from "wisp-server-node";
import { LOG_LEVEL, WispOptions } from "wisp-server-node/dist/Types.js";
import { parsedDoc } from "./config.js";
const wispOptions: WispOptions = {
logLevel: parsedDoc.server.server.logging ? LOG_LEVEL.DEBUG : LOG_LEVEL.NONE,
pingInterval: 30
};
const serverFactory: FastifyServerFactory = (
handler: FastifyServerFactoryHandler
): RawServerDefault => {
const httpServer = createServer();
httpServer.on("request", (req, res) => {
handler(req, res);
});
httpServer.on("upgrade", (req, socket, head) => {
if (parsedDoc.server.server.wisp) {
if (req.url?.endsWith("/wisp/")) {
wisp.routeRequest(req, socket as any, head, wispOptions);
}
}
});
return httpServer;
};
export { serverFactory };

11
server/tsconfig.json Normal file
View file

@ -0,0 +1,11 @@
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "bundler",
"noEmit": false,
"esModuleInterop": true,
"skipLibCheck": true,
"paths": {}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
src/assets/credits/uv.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
src/assets/fortnite.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

61
src/components/Card.astro Normal file
View file

@ -0,0 +1,61 @@
---
interface Props {
title: string;
body: string;
href: string;
}
const { href, title, body } = Astro.props;
---
<li class="link-card">
<a href={href}>
<h2>
{title}
<span>&rarr;</span>
</h2>
<p>
{body}
</p>
</a>
</li>
<style>
.link-card {
list-style: none;
display: flex;
padding: 1px;
background-color: #23262d;
background-image: none;
background-size: 400%;
border-radius: 7px;
background-position: 100%;
transition: background-position 0.6s cubic-bezier(0.22, 1, 0.36, 1);
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1);
}
.link-card > a {
width: 100%;
text-decoration: none;
line-height: 1.4;
padding: calc(1.5rem - 1px);
border-radius: 8px;
color: white;
background-color: #23262d;
opacity: 0.8;
}
h2 {
margin: 0;
font-size: 1.25rem;
transition: color 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}
p {
margin-top: 0.5rem;
margin-bottom: 0;
}
.link-card:is(:hover, :focus-within) {
background-position: 0;
background-image: var(--accent-gradient);
}
.link-card:is(:hover, :focus-within) h2 {
color: rgb(var(--accent-light));
}
</style>

View file

@ -0,0 +1,71 @@
---
import { MARKETPLACE_ENABLED } from "astro:env/client";
import { Icon } from "astro-icon/components";
import { getLangFromUrl, useTranslations } from "../i18n/utils";
import HeaderButton from "./HeaderButton.astro";
import Logo from "./Logo.astro";
const lang = getLangFromUrl(Astro.url);
const t = useTranslations(lang);
---
<div
id="navbar"
class="flex h-16 flex-row items-center justify-end border-b-2 border-border-color bg-navbar-color px-4 z-30 relative"
>
<div class="w-1/8">
{/* Typical desktop menu */}
<div class="relative flex-row hidden lg:flex">
<HeaderButton text={t("header.home")} route={`/${lang}/`}>
<Icon
name="ph:house-bold"
class="h-6 w-6 text-text-color transition duration-500 group-hover:text-text-hover-color md:h-6 md:w-6"
/>
</HeaderButton>
<HeaderButton text={t("header.games")} route={`/${lang}/games/`}>
<Icon
name="ph:cube"
class="h-6 w-6 text-text-color transition duration-500 group-hover:text-text-hover-color md:h-6 md:w-6"
/>
{
/* Astro won't let us pass the icon as a prop so it's going into the outlet here. */
}
</HeaderButton>
<HeaderButton
text={t("header.settings")}
route={`/${lang}/settings/appearance`}
>
<Icon
name="ph:wrench-fill"
class="h-6 w-6 text-text-color transition duration-500 group-hover:text-text-hover-color md:h-6 md:w-6"
/>
</HeaderButton>
{MARKETPLACE_ENABLED &&
<HeaderButton text={t("header.catalog")} route={`/${lang}/catalog/1`}>
<Icon
name="ph:shopping-bag-open-fill"
class="h-6 w-6 text-text-color transition duration-500 group-hover:text-text-hover-color md:h-6 md:w-6"
/>
</HeaderButton>
}
<HeaderButton text={t("header.morelinks")}>
<Icon
name="ph:link-bold"
class="h-6 w-6 text-text-color transition duration-500 group-hover:text-text-hover-color md:h-6 md:w-6"
/>
</HeaderButton>
</div>
{/* Mobile hamburger menu */}
<div class="flex lg:hidden cursor-pointer" id="mobileNavTrigger">
<Icon
name="ph:text-align-justify-bold"
class="h-9 w-9 text-text-color"
id="hamburger_menu"
/>
<Icon
name="ph:caret-right-bold"
class="h-9 w-9 text-text-color hidden"
id="right_caret"
/>
</div>
</div>
</div>

View file

@ -0,0 +1,16 @@
---
const { text, route } = Astro.props;
---
<a
class="group flex w-full flex-row items-center justify-center border-t-2 border-solid border-navbar-text-color p-4 lg:border-none h-1/3 lg:h-fit"
id="header_anchor"
href={route}
>
<slot />
<span
class="font-roboto pl-2 text-center text-3xl font-bold text-text-color roboto transition duration-500 group-hover:text-text-hover-color lg:text-xl text-nowrap"
>
{text}
</span>
</a>

View file

@ -0,0 +1,23 @@
<div class="w-full h-full bg-primary text-navbar-text-color flex justify-center items-center">
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" viewBox="0 0 400 400" width="400" height="400" fill="#5e17eb" class="animate-pulse-brighter w-48 h-48">
<g id="svgg">
<path id="path0" fill="currentColor" fill-rule="evenodd" class="s0" d="m213.6 84c1 0.3 3.4 0.7 5.1 1 1.8 0.2 4.1 0.7 5.2 1 13.2 4.1 20.3 6.8 24.5 9.1 0.6 0.3 2.3 1.2 3.8 2 2.8 1.4 13.1 8 14.4 9.2 0.5 0.3 2.3 1.9 4.2 3.5 6.7 5.5 15.5 14.9 19.2 20.4 1 1.4 2 2.7 2.2 2.8 0.3 0.1 0.5 0.5 0.5 0.8 0 0.3 1.2 2.2 2.5 4.3 2.3 3.4 7.8 14.3 9.8 19.3 0.8 2.1 0.9 2.2 10 4.9 5.6 1.6 11.1 3.4 11.7 3.8 0.3 0.2 2.4 1.1 4.7 1.9 11.1 4.1 23 12.5 27.3 19.4 5.5 8.7 3.6 20.5-4.5 28.5-3.1 3-7.5 6.4-8.4 6.4-0.3 0-0.7 0.2-0.8 0.5-1.1 2.3-23.3 11.2-35.9 14.3-3.2 0.9-3.5 1.2-5.7 6.8-7.5 19-25.5 40.6-42.3 51.1-1.6 1-3.1 2-3.3 2.2-0.1 0.2-0.9 0.7-1.7 1.2-0.8 0.4-2.2 1.2-2.9 1.6-0.8 0.4-1.6 1-1.8 1.1-0.5 0.5-4.1 2.2-8.1 3.9-1.8 0.8-3.8 1.6-4.5 2-0.7 0.3-3.1 1.1-5.2 1.8-8.3 2.6-9.8 3-21 4.9-6.4 1.1-25.3 1.3-30.5 0.3-1.9-0.3-5.8-1.1-8.6-1.6-6.8-1.3-12.7-3-20-5.7-3.3-1.2-18-8.8-19.7-10.1-0.9-0.7-4.1-3.1-7.1-5.2-5.7-4.1-17.9-15.9-20.7-20-0.9-1.2-2-2.7-2.5-3.2-3.2-3.3-13.7-21.7-13.7-24.1 0-0.6-0.2-1.2-0.6-1.4-0.3-0.2-0.8-1.2-1-2.3-0.4-1.9-1.7-2.7-6.5-3.8-23.2-5.6-43.1-17.2-48.6-28.5-7.1-14.4 4.5-31.3 27.3-39.7 1.8-0.7 4.1-1.6 5.2-2 3.7-1.5 8-2.9 19.5-6.2 1.6-0.5 2.8-1.2 2.8-1.7 0-2.4 9.8-21.6 13.1-25.7 0.2-0.4 1.4-1.8 2.5-3.2 13.8-18.1 30.2-30.6 50.6-38.8 4.3-1.7 6-2.3 14.3-4.5 5.5-1.6 11.2-2.4 18.4-2.9 7.9-0.5 24-0.2 26.8 0.6zm-29.7 17.3c-0.2 0.1-7.3 1.7-12.9 2.7-1.7 0.4-4.3 1.2-5.8 1.9-1.5 0.6-3.9 1.5-5.5 2-1.5 0.4-3.3 1.3-4 2-0.7 0.7-1.7 1.2-2.3 1.2-1.2 0-9.5 4.5-9.8 5.3-0.2 0.3-0.5 0.6-0.9 0.6-1.9 0-19.6 16-23.8 21.6-9.3 12.2-16.1 27.4-19.2 42.7-2 10.1-1.1 37.5 1.4 41.4 0 0.1 3.7 0.9 8.1 1.8 9.5 1.9 12.8 2.4 34.6 4.9 38.5 4.5 107.9 2.2 138.3-4.5 1.4-0.3 4.1-0.9 6.1-1.3 4.2-0.8 3.4 0.2 4.9-7.1 1.6-8.3 1.7-27 0.1-34.6-1.5-7.1-3.2-13.4-3.7-14.2-0.3-0.4-0.7-1.5-0.9-2.6-2.8-12.1-19.2-34.1-33-44.3-2.9-2.1-5.5-4-5.8-4.3-2.8-2.2-4.9-3.1-7.2-3.1-2.1 0-2.6-0.2-2.7-1.3-0.2-1.5-5.7-4.5-6.3-3.5-0.7 1.1-2.4 0.6-2.7-0.7-0.4-1.3-1.2-1.6-5.8-2.1-1.6-0.2-4-0.9-5.5-1.6-3.9-1.8-5.3-2.2-10.2-2.6-4.6-0.4-25.2-0.7-25.5-0.3zm74.3 42.2c7.4 9.8 4.8 23.5-4.6 24.9-6.9 1-20.9-5.8-21-10.2 0-0.2-0.3-0.8-0.8-1.3-6.4-6.8-5-20.8 2.4-24.1 6.7-2.9 17.2 1.8 24 10.7zm-176.4 36.4c-0.1-0.1-4.6 1.1-5.9 1.6-0.7 0.3-3 1.2-5.1 2-9.9 3.8-15.1 6.8-19.6 11.5-3.4 3.5-3.3 4.5 0.5 8.7 1 1 11.3 7.6 12 7.6 0.2 0 1.7 0.6 3.4 1.3 1.6 0.8 3.6 1.6 4.3 1.9 1.8 0.8 9.3 3.3 9.9 3.3 0.3 0 0.3-2 0-4.4-0.6-5.6-0.6-24.5 0.1-29.6 0.3-2.1 0.5-3.9 0.4-3.9zm229.3-0.3c-0.2 0 0 1 0.2 2.1 0.6 2.8 0.6 31.3 0 34-0.5 2.2-0.4 2.2 1.3 1.8 3.1-0.7 12.9-4.5 18.3-7 8.5-4 14.3-10.1 12.6-13.3-1.1-2.1-6.7-7.2-7.9-7.2-0.4 0-0.9-0.2-1-0.5-0.4-1.1-11.8-6.1-19.2-8.5-2.3-0.7-4.2-1.4-4.3-1.4zm-199.4 63.4l-3.1-0.4 1.8 3.2c0.9 1.8 1.9 3.4 2.2 3.5 0.3 0.1 0.5 0.6 0.5 1.1 0 0.4 0.6 1.5 1.3 2.3 0.7 0.9 1.5 1.9 1.8 2.2 0.3 0.4 0.8 1.2 1.1 1.7 6.2 10.7 35.6 33.5 43.3 33.5 0.2 0 1.3 0.4 2.5 0.9 2.5 1.2 10.6 3.4 15.3 4.2 9.5 1.8 11.6 2.1 17.4 2.1 6.6 0 16.4-1.3 22.9-3 2.2-0.5 5.2-1.3 6.8-1.7 1.6-0.3 3.2-0.9 3.5-1.2 0.4-0.3 1.1-0.6 1.6-0.6 2.3 0 22-10.6 24-12.9 0.2-0.2 2.2-1.9 4.5-3.7 5.7-4.5 11.8-11 17.1-18.4 1.6-2.3 3.2-4.5 3.6-4.9 0.4-0.4 0.7-1 0.7-1.2 0-0.2 0.8-1.9 1.9-3.6 1.1-1.7 1.9-3.2 1.9-3.4 0-0.2-3.8 0.4-11 1.6-31.7 5.4-85.1 6.7-126.9 3.1-9.6-0.8-23.1-2.3-27.8-3.2-2.2-0.4-5.3-0.9-6.9-1.2z"/>
</g>
</svg>
</div>
<style>
@keyframes pulse-brighter {
0%,
100% {
opacity: 1;
}
50% {
opacity: 0.5;
}
}
.animate-pulse-brighter {
animation: pulse-brighter 2s infinite;
height: 11rem;
}
</style>

15
src/components/Logo.astro Normal file
View file

@ -0,0 +1,15 @@
<svg
version="1.2"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 400 400"
width="400"
height="400"
style="width: 100%; height: 100%;"
><title>nebula</title><g id="svgg"
><path
id="path0"
fill-rule="evenodd"
d="m213.6 84c1 0.3 3.4 0.7 5.1 1 1.8 0.2 4.1 0.7 5.2 1 13.2 4.1 20.3 6.8 24.5 9.1 0.6 0.3 2.3 1.2 3.8 2 2.8 1.4 13.1 8 14.4 9.2 0.5 0.3 2.3 1.9 4.2 3.5 6.7 5.5 15.5 14.9 19.2 20.4 1 1.4 2 2.7 2.2 2.8 0.3 0.1 0.5 0.5 0.5 0.8 0 0.3 1.2 2.2 2.5 4.3 2.3 3.4 7.8 14.3 9.8 19.3 0.8 2.1 0.9 2.2 10 4.9 5.6 1.6 11.1 3.4 11.7 3.8 0.3 0.2 2.4 1.1 4.7 1.9 11.1 4.1 23 12.5 27.3 19.4 5.5 8.7 3.6 20.5-4.5 28.5-3.1 3-7.5 6.4-8.4 6.4-0.3 0-0.7 0.2-0.8 0.5-1.1 2.3-23.3 11.2-35.9 14.3-3.2 0.9-3.5 1.2-5.7 6.8-7.5 19-25.5 40.6-42.3 51.1-1.6 1-3.1 2-3.3 2.2-0.1 0.2-0.9 0.7-1.7 1.2-0.8 0.4-2.2 1.2-2.9 1.6-0.8 0.4-1.6 1-1.8 1.1-0.5 0.5-4.1 2.2-8.1 3.9-1.8 0.8-3.8 1.6-4.5 2-0.7 0.3-3.1 1.1-5.2 1.8-8.3 2.6-9.8 3-21 4.9-6.4 1.1-25.3 1.3-30.5 0.3-1.9-0.3-5.8-1.1-8.6-1.6-6.8-1.3-12.7-3-20-5.7-3.3-1.2-18-8.8-19.7-10.1-0.9-0.7-4.1-3.1-7.1-5.2-5.7-4.1-17.9-15.9-20.7-20-0.9-1.2-2-2.7-2.5-3.2-3.2-3.3-13.7-21.7-13.7-24.1 0-0.6-0.2-1.2-0.6-1.4-0.3-0.2-0.8-1.2-1-2.3-0.4-1.9-1.7-2.7-6.5-3.8-23.2-5.6-43.1-17.2-48.6-28.5-7.1-14.4 4.5-31.3 27.3-39.7 1.8-0.7 4.1-1.6 5.2-2 3.7-1.5 8-2.9 19.5-6.2 1.6-0.5 2.8-1.2 2.8-1.7 0-2.4 9.8-21.6 13.1-25.7 0.2-0.4 1.4-1.8 2.5-3.2 13.8-18.1 30.2-30.6 50.6-38.8 4.3-1.7 6-2.3 14.3-4.5 5.5-1.6 11.2-2.4 18.4-2.9 7.9-0.5 24-0.2 26.8 0.6zm-29.7 17.3c-0.2 0.1-7.3 1.7-12.9 2.7-1.7 0.4-4.3 1.2-5.8 1.9-1.5 0.6-3.9 1.5-5.5 2-1.5 0.4-3.3 1.3-4 2-0.7 0.7-1.7 1.2-2.3 1.2-1.2 0-9.5 4.5-9.8 5.3-0.2 0.3-0.5 0.6-0.9 0.6-1.9 0-19.6 16-23.8 21.6-9.3 12.2-16.1 27.4-19.2 42.7-2 10.1-1.1 37.5 1.4 41.4 0 0.1 3.7 0.9 8.1 1.8 9.5 1.9 12.8 2.4 34.6 4.9 38.5 4.5 107.9 2.2 138.3-4.5 1.4-0.3 4.1-0.9 6.1-1.3 4.2-0.8 3.4 0.2 4.9-7.1 1.6-8.3 1.7-27 0.1-34.6-1.5-7.1-3.2-13.4-3.7-14.2-0.3-0.4-0.7-1.5-0.9-2.6-2.8-12.1-19.2-34.1-33-44.3-2.9-2.1-5.5-4-5.8-4.3-2.8-2.2-4.9-3.1-7.2-3.1-2.1 0-2.6-0.2-2.7-1.3-0.2-1.5-5.7-4.5-6.3-3.5-0.7 1.1-2.4 0.6-2.7-0.7-0.4-1.3-1.2-1.6-5.8-2.1-1.6-0.2-4-0.9-5.5-1.6-3.9-1.8-5.3-2.2-10.2-2.6-4.6-0.4-25.2-0.7-25.5-0.3zm74.3 42.2c7.4 9.8 4.8 23.5-4.6 24.9-6.9 1-20.9-5.8-21-10.2 0-0.2-0.3-0.8-0.8-1.3-6.4-6.8-5-20.8 2.4-24.1 6.7-2.9 17.2 1.8 24 10.7zm-176.4 36.4c-0.1-0.1-4.6 1.1-5.9 1.6-0.7 0.3-3 1.2-5.1 2-9.9 3.8-15.1 6.8-19.6 11.5-3.4 3.5-3.3 4.5 0.5 8.7 1 1 11.3 7.6 12 7.6 0.2 0 1.7 0.6 3.4 1.3 1.6 0.8 3.6 1.6 4.3 1.9 1.8 0.8 9.3 3.3 9.9 3.3 0.3 0 0.3-2 0-4.4-0.6-5.6-0.6-24.5 0.1-29.6 0.3-2.1 0.5-3.9 0.4-3.9zm229.3-0.3c-0.2 0 0 1 0.2 2.1 0.6 2.8 0.6 31.3 0 34-0.5 2.2-0.4 2.2 1.3 1.8 3.1-0.7 12.9-4.5 18.3-7 8.5-4 14.3-10.1 12.6-13.3-1.1-2.1-6.7-7.2-7.9-7.2-0.4 0-0.9-0.2-1-0.5-0.4-1.1-11.8-6.1-19.2-8.5-2.3-0.7-4.2-1.4-4.3-1.4zm-199.4 63.4l-3.1-0.4 1.8 3.2c0.9 1.8 1.9 3.4 2.2 3.5 0.3 0.1 0.5 0.6 0.5 1.1 0 0.4 0.6 1.5 1.3 2.3 0.7 0.9 1.5 1.9 1.8 2.2 0.3 0.4 0.8 1.2 1.1 1.7 6.2 10.7 35.6 33.5 43.3 33.5 0.2 0 1.3 0.4 2.5 0.9 2.5 1.2 10.6 3.4 15.3 4.2 9.5 1.8 11.6 2.1 17.4 2.1 6.6 0 16.4-1.3 22.9-3 2.2-0.5 5.2-1.3 6.8-1.7 1.6-0.3 3.2-0.9 3.5-1.2 0.4-0.3 1.1-0.6 1.6-0.6 2.3 0 22-10.6 24-12.9 0.2-0.2 2.2-1.9 4.5-3.7 5.7-4.5 11.8-11 17.1-18.4 1.6-2.3 3.2-4.5 3.6-4.9 0.4-0.4 0.7-1 0.7-1.2 0-0.2 0.8-1.9 1.9-3.6 1.1-1.7 1.9-3.2 1.9-3.4 0-0.2-3.8 0.4-11 1.6-31.7 5.4-85.1 6.7-126.9 3.1-9.6-0.8-23.1-2.3-27.8-3.2-2.2-0.4-5.3-0.9-6.9-1.2z"
class="s0"></path></g
></svg
>

After

Width:  |  Height:  |  Size: 3.4 KiB

View file

@ -0,0 +1,102 @@
---
import { Icon } from "astro-icon/components";
import { getLangFromUrl, useTranslations } from "../i18n/utils";
import HeaderButton from "./HeaderButton.astro";
const lang = getLangFromUrl(Astro.url);
const t = useTranslations(lang);
import { MARKETPLACE_ENABLED } from "astro:env/client";
---
<div class="h-full mt-16 flex w-full flex-col justify-evenly bg-navbar-color m-auto" id="mobilenav">
<HeaderButton text={t("header.home")} route={`/${lang}/`}>
<Icon
name="ph:house-bold"
class="h-6 w-6 text-text-color transition duration-500 group-hover:text-text-hover-color md:h-6 md:w-6"
/>
</HeaderButton>
<HeaderButton text={t("header.games")} route={`/${lang}/games/`}>
<Icon
name="ph:cube"
class="h-6 w-6 text-text-color transition duration-500 group-hover:text-text-hover-color md:h-6 md:w-6"
/>
</HeaderButton>
<HeaderButton
text={t("header.settings")}
route={`/${lang}/settings/appearance`}
>
<Icon
name="ph:wrench-fill"
class="h-6 w-6 text-text-color transition duration-500 group-hover:text-text-hover-color md:h-6 md:w-6"
/>
</HeaderButton>
{MARKETPLACE_ENABLED &&
<HeaderButton text={t("header.catalog")} route={`/${lang}/catalog/1`}>
<Icon
name="ph:shopping-bag-open-fill"
class="h-6 w-6 text-text-color transition duration-500 group-hover:text-text-hover-color md:h-6 md:w-6"
/>
</HeaderButton>
}
<HeaderButton text={t("header.morelinks")}>
<Icon
name="ph:link-bold"
class="h-6 w-6 text-text-color transition duration-500 group-hover:text-text-hover-color md:h-6 md:w-6"
/>
</HeaderButton>
</div>
<style is:global>
#mobilenav {
-webkit-transition-duration: 600ms;
transition-duration: 600ms;
transform: translateX(100%);
}
#mobilenavwrapper {
-webkit-transition-duration: 600ms;
transition-duration: 600ms;
transform: translateX(100%);
}
</style>
<script>
import { EventHandler } from "@utils/events";
import { Elements } from "@utils/index";
const init = async () => {
const els = Elements.select([
{ type: 'id', val: 'mobileNavTrigger' },
{ type: 'id', val: 'right_caret' },
{ type: 'id', val: 'hamburger_menu' },
{ type: 'id', val: 'mobilenavwrapper' },
{ type: 'id', val: 'mobilenav' }
]);
const trigger = Elements.exists<HTMLDivElement>(await els.next());
const rightCaret = Elements.exists<SVGElement>(await els.next());
const hamburgerMenu = Elements.exists<SVGElement>(await els.next());
const wrapper = Elements.exists<HTMLDivElement>(await els.next());
const mnm = Elements.exists<HTMLDivElement>(await els.next());
let isOpen = false;
Elements.attachEvent(trigger, "click", async () => {
console.log(isOpen);
if (isOpen) {
rightCaret.style.display = "none";
hamburgerMenu.style.display = "block";
mnm.style.transform = "translateX(100%)";
wrapper.style.transform = "translateX(100%)";
isOpen = false;
}
else {
hamburgerMenu.style.display = "none";
rightCaret.style.display = "block";
mnm.style.display = "flex";
mnm.style.transform = "translateX(0%)";
wrapper.style.transform = "translateX(0%)";
isOpen = true;
}
});
}
new EventHandler({
events: {
"astro:page-load": init
},
logging: false
}).bind();
</script>

View file

@ -0,0 +1,17 @@
---
const { title, route } = Astro.props;
---
<a
href={route}
class="snap-center snap-always group flex flex-col items-center md:p-0 max-sm:p-3 sm:p-3 bg-navbar-color w-full rounded-3xl md:flex-row md:bg-none md:rounded-none"
>
<div class="xl:p-2 max-sm:p-2 sm:p-2 md:p-0">
<slot />
</div>
<div
class="max-md:min-w-24 font-roboto text-center font-bold text-text-color roboto transition duration-500 group-hover:text-text-hover-color md:text-xl text-nowrap"
>
{title}
</div>
</a>

View file

@ -0,0 +1,58 @@
---
interface Props {
page: number | string | undefined;
lang: string;
}
interface Asset {
title: string;
description: string;
author: string;
image: string;
tags: [];
version: string;
background_image: string | null;
background_video: string | null;
payload: string;
type: "theme" | "plugin-sw" | "plugin-page";
}
const { page, lang } = Astro.props;
const getAssets = async () => {
const res = await fetch(new URL(`/api/catalog-assets?page=${page}`, Astro.url));
const data = await res.json();
return data.assets;
};
const assets = await getAssets();
---
<div class="text-3xl font-roboto font-bold text-text-color p-10">
{Object.keys(assets).length > 0 && (
<div class="flex flex-row gap-6 flex-wrap justify-center">
{Object.entries(assets).map((asset) => {
const pName = asset[0];
const a = asset[1] as unknown as Asset;
return (
<a href={`/${lang}/catalog/package/${pName}`}>
<div class="bg-navbar-color w-64 rounded-3xl shadow-lg overflow-hidden transition-transform duration-300 hover:scale-105 text-text-color">
<img src={`/packages/${pName}/${a.image}`} alt={a.title} class="w-full h-40 object-cover" />
<div class="p-6 text-sm">
<p class="font-semibold text-2xl mb-2"> {a.title} </p>
<p class="mb-4"> {a.description} </p>
<div class="flex flex-wrap gap-2 mb-4 w-full">
{a.tags.map((tag) => (
<p class="bg-navbar-text-color text-navbar-color font-bold px-3 py-1 rounded-md text-center"> { tag } </p>
))}
</div>
<p>
<strong>Version: </strong> { a.version }
</p>
<p>
<strong>Type: </strong> { a.type === "plugin-page" || a.type === "plugin-sw" ? "plugin" : a.type }
</p>
</div>
</div>
</a>
)
}
)}
</div>
)}
</div>

View file

@ -0,0 +1,107 @@
<div id="parent" class="flex flex-row flex-wrap gap-4 items-center font-roboto justify-center">
</div>
<div class="w-0 h-0 visibility-none hidden"> <asset-loader1 /> </div>
<script>
import { Elements } from "@utils/index";
import { Marketplace } from "@utils/marketplace";
import { SettingsVals } from "@utils/values";
type Item = {
description: string,
image: string,
package_name: string,
payload: string,
tags: [],
background_video: string,
background_image: string,
title: string,
type: string,
version: string
}
const getItem = async (item: any) => {
try {
const res = await fetch(new URL(`/api/packages/${item.name}`, window.location.origin));
const data = await res.json();
return { ...data, package_name: item.name }
}
catch (err: any) {
console.log(`Err in themes: ${err}`);
return null;
}
}
const constructElements = async (item: Item, parent: HTMLDivElement, marketplace: Marketplace) => {
const main = document.createElement("div");
main.classList.add("rounded-3xl", "bg-navbar-color", "w-64", "flex", "flex-col", "cursor-pointer", "border-text-color");
main.dataset.name = item.package_name
const click = document.createElement("div");
click.classList.add("w-full");
const img = document.createElement("img");
img.classList.add("aspect-[16/9]", "rounded-t-3xl");
img.src = `/packages/${item.package_name}/${item.image}`;
img.alt = `${item.type}-${item.package_name}`;
img.loading = "lazy";
const info = document.createElement("div");
info.classList.add("h-2/6", "text-center", "content-center", "p-3", "font-semibold", "items-center", "flex", "flex-col");
const infoTitle = document.createElement("p");
infoTitle.classList.add("text-2xl");
infoTitle.innerHTML = item.title;
const infoInner = document.createElement("div");
infoInner.classList.add("flex", "flex-row");
const infoInnerDelete = document.createElement("div");
infoInnerDelete.classList.add("h-8", "w-8", "cursor-pointer");
// This is cursed yes. SVG's SUUUCK
infoInnerDelete.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 256 256"><path fill="currentColor" d="M216 48h-40v-8a24 24 0 0 0-24-24h-48a24 24 0 0 0-24 24v8H40a8 8 0 0 0 0 16h8v144a16 16 0 0 0 16 16h128a16 16 0 0 0 16-16V64h8a8 8 0 0 0 0-16M112 168a8 8 0 0 1-16 0v-64a8 8 0 0 1 16 0Zm48 0a8 8 0 0 1-16 0v-64a8 8 0 0 1 16 0Zm0-120H96v-8a8 8 0 0 1 8-8h48a8 8 0 0 1 8 8Z" /></svg>`;
const infoInnerOpen = document.createElement("a");
infoInnerOpen.classList.add("h-8", "w-8", "cursor-pointer");
infoInnerOpen.href = `../catalog/package/${item.package_name}`;
infoInnerOpen.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 256 256"><path fill="currentColor" d="M192 136v72a16 16 0 0 1-16 16H48a16 16 0 0 1-16-16V80a16 16 0 0 1 16-16h72a8 8 0 0 1 0 16H48v128h128v-72a8 8 0 0 1 16 0m32-96a8 8 0 0 0-8-8h-64a8 8 0 0 0-5.66 13.66L172.69 72l-42.35 42.34a8 8 0 0 0 11.32 11.32L184 83.31l26.34 26.35A8 8 0 0 0 224 104Z" /></svg>`;
click.appendChild(img);
infoInner.appendChild(infoInnerDelete);
infoInner.appendChild(infoInnerOpen);
info.appendChild(infoTitle);
info.appendChild(infoInner);
main.appendChild(click);
main.appendChild(info);
parent.appendChild(main);
Elements.attachEvent(infoInnerDelete, "click", async () => {
await marketplace.uninstallPlugin({ name: item.package_name, type: item.type as "page" | "serviceWorker" })
parent.removeChild(main);
});
}
const init = async () => {
await Marketplace.ready();
const mp = Marketplace.getInstances().next().value!;
const els = Elements.select([
{ type: 'id', val: 'parent' }
]);
const itemsJSON = JSON.parse(await mp.getValueFromStore(SettingsVals.marketPlace.plugins)) || [];
const filteredItems = itemsJSON.filter((dat: any) => dat.remove !== true);
const itemPromises = filteredItems.map(getItem);
const itemsArray = await Promise.all(itemPromises);
return {
items: itemsArray.filter((data) => data !== null),
elements: els,
marketplace: mp
}
}
Elements.createCustomElement("asset-loader1", async () => {
const { items, elements, marketplace } = await init();
const parentElem = Elements.exists<HTMLDivElement>(await elements.next());
const promises = items.map(item => constructElements(item, parentElem, marketplace));
await Promise.all(promises);
});
</script>

View file

@ -0,0 +1,138 @@
<div id="parent" class="flex flex-row flex-wrap gap-4 items-center font-roboto justify-center">
<div id="main-theme" class="rounded-3xl bg-navbar-color w-64 flex flex-col cursor-pointer">
<div class="w-full">
<img src="/classic_theme.png" alt="Classic nebula" class="aspect-[16/9] rounded-t-3xl" loading="eager" />
</div>
<div class="h-2/6 text-center content-center p-3 font-semibold items-center flex flex-col text-2xl">
Classic Nebula
</div>
</div>
</div>
<div class="w-0 h-0 visibility-none hidden">
<asset-loader />
</div>
<script>
import { Elements } from "@utils/index";
import { Marketplace } from "@utils/marketplace";
import { SettingsVals } from "@utils/values";
type Item = {
description: string,
image: string,
package_name: string,
payload: string,
tags: [],
background_video: string,
background_image: string,
title: string,
type: string,
version: string
}
const getItem = async (item: any) => {
try {
const res = await fetch(new URL(`/api/packages/${item}`, window.location.origin));
const data = await res.json();
return { ...data, package_name: item }
}
catch (err: any) {
console.log(`Err in themes: ${err}`);
return null;
}
}
const constructElements = async (item: Item, mainTheme: HTMLDivElement, parent: HTMLDivElement, marketplace: Marketplace) => {
const main = document.createElement("div");
main.classList.add("rounded-3xl", "bg-navbar-color", "w-64", "flex", "flex-col", "cursor-pointer", "border-text-color");
main.dataset.name = item.package_name
const click = document.createElement("div");
click.classList.add("w-full");
const img = document.createElement("img");
img.classList.add("aspect-[16/9]", "rounded-t-3xl");
img.src = `/packages/${item.package_name}/${item.image}`;
img.alt = `${item.type}-${item.package_name}`;
img.loading = "lazy";
const info = document.createElement("div");
info.classList.add("h-2/6", "text-center", "content-center", "p-3", "font-semibold", "items-center", "flex", "flex-col");
const infoTitle = document.createElement("p");
infoTitle.classList.add("text-2xl");
infoTitle.innerHTML = item.title;
const infoInner = document.createElement("div");
infoInner.classList.add("flex", "flex-row");
const infoInnerDelete = document.createElement("div");
infoInnerDelete.classList.add("h-8", "w-8", "cursor-pointer");
// This is cursed yes. SVG's SUUUCK
infoInnerDelete.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 256 256"><path fill="currentColor" d="M216 48h-40v-8a24 24 0 0 0-24-24h-48a24 24 0 0 0-24 24v8H40a8 8 0 0 0 0 16h8v144a16 16 0 0 0 16 16h128a16 16 0 0 0 16-16V64h8a8 8 0 0 0 0-16M112 168a8 8 0 0 1-16 0v-64a8 8 0 0 1 16 0Zm48 0a8 8 0 0 1-16 0v-64a8 8 0 0 1 16 0Zm0-120H96v-8a8 8 0 0 1 8-8h48a8 8 0 0 1 8 8Z" /></svg>`;
const infoInnerOpen = document.createElement("a");
infoInnerOpen.classList.add("h-8", "w-8", "cursor-pointer");
infoInnerOpen.href = `../catalog/package/${item.package_name}`;
infoInnerOpen.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 256 256"><path fill="currentColor" d="M192 136v72a16 16 0 0 1-16 16H48a16 16 0 0 1-16-16V80a16 16 0 0 1 16-16h72a8 8 0 0 1 0 16H48v128h128v-72a8 8 0 0 1 16 0m32-96a8 8 0 0 0-8-8h-64a8 8 0 0 0-5.66 13.66L172.69 72l-42.35 42.34a8 8 0 0 0 11.32 11.32L184 83.31l26.34 26.35A8 8 0 0 0 224 104Z" /></svg>`;
click.appendChild(img);
infoInner.appendChild(infoInnerDelete);
infoInner.appendChild(infoInnerOpen);
info.appendChild(infoTitle);
info.appendChild(infoInner);
main.appendChild(click);
main.appendChild(info);
parent.appendChild(main);
Elements.attachEvent(mainTheme, "click", () => {
marketplace.theme({ type: 'remove' });
});
Elements.attachEvent(click, "click", async () => {
await marketplace.theme(
{
type: 'normal',
payload: item.payload,
sources: {
video: item.background_video,
bg: item.background_image
},
name: item.package_name
}
);
});
Elements.attachEvent(infoInnerDelete, "click", async () => {
await marketplace.uninstallTheme({ name: item.package_name });
parent.removeChild(main);
await marketplace.theme({ type: 'remove' });
});
}
const init = async () => {
await Marketplace.ready();
const mp = Marketplace.getInstances().next().value!;
const els = Elements.select([
{ type: 'id', val: 'main-theme' },
{ type: 'id', val: 'parent' }
]);
const itemsJSON = JSON.parse(await mp.getValueFromStore(SettingsVals.marketPlace.themes)) || [];
const itemPromises = itemsJSON.map(getItem);
const itemsArray = await Promise.all(itemPromises);
return {
items: itemsArray.filter((data) => data !== null),
elements: els,
marketplace: mp
}
}
Elements.createCustomElement("asset-loader", async () => {
const { items, elements, marketplace } = await init();
const mainTheme = Elements.exists<HTMLDivElement>(await elements.next());
const parentElem = Elements.exists<HTMLDivElement>(await elements.next());
const promises = items.map(item => constructElements(item, mainTheme, parentElem, marketplace));
await Promise.all(promises);
});
</script>

View file

@ -0,0 +1,19 @@
---
import { Image } from "astro:assets";
import { type ImageMetadata } from "astro";
const images = import.meta.glob<{ default: ImageMetadata }>(
"/src/assets/credits/*.{jpeg,jpg,png,gif,webp}"
);
interface Props {
image?: string;
name: string;
link: string;
}
const { image, name, link } = Astro.props;
---
<a class="rounded-md bg-navbar-color h-50 w-50 p-2 flex flex-col items-center" href={link} target="_blank" rel="noopener noreferrer">
{image && <Image loading='lazy' class='w-32 h-32 object-cover rounded-md' src={images[image]()} alt={name} />}
<p class="h-12 w-full text-text-color flex items-center justify-center text-xl font-semibold">{name}</p>
</a>

View file

@ -0,0 +1,70 @@
<script>
import { EventHandler } from "@utils/events";
import { SW, createProxyScripts, checkProxyScripts, createBareMuxConn, setTransport } from "@utils/serviceWorker";
import { Settings } from "@utils/settings";
import { log } from "@utils/index";
import { Marketplace } from "@utils/marketplace";
import { SettingsVals } from "@utils/values";
const titleText = `
_ _ _ _ ____ _
| \\ | | ___| |__ _ _| | __ _ / ___| ___ _ ____ _(_) ___ ___ ___
| \\| |/ _ \\ '_ \\| | | | |/ _' | \\___ \\ / _ \\ '__\\ \\ / / |/ __/ _ \\/ __|
| |\\ | __/ |_) | |_| | | (_| | ___) | __/ | \\ V /| | (_| __/\\__ \\
|_| \\_|\\___|_.__/ \\__,_|_|\\__,_| |____/ \\___|_| \\_/ |_|\\___\\___||___/
`;
const info = "Hello developer or curious individual & welcome to the console! \nThere isn't a whole lot here for you unless you have run into an error.";
const sysInfo = `In which case please include the info below when opening the issue: \n\nOS: ${navigator.platform} \nBrowser: ${navigator.userAgent} \nService workers: ${"serviceWorker" in navigator ? "Yes" : "No"}`
const init = async (): Promise<Marketplace> => {
log({ type: 'normal', bg: false, prefix: false }, titleText);
log({ type: 'normal', bg: true, prefix: false }, info);
log({ type: 'normal', bg: true, prefix: false }, sysInfo);
log({ type: 'info', bg: true, prefix: true }, "General init...");
for (const script of createProxyScripts()) {
document.body.appendChild(script);
}
await checkProxyScripts();
const conn = await createBareMuxConn("/baremux/worker.js");
const sw = new SW(conn);
const mp = new Marketplace();
const { serviceWorker, bareMuxConn, sj } = await sw.getSWInfo();
log({ type: 'info', bg: true, prefix: true }, `General init completed! \n\nServiceWorker: ${serviceWorker.active?.state} \nBareMuxConn: ${bareMuxConn ? 'Active': 'Not active'} \nScramjetController: ${sj ? 'Active' : 'Not active'}`);
return mp;
}
const handleTheme = async (marketplace: Marketplace) => {
const name = await marketplace.getValueFromStore(SettingsVals.marketPlace.appearance.theme.name);
const payload = await marketplace.getValueFromStore(SettingsVals.marketPlace.appearance.theme.payload);
const video = await marketplace.getValueFromStore(SettingsVals.marketPlace.appearance.video);
const image = await marketplace.getValueFromStore(SettingsVals.marketPlace.appearance.image);
if (name !== null) {
marketplace.theme({
type: 'normal',
name: name,
payload: payload,
sources: {
video: video,
bg: image
}
});
}
}
const initSettings = async (marketplace: Marketplace) => {
log({ type: 'info', bg: true, prefix: true }, "Initializing settings...");
for await (const _ of Settings.initDefaults());
await handleTheme(marketplace);
log({ type: 'info', bg: true, prefix: true }, "Initialized Settings!");
}
const eventHandler = new EventHandler({
events: {
"DOMContentLoaded": async () => {
const mp = await init();
await initSettings(mp);
}
},
logging: true
});
//bind the events
eventHandler.bind();
</script>

View file

@ -0,0 +1,67 @@
---
interface Inputs {
input: boolean;
required?: boolean;
placeholder?: string;
validate?: boolean;
validateString?: string;
}
interface SelectOptions {
value: string;
name: string;
disabled: boolean;
}
interface Both {
enabled: boolean;
showOnSelect?: {
value: string;
};
showOnInput?: boolean;
}
interface Selects {
select: boolean;
name?: string;
multiple?: boolean;
options?: SelectOptions[];
}
interface Buttons {
name: string;
id: string;
}
interface Props {
title: string;
description: string;
input: Inputs;
select: Selects;
both: Both;
button: Buttons;
}
const { title, description, input, select, both, button } = Astro.props;
---
<div class={`${both.enabled ? "h-72" : "h-64"} w-64 rounded-3xl bg-navbar-color flex flex-col items-center p-4`}>
<h1 class="text-3xl font-bold mb-2"> { title } </h1>
<p class="text-md w-full text-ellipsis text-center"> { description } </p>
<div class="w-full h-full flex-grow flex justify-center items-center flex-col gap-4">
<!-- We only want to render an input if it's enabled -->
{(input.input && !both.enabled) &&
<input class="text-md w-full h-10 p-2 bg-input border border-input-border-color rounded-md text-input-text" required={input.required} placeholder={input.placeholder}></input>
}
<!-- Same with dropdown selections -->
{select.select &&
<select id={select.name?.replace(/[^a-zA-Z0-9]/g, '').toLowerCase()} class="text-md w-full h-10 p-2 bg-input border border-input-border-color rounded-md text-input-text" multiple={select.multiple} name={select.name}>
{select.options!.map((option) => (
<option id={option.value} disabled={option.disabled} value={option.value}>{option.name}</option>
))}
</select>
}
{(both.enabled && both.showOnSelect?.value) &&
<input id={'inputOnSelectValue' + both.showOnSelect?.value} class="hidden text-md w-full h-10 p-2 bg-input border border-input-border-color rounded-md text-input-text" required={input.required} placeholder={input.placeholder}></input>
}
<button id={button.id.replace(/[^a-zA-Z0-9]/g, '').toLowerCase()} class="w-36 h-10 rounded-md border border-input-border-color text-input-text bg-input hover:border-input hover:bg-input-border-color hover:text-input hover:font-bold active:bg-input active:text-input-text transition-all duration-200">
{button.name}
</button>
</div>
</div>

View file

@ -0,0 +1,13 @@
---
const { image, title } = Astro.props;
import { Image } from "astro:assets";
---
<div class="rounded-3xl bg-navbar-color w-64 flex flex-col">
<div class="w-full">
<Image src={image} alt="Theme" class="aspect-[16/9] rounded-t-3xl" />
</div>
<div class="h-2/6 text-center content-center p-3 font-semibold">
{title}
</div>
</div>

Some files were not shown because too many files have changed in this diff Show more