Merge pull request #75 from cohenerickson/main

Format using prettier & bump NodeJS version requirements. [hyper epic !]
This commit is contained in:
Green! 2023-02-05 21:49:29 -05:00 committed by GitHub
commit 08afaff9f9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 4791 additions and 4435 deletions

View file

@ -1,3 +0,0 @@
{
"files": {}
}

View file

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

7
.gitignore vendored
View file

@ -1,2 +1,7 @@
# dependencies
/node_modules
.DS_Store
# System Files
.DS_Store
Thumbs.db
.breakpoints

1
.prettierignore Normal file
View file

@ -0,0 +1 @@
node_modules

6
.prettierrc Normal file
View file

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

32
.replit
View file

@ -1,19 +1,31 @@
entrypoint = "app.js"
hidden = [".config"]
run = "npm start"
hidden = [".config", "package-lock.json"]
[interpreter]
command = [
"prybar-nodejs",
"-q",
"--ps1",
"\u0001\u001b[33m\u0002\u0001\u001b[00m\u0002 ",
"-i"
]
[[hints]]
regex = "Error \\[ERR_REQUIRE_ESM\\]"
message = "We see that you are using require(...) inside your code. We currently do not support this syntax. Please use 'import' instead when using external modules. (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import)"
[nix]
channel = "stable-21_11"
channel = "stable-22_11"
[env]
XDG_CONFIG_HOME = "/home/runner/.config"
PATH = "/home/runner/$REPL_SLUG/.config/npm/node_global/bin:/home/runner/$REPL_SLUG/node_modules/.bin"
npm_config_prefix = "/home/runner/$REPL_SLUG/.config/npm/node_global"
[gitHubImport]
requiredFiles = [".replit", "replit.nix", ".config", "package.json", "package-lock.json"]
[packager]
language = "nodejs"
@ -25,12 +37,6 @@ language = "nodejs"
[unitTest]
language = "nodejs"
[languages.javascript]
pattern = "**/{*.js,*.jsx,*.ts,*.tsx}"
[languages.javascript.languageServer]
start = [ "typescript-language-server", "--stdio" ]
[debugger]
support = true
@ -70,3 +76,11 @@ support = true
sourceMaps = true
stopOnEntry = false
type = "pwa-node"
[languages]
[languages.javascript]
pattern = "**/{*.js,*.jsx,*.ts,*.tsx}"
[languages.javascript.languageServer]
start = "typescript-language-server --stdio"

7
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,7 @@
{
"editor.tabSize": 2,
"editor.insertSpaces": true,
"editor.formatOnSave": true,
"editor.formatOnPaste": true,
"editor.defaultFormatter": "esbenp.prettier-vscode"
}

195
README.md
View file

@ -1,39 +1,34 @@
# Nebula
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.
![license](https://img.shields.io/badge/License-GNU%20AGPL%20v3-blue)
![chat](https://img.shields.io/badge/chat-1139%20online-brightgreen)
![license](https://img.shields.io/badge/License-GNU%20AGPL%20v3-blue)
![chat](https://img.shields.io/badge/chat-1139%20online-brightgreen)
## Features
- Stunning and highly functional UI with multiple themes
- 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/main/docs/officially-supported-sites.md)
- *limited* mobile support
- _limited_ mobile support
- Stealth Mode (buffed `about:blank` cloaking)
- **NEW** Clickoff cloaking
- **NEW** Email OTP verification
- **NEW** Clickoff cloaking
- **NEW** Email OTP verification
# Deployment
Table of contents
Table of contents
- Quick & easy deployment
- Deployment configuration explaination
- Deployment configuration explaination
- how to use email OTP Verification mode
- Advanced Deployment
- Advanced Deployment
- Filesystem
## Quick & Easy Deployment Options
[![Deploy to Heroku](https://raw.githubusercontent.com/BinBashBanana/deploy-buttons/master/buttons/remade/heroku.svg)](https://heroku.com/deploy/?template=https://github.com/NebulaServices/Nebula)
<br>
[![Run on Replit](https://raw.githubusercontent.com/BinBashBanana/deploy-buttons/master/buttons/remade/replit.svg)](https://replit.com/github/NebulaServices/Nebula)
@ -51,15 +46,18 @@ Table of contents
[![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)
---
## Deployment Configuration Guide
(Example configuration with none-json notes)
## 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"
"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,
@ -79,77 +77,86 @@ Table of contents
}
```
## 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.
## 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.
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
- 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
- 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"
- 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"
---
### 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
- 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
@ -161,48 +168,46 @@ 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*
_Note: Server will need to run` cd Nebula && sudo nohup PORT=80 node . &` on reboot_
## File Structure
| **File** | Purpose | |
|----------------------------------|----------------------------------------------------------------------------------------------------------|---|
| `static/index.html` | The main frontend visuals for NebulaWEB. | |
| `static/unv.html` | The verification-required frontend/visuals. | |
| `static/options/` | The frontend for Nebula's options, settings, and preferences. | |
| `static/resources/v.js` | Client verification system for the OTP system. | |
| `static/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. | |
| **File** | Purpose | |
| -------------------------------- | -------------------------------------------------------------------------------------------------------- | --- |
| `static/index.html` | The main frontend visuals for NebulaWEB. | |
| `static/unv.html` | The verification-required frontend/visuals. | |
| `static/options/` | The frontend for Nebula's options, settings, and preferences. | |
| `static/resources/v.js` | Client verification system for the OTP system. | |
| `static/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)
- UV Backend Proxy
- Partical.JS (Specifically v4, 5, 6.1 &< only)
- UV Backend Proxy
- Osana Backend Proxy
- TompHTTP Bare Server
- node HTTP (No ExpressJS!)
- node HTTP (No ExpressJS!)
## Support
For support, email chloe@nebula.bio or join our discord: discord.gg/unblocker
## Demo
[Click here to see a demo of Nebula](https://nebulaproxy.io/)
## Acknowledgements
- [UV (one of the back-end proxy we use)](https://github.com/titaniumnetwork-dev/Ultraviolet)
- [Osana (one of the back-end proxy we use)](https://github.com/NebulaServices/Osana)
- [Bare Server](https://github.com/tomphttp/bare-server-node)
- [Partical.JS (v4, 5, 6.1 &< only)](https://github.com/VincentGarreau/particles.js)
- [UV (one of the back-end proxy we use)](https://github.com/titaniumnetwork-dev/Ultraviolet)
- [Osana (one of the back-end proxy we use)](https://github.com/NebulaServices/Osana)
- [Bare Server](https://github.com/tomphttp/bare-server-node)
- [Partical.JS (v4, 5, 6.1 &< only)](https://github.com/VincentGarreau/particles.js)
## License
(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.
This project uses the AGLP GNU V3 license.

87
app.js
View file

@ -1,9 +1,9 @@
import createBareServer from "@tomphttp/bare-server-node";
import http from "http";
import {createRequire} from "module";
import {dirname, join} from "path";
import { createRequire } from "module";
import { dirname, join } from "path";
import serveStatic from "serve-static";
import {fileURLToPath} from "url";
import { fileURLToPath } from "url";
const require = createRequire(import.meta.url);
const config = require("./deployment.config.json");
import fs from "fs";
@ -12,30 +12,30 @@ import sgTransport from "nodemailer-sendgrid-transport";
import nodemailer from "nodemailer";
import fetch from "node-fetch";
const options = {
auth : {
api_key : config.sendgrid_options.api_key,
},
auth: {
api_key: config.sendgrid_options.api_key
}
};
const sendgridMailerAgent = nodemailer.createTransport(sgTransport(options));
const smtpMailerAgent = nodemailer.createTransport(config.smtp_options);
function sendVerificationEmail(UUID, OTP) {
let email = {
to : "",
from : "",
subject : `NebulaWEB personal access code ${OTP}`,
text : `
to: "",
from: "",
subject: `NebulaWEB personal access code ${OTP}`,
text: `
####### ACCESS CODE (OTP) ${OTP} #######
####### DO NOT SHARE THIS CODE! #######
(this message is automated)`,
html : `
html: `
####### ACCESS CODE (OTP) ${OTP} #######
####### DO NOT SHARE THIS CODE! #######
(this message is automated)
`,
`
};
if (config.sendgrid_verification == true) {
email.to = config.sendgrid_options.to_email
email.from = config.sendgrid_options.sendFromEmail
email.to = config.sendgrid_options.to_email;
email.from = config.sendgrid_options.sendFromEmail;
sendgridMailerAgent.sendMail(email, (err, res) => {
if (err) {
console.log(err);
@ -44,8 +44,8 @@ function sendVerificationEmail(UUID, OTP) {
});
}
if (config.smtp_verification == true) {
email.to = config.smtp_options.to_email
email.from = config.smtp_options.sendFromEmail
email.to = config.smtp_options.to_email;
email.from = config.smtp_options.sendFromEmail;
smtpMailerAgent.sendMail(email, (err, res) => {
if (err) {
console.log(err);
@ -55,13 +55,13 @@ function sendVerificationEmail(UUID, OTP) {
}
if (config.discord_verification == true) {
fetch(config.webhook_url, {
method : "POST",
headers : {
"Content-Type" : "application/json",
method: "POST",
headers: {
"Content-Type": "application/json"
},
body : JSON.stringify({
content : `Your NebulaWEB access code is ${OTP}`,
}),
body: JSON.stringify({
content: `Your NebulaWEB access code is ${OTP}`
})
});
}
}
@ -76,15 +76,17 @@ function getNewCode() {
const PORT = process.env.PORT || 3000;
const bareServer = createBareServer("/bare/", {
logErrors : false,
localAddress : undefined,
logErrors: false,
localAddress: undefined
});
const serve =
serveStatic(join(dirname(fileURLToPath(import.meta.url)), "static/"), {
fallthrough : false,
maxAge : 5 * 60 * 1000,
});
const serve = serveStatic(
join(dirname(fileURLToPath(import.meta.url)), "static/"),
{
fallthrough: false,
maxAge: 5 * 60 * 1000
}
);
const server = http.createServer();
@ -97,9 +99,8 @@ server.on("request", (request, response) => {
const url = request.url;
if (url.startsWith("/sendNewCode")) {
const OTP = getNewCode();
fs.writeFile("./memory.txt", OTP, function(err) {
if (err)
return console.log(err);
fs.writeFile("./memory.txt", OTP, function (err) {
if (err) return console.log(err);
console.log(`Wrote OTP code to temp file`);
});
@ -115,33 +116,35 @@ server.on("request", (request, response) => {
base64data = buff.toString("base64");
console.log("302");
response.writeHead(302, {
location : "/unv.html?c=" + base64data,
location: "/unv.html?c=" + base64data
});
response.end();
});
} else if (url.startsWith("/verification")) {
var body;
if (config.sendgrid_verification == true ||
config.discord_verification == true ||
config.smtp_verificaton == true) {
if (
config.sendgrid_verification == true ||
config.discord_verification == true ||
config.smtp_verificaton == true
) {
const body = "true";
response.writeHead(200, {
"Content-Length" : Buffer.byteLength(body),
"Content-Type" : "text/plain",
"Content-Length": Buffer.byteLength(body),
"Content-Type": "text/plain"
});
response.end(body);
} else {
const body = "false";
response.writeHead(200, {
"Content-Length" : Buffer.byteLength(body),
"Content-Type" : "text/plain",
"Content-Length": Buffer.byteLength(body),
"Content-Type": "text/plain"
});
response.end(body);
}
} else {
serve(request, response, (err) => {
response.writeHead(err?.statusCode || 500, null, {
"Content-Type" : "text/plain",
"Content-Type": "text/plain"
});
response.end(err?.stack);
});
@ -149,7 +152,7 @@ server.on("request", (request, response) => {
}
} catch (e) {
response.writeHead(500, "Internal Server Error", {
"Content-Type" : "text/plain",
"Content-Type": "text/plain"
});
response.end(e.stack);
}

View file

@ -1,7 +1,7 @@
{
"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"]
}
"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"]
}

View file

@ -1,9 +1,9 @@
{
"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"
"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,

View file

@ -1,4 +1,4 @@
version: '3'
version: "3"
services:
nebula:
image: nebula:latest

View file

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

6066
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,25 +1,25 @@
{
"name": "nebula-web",
"version": "7.10.0",
"description": "Explore the web. Freely.",
"type": "module",
"main": "app.js",
"scripts": {
"start": "node app.js"
},
"keywords": [
"proxy"
],
"author": "Nebula Services",
"license": "AGPL-3.0-only",
"dependencies": {
"@tomphttp/bare-server-node": "^1.2.2",
"node-fetch": "^3.3.0",
"nodemailer": "^6.8.0",
"nodemailer-sendgrid-transport": "^0.2.0",
"serve-static": "^1.15.0"
},
"engines": {
"node": ">=16.0.0"
}
"name": "nebula-web",
"version": "7.11.6",
"description": "Explore the web. Freely.",
"type": "module",
"main": "app.js",
"scripts": {
"start": "node app.js"
},
"keywords": [
"proxy"
],
"author": "Nebula Services",
"license": "AGPL-3.0-only",
"dependencies": {
"@tomphttp/bare-server-node": "^1.2.2",
"node-fetch": "^3.3.0",
"nodemailer": "^6.8.0",
"nodemailer-sendgrid-transport": "^0.2.0",
"serve-static": "^1.15.0"
},
"engines": {
"node": ">=18"
}
}

View file

@ -1,8 +1,8 @@
{ pkgs }: {
deps = [
pkgs.nodejs-16_x
pkgs.nodePackages.typescript-language-server
pkgs.yarn
pkgs.replitPackages.jest
];
deps = [
pkgs.nodejs-18_x
pkgs.nodePackages.typescript-language-server
pkgs.yarn
pkgs.replitPackages.jest
];
}

File diff suppressed because one or more lines are too long

View file

@ -59,9 +59,9 @@
<div style='color:black;'>
Acknowledgements are resources Nebula is using/has used.
<ul style='color:black;'>
<li><a style='color:black;' href="https://github.com/titaniumnetwork-dev/Ultraviolet">UV (one of the back-end proxy we use)</a></li>
<li><a style='color:black;' href="https://github.com/NebulaServices/Osana">Osana (one of the back-end proxy we use)</a></li>
<li><a style='color:black;' href="https://github.com/tomphttp/bare-server-node">Bare Server</a></li>
<li><a style='color:black;' href="https://github.com/titaniumnetwork-dev/Ultraviolet">Ultraviolet (one of the proxies we use)</a></li>
<li><a style='color:black;' href="https://github.com/NebulaServices/Osana">Osana (one of the proxies we use)</a></li>
<li><a style='color:black;' href="https://github.com/tomphttp/bare-server-node">Bare Server Node</a></li>
<br>
<li><a style='color:black;' href="https://github.com/VincentGarreau/particles.js">Partical.JS (v4, 5, 6.1 &amp;&lt; only)</a></li>
</ul>

View file

@ -4,49 +4,103 @@
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]> <html class="no-js"> <!--<![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="">
</head>
<meta name="description" content="" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="" />
</head>
<body>
<body>
<h2>Privacy Policy</h2>
<p>Your privacy is important to us. It is Nebula Services&#39; policy to respect your privacy and comply with any applicable law and regulation regarding any personal information we may collect about you, including across our website, <a href="https://nebula.bio">https://nebula.bio</a>,
and other sites we own and operate. </p>
<p>This policy is effective as of 8 June 2022 and was last updated on 8 June 2022. </p>
<p>
Your privacy is important to us. It is Nebula Services&#39; policy to
respect your privacy and comply with any applicable law and regulation
regarding any personal information we may collect about you, including
across our website, <a href="https://nebula.bio">https://nebula.bio</a>,
and other sites we own and operate.
</p>
<p>
This policy is effective as of 8 June 2022 and was last updated on 8 June
2022.
</p>
<h3>Information We Collect</h3>
<p>Information we collect includes both information you knowingly and actively provide us when using or participating in any of our services and promotions, and any information automatically sent by your devices in the course of accessing our products
and services. </p>
<p>
Information we collect includes both information you knowingly and
actively provide us when using or participating in any of our services and
promotions, and any information automatically sent by your devices in the
course of accessing our products and services.
</p>
<h4>Log Data</h4>
<p>When you visit our website, our servers may automatically log the standard data provided by your web browser. It may include your devices Internet Protocol (IP) address, your browser type and version, the pages you visit, the time and date of your
visit, the time spent on each page, other details about your visit, and technical details that occur in conjunction with any errors you may encounter. </p>
<p>Please be aware that while this information may not be personally identifying by itself, it may be possible to combine it with other data to personally identify individual persons. </p>
<p>
When you visit our website, our servers may automatically log the standard
data provided by your web browser. It may include your devices Internet
Protocol (IP) address, your browser type and version, the pages you visit,
the time and date of your visit, the time spent on each page, other
details about your visit, and technical details that occur in conjunction
with any errors you may encounter.
</p>
<p>
Please be aware that while this information may not be personally
identifying by itself, it may be possible to combine it with other data to
personally identify individual persons.
</p>
<h4>Collection and Use of Information</h4>
<p>We may collect personal information from you when you do any of the following on our website: </p>
<p>
We may collect personal information from you when you do any of the
following on our website:
</p>
<ul>
<li>Use a mobile device or web browser to access our content</li>
<li>Contact us via email, social media, or on any similar technologies</li>
<li>When you mention us on social media</li>
<li>Use a mobile device or web browser to access our content</li>
<li>
Contact us via email, social media, or on any similar technologies
</li>
<li>When you mention us on social media</li>
</ul>
<h3>Childrens Privacy</h3>
<p>We do not aim any of our products or services directly at children under the age of 13, and we do not knowingly collect personal information about children under 13. </p>
<p>
We do not aim any of our products or services directly at children under
the age of 13, and we do not knowingly collect personal information about
children under 13.
</p>
<h3>Use of Cookies</h3>
<p>We use &ldquo;cookies&rdquo; to collect information about you and your activity across our site. A cookie is a small piece of data that our website stores on your computer, and accesses each time you visit, so we can understand how you use our site.
This helps us serve you content based on preferences you have specified. </p>
<p>
We use &ldquo;cookies&rdquo; to collect information about you and your
activity across our site. A cookie is a small piece of data that our
website stores on your computer, and accesses each time you visit, so we
can understand how you use our site. This helps us serve you content based
on preferences you have specified.
</p>
<h3>Limits of Our Policy</h3>
<p>Our website may link to external sites that are not operated by us. Please be aware that we have no control over the content and policies of those sites, and cannot accept responsibility or liability for their respective privacy practices. </p>
<p>
Our website may link to external sites that are not operated by us. Please
be aware that we have no control over the content and policies of those
sites, and cannot accept responsibility or liability for their respective
privacy practices.
</p>
<h3>Changes to This Policy</h3>
<p>At our discretion, we may change our privacy policy to reflect updates to our business processes, current acceptable practices, or legislative or regulatory changes. If we decide to change this privacy policy, we will post the changes here at the
same link by which you are accessing this privacy policy. </p>
<p>If required by law, we will get your permission or give you the opportunity to opt in to or opt out of, as applicable, any new uses of your personal information. </p>
<p>
At our discretion, we may change our privacy policy to reflect updates to
our business processes, current acceptable practices, or legislative or
regulatory changes. If we decide to change this privacy policy, we will
post the changes here at the same link by which you are accessing this
privacy policy.
</p>
<p>
If required by law, we will get your permission or give you the
opportunity to opt in to or opt out of, as applicable, any new uses of
your personal information.
</p>
<h3>Contact Us</h3>
<p>For any questions or concerns regarding your privacy, you may contact us using the following details: </p>
<p>Chloe B<br /> chloe@nebula.bio </p>
</body>
</html>
<p>
For any questions or concerns regarding your privacy, you may contact us
using the following details:
</p>
<p>
Chloe B<br />
chloe@nebula.bio
</p>
</body>
</html>

File diff suppressed because it is too large Load diff

View file

@ -1,161 +1,161 @@
// OPTIONS
const storedSetTheme = localStorage.getItem('theme')
const storedSetTheme = localStorage.getItem("theme");
function switchProxy () {
var selecter = document.getElementById('proxySwitcher')
var selectedOption = selecter.value
function switchProxy() {
var selecter = document.getElementById("proxySwitcher");
var selectedOption = selecter.value;
localStorage.setItem('proxy', selectedOption)
var storedChoice = localStorage.getItem('proxy')
console.log(selectedOption)
localStorage.setItem("proxy", selectedOption);
var storedChoice = localStorage.getItem("proxy");
console.log(selectedOption);
}
function switchTheme () {
var selecter = document.getElementById('themeSwitcher')
var selectedOption = selecter.value
if (selectedOption == 'dark') {
changeCSS('--background-primary', '#191724', true)
changeCSS('--navbar-color', '#26233a', true)
changeCSS('--navbar-height', '60px', true)
changeCSS('--navbar-text-color', '#7967dd', 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)
changeCSS('--navbar-link-color', '#e0def4', true)
changeCSS('--navbar-font', '"Roboto"', true)
changeCSS('--navbar-logo-filter', 'invert(0%)', true)
changeCSS('--text-color-primary', '#e0def4', true)
localStorage.setItem('theme', 'dark')
function switchTheme() {
var selecter = document.getElementById("themeSwitcher");
var selectedOption = selecter.value;
if (selectedOption == "dark") {
changeCSS("--background-primary", "#191724", true);
changeCSS("--navbar-color", "#26233a", true);
changeCSS("--navbar-height", "60px", true);
changeCSS("--navbar-text-color", "#7967dd", 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);
changeCSS("--navbar-link-color", "#e0def4", true);
changeCSS("--navbar-font", '"Roboto"', true);
changeCSS("--navbar-logo-filter", "invert(0%)", true);
changeCSS("--text-color-primary", "#e0def4", true);
localStorage.setItem("theme", "dark");
}
if (selectedOption == 'light') {
changeCSS('--background-primary', '#d8d8d8', true)
changeCSS('--navbar-color', '#a2a2a2', true)
changeCSS('--navbar-height', '4em', true)
changeCSS('--navbar-text-color', '#000000', true)
changeCSS('--input-text-color', '#e0def4', true)
changeCSS('--input-placeholder-color', 'white', true)
changeCSS('--input-background-color', 'black', true)
changeCSS('--input-border-color', '#eb6f92', true)
changeCSS('--input-border-size', '1.3px', true)
changeCSS('--navbar-link-color', '#000000', true)
changeCSS('--navbar-font', '"Roboto"', true)
changeCSS('--navbar-logo-filter', 'invert(30%)', true)
changeCSS('--text-color-primary', '#303030', true)
localStorage.setItem('theme', 'light')
if (selectedOption == "light") {
changeCSS("--background-primary", "#d8d8d8", true);
changeCSS("--navbar-color", "#a2a2a2", true);
changeCSS("--navbar-height", "4em", true);
changeCSS("--navbar-text-color", "#000000", true);
changeCSS("--input-text-color", "#e0def4", true);
changeCSS("--input-placeholder-color", "white", true);
changeCSS("--input-background-color", "black", true);
changeCSS("--input-border-color", "#eb6f92", true);
changeCSS("--input-border-size", "1.3px", true);
changeCSS("--navbar-link-color", "#000000", true);
changeCSS("--navbar-font", '"Roboto"', true);
changeCSS("--navbar-logo-filter", "invert(30%)", true);
changeCSS("--text-color-primary", "#303030", true);
localStorage.setItem("theme", "light");
}
if (selectedOption == 'custom') {
let response = prompt('Please enter the code for a custom theme:', '')
alert('This feature is not ready yet. Please try again later.')
if (selectedOption == "custom") {
let response = prompt("Please enter the code for a custom theme:", "");
alert("This feature is not ready yet. Please try again later.");
}
}
// onload event
window.onload = function () {
let background = localStorage.getItem('--background-primary')
let navbar = localStorage.getItem('--navbar-color')
let navbarHeight = localStorage.getItem('--navbar-height')
let navbarText = localStorage.getItem('--navbar-text-color')
let inputText = localStorage.getItem('--input-text-color')
let inputPlaceholder = localStorage.getItem('--input-placeholder-color')
let inputBackground = localStorage.getItem('--input-background-color')
let inputBorder = localStorage.getItem('--input-border-color')
let inputBorderSize = localStorage.getItem('--input-border-size')
let navbarFont = localStorage.getItem('--navbar-font')
let navbarLink = localStorage.getItem('--navbar-link-color')
let navbarLogoFilter = localStorage.getItem('--navbar-logo-filter')
let textColorPrimary = localStorage.getItem('--text-color-primary')
changeCSS('--background-primary', background)
changeCSS('--navbar-color', navbar)
changeCSS('--navbar-height', navbarHeight)
changeCSS('--navbar-text-color', navbarText)
changeCSS('--input-text-color', inputText)
changeCSS('--input-placeholder-color', inputPlaceholder)
changeCSS('--input-background-color', inputBackground)
changeCSS('--input-border-color', inputBorder)
changeCSS('--input-border-size', inputBorderSize)
changeCSS('--navbar-link-color', navbarLink)
changeCSS('--navbar-font', navbarFont)
changeCSS('--navbar-logo-filter', navbarLogoFilter)
changeCSS('--text-color-primary', textColorPrimary)
}
let background = localStorage.getItem("--background-primary");
let navbar = localStorage.getItem("--navbar-color");
let navbarHeight = localStorage.getItem("--navbar-height");
let navbarText = localStorage.getItem("--navbar-text-color");
let inputText = localStorage.getItem("--input-text-color");
let inputPlaceholder = localStorage.getItem("--input-placeholder-color");
let inputBackground = localStorage.getItem("--input-background-color");
let inputBorder = localStorage.getItem("--input-border-color");
let inputBorderSize = localStorage.getItem("--input-border-size");
let navbarFont = localStorage.getItem("--navbar-font");
let navbarLink = localStorage.getItem("--navbar-link-color");
let navbarLogoFilter = localStorage.getItem("--navbar-logo-filter");
let textColorPrimary = localStorage.getItem("--text-color-primary");
changeCSS("--background-primary", background);
changeCSS("--navbar-color", navbar);
changeCSS("--navbar-height", navbarHeight);
changeCSS("--navbar-text-color", navbarText);
changeCSS("--input-text-color", inputText);
changeCSS("--input-placeholder-color", inputPlaceholder);
changeCSS("--input-background-color", inputBackground);
changeCSS("--input-border-color", inputBorder);
changeCSS("--input-border-size", inputBorderSize);
changeCSS("--navbar-link-color", navbarLink);
changeCSS("--navbar-font", navbarFont);
changeCSS("--navbar-logo-filter", navbarLogoFilter);
changeCSS("--text-color-primary", textColorPrimary);
};
function changeCSS (variable, value, saveBool) {
document.documentElement.style.setProperty(variable, value)
function changeCSS(variable, value, saveBool) {
document.documentElement.style.setProperty(variable, value);
if (saveBool === true) {
saveCSS(variable, value)
saveCSS(variable, value);
}
}
function saveCSS (variable, value) {
localStorage.setItem(variable, value)
function saveCSS(variable, value) {
localStorage.setItem(variable, value);
}
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 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 () {
console.log('Checked')
function saveIc() {
console.log("Checked");
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
`;
document.getElementById("notifhere").innerHTML = notification;
setTimeout(() => {
var NotificationOBJ = document.getElementById('notifhere')
}, 2000)
var NotificationOBJ = document.getElementById("notifhere");
}, 2000);
}
function unsavedChanges () {
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
`;
document.getElementById("notifhere").innerHTML = notification;
setTimeout(() => {
var NotificationOBJ = document.getElementById('notifhere')
}, 2000)
var NotificationOBJ = document.getElementById("notifhere");
}, 2000);
}
var option = localStorage.getItem('nogg')
var option = localStorage.getItem("nogg");
function toggleNoGG () {
if (option === 'on') {
option = 'off'
localStorage.setItem('nogg', 'off')
function toggleNoGG() {
if (option === "on") {
option = "off";
localStorage.setItem("nogg", "off");
} else {
option = 'on'
localStorage.setItem('nogg', 'on')
option = "on";
localStorage.setItem("nogg", "on");
}
}
var option2 = localStorage.getItem('ADVcloak')
function toggleClickoff () {
if (option2 === 'on') {
option2 = 'off'
localStorage.setItem('ADVcloak', 'off')
var option2 = localStorage.getItem("ADVcloak");
function toggleClickoff() {
if (option2 === "on") {
option2 = "off";
localStorage.setItem("ADVcloak", "off");
} else {
option2 = 'on'
localStorage.setItem('ADVcloak', 'on')
option2 = "on";
localStorage.setItem("ADVcloak", "on");
}
}

File diff suppressed because one or more lines are too long

View file

@ -1,174 +1,174 @@
@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');
@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;
--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';
text-align: center;
font-family: "Roboto";
}
:-moz-placeholder {
text-align: center;
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);
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;
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;
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;
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;
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 */
/* funny number */
#navbar>ul>li {
display: none;
}
#navbar > ul > li {
display: none;
}
.sidenav-btn {
display: flex;
.sidenav-btn {
display: flex;
align-items: center;
position: absolute;
left: 90vw;
width: var(--navbar-height);
height: var(--navbar-height);
}
align-items: center;
position: absolute;
left: 90vw;
width: var(--navbar-height);
height: var(--navbar-height);
}
.sidenav-btn>svg {
width: 50px;
height: 50px;
}
.sidenav-btn > svg {
width: 50px;
height: 50px;
}
#digitalCLOContainerLI {
display: none;
}
#digitalCLOContainerLI {
display: none;
}
#navbar>ul>li>a>svg {
min-width: 24px;
}
#navbar > ul > li > a > svg {
min-width: 24px;
}
}
a {
color: var(--navbar-link-color);
text-decoration: none !important;
font-family: 'Roboto';
color: var(--navbar-link-color);
text-decoration: none !important;
font-family: "Roboto";
}
a:hover {
color: grey;
transition: 0.5s;
cursor: pointer;
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;
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;
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;
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';
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;
font-weight: bold;
display: flex;
align-items: center;
}
*/
@ -179,328 +179,322 @@ ul a {
*/
#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;
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;
visibility: visible;
opacity: 1;
display: block;
}
#navbar ul li p {
color: white;
font-family: 'Calibri';
z-index: 3 !important;
color: white;
font-family: "Calibri";
z-index: 3 !important;
}
#navbar ul li ul li {
clear: both;
width: 100%;
clear: both;
width: 100%;
}
#content {
display: flex;
justify-content: center;
align-items: center;
height: 98%;
color: white;
flex-direction: column;
font-family: 'Roboto';
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;
padding-bottom: 0.5em;
font-weight: 100;
text-align: center;
}
#content img {
padding-left: .5em;
filter: brightness(0) invert(1);
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';
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;
outline: none;
box-shadow: none !important;
}
@keyframes inputwide {
0% {
width: 0px;
transition-duration: 0.5s;
}
0% {
width: 0px;
transition-duration: 0.5s;
}
100% {
width: 300px;
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: .1s;
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;
fill: #eb6f92;
}
.connector {
color: white;
margin-left: 10px;
font-size: 15px;
color: white;
margin-left: 10px;
font-size: 15px;
}
@keyframes popout {
0% {
height: -20px;
}
0% {
height: -20px;
}
100% {
height: 0px;
}
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: .5%;
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%;
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;
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;
}
0% {
opacity: 0;
}
100% {
opacity: 1;
}
100% {
opacity: 1;
}
}
input:focus::placeholder {
color: transparent;
color: transparent;
}
#navbar #thumbImg {
transition: width 2s, height 2s, transform 2s;
filter: var(--navbar-logo-filter);
transition: width 2s, height 2s, transform 2s;
filter: var(--navbar-logo-filter);
}
#navbar #thumbImg:hover {
transform: rotate(360deg);
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;
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;
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;
position: fixed;
right: 0;
bottom: 0;
padding-right: 10px;
}
.tos {
position: fixed;
right: 67px;
bottom: 0;
padding-right: 15px;
position: fixed;
right: 67px;
bottom: 0;
padding-right: 15px;
}
.privacy {
position: fixed;
right: 114px;
bottom: 0;
padding-right: 15px;
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;
;
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;
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 > div {
width: 400px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: 2em;
background: white;
}
.modal-window header {
font-weight: bold;
font-weight: bold;
}
.modal-window h1 {
font-size: 150%;
margin: 0 0 15px;
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;
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;
color: black;
}
.modal-window>div {
border-radius: 1rem;
.modal-window > div {
border-radius: 1rem;
}
.modal-window div:not(:last-of-type) {
margin-bottom: 15px;
margin-bottom: 15px;
}
.logo {
max-width: 150px;
display: block;
max-width: 150px;
display: block;
}
small {
color: lightgray;
color: lightgray;
}
.btn {
background-color: white;
padding: 1em 1.5em;
border-radius: 0.5rem;
text-decoration: none;
background-color: white;
padding: 1em 1.5em;
border-radius: 0.5rem;
text-decoration: none;
}
.btn i {
padding-right: 0.3em;
padding-right: 0.3em;
}
@media only screen and (max-width: 1100px) {
#digitalClock {
display: none;
}
#digitalClock {
display: none;
}
}
.clockColon {
opacity: 100%;
animation: blink .5s step-end infinite alternate;
transition: 0.2s;
opacity: 100%;
animation: blink 0.5s step-end infinite alternate;
transition: 0.2s;
}
@keyframes blink {
50% {
opacity: 0%
}
}
50% {
opacity: 0%;
}
}

View file

@ -1,10 +1,12 @@
importScripts('./uv/uv.sw.js');
importScripts('./osana/osana.worker.js');
importScripts("./uv/uv.sw.js");
importScripts("./osana/osana.worker.js");
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));
});
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));
});

View file

@ -1,87 +1,138 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@100&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@1,700&display=swap" rel="stylesheet">
</head>
<body style="background: #26233a;">
<div style="display: flex;
align-items: center;
justify-content: center;
flex-wrap: nowrap;
flex-direction: row;">
<button id='send-code' style="
background: #eb6f92;
border-radius: 3px;
border: transparent;
width: 268px;
font-size: 18px;
height: 69px;
cursor: pointer;
font-family: 'Roboto', sans-serif;
" > Send Verification Code </button>
<svg style="
color: white;
font-size: 10px;
width: 53px;
" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12h15m0 0l-6.75-6.75M19.5 12l-6.75 6.75" />
</svg>
<input id='codeBox' type="text" placeholder='Enter the code sent to your email' style="width: 268px;
font-size: 18px;
height: 69px;
background: #1f1d2e;
border-color: #eb6f92;
border-width: 1px;
color: white;
font-style: italic;
border-radius: 6px;
text-align: center;">
<svg style="
color: white;
font-size: 10px;
width: 53px;" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12h15m0 0l-6.75-6.75M19.5 12l-6.75 6.75" />
</svg>
<button id="checkCode" style="
background: #eb6f92;
border-radius: 3px;
border: transparent;
width: 268px;
font-size: 18px;
height: 69px;
cursor: pointer;
font-family: 'Roboto', sans-serif;
"> Submit </button>
</div>
<br>
<div style="
display: flex;
align-items: center;
justify-content: center;
align-content: center;
flex-wrap: nowrap;
flex-direction: row;
color: white;
font-family: 'Roboto', sans-serif;
">
<p id='checked'></p>
</div>
<hr>
<div style="
display: flex;
align-items: center;
justify-content: center;
align-content: center;
flex-wrap: nowrap;
flex-direction: row;
color: white;
font-family: 'Roboto', sans-serif;
">
<p id='checked'>You are seeing this screen because the owner of this website has set this site to require email one time password upon entry.</p>
</div>
<script src="resources/v.js"></script>
</body>
</html>
<head>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Roboto:wght@100&display=swap"
rel="stylesheet"
/>
<link
href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@1,700&display=swap"
rel="stylesheet"
/>
</head>
<body style="background: #26233a">
<div
style="
display: flex;
align-items: center;
justify-content: center;
flex-wrap: nowrap;
flex-direction: row;
"
>
<button
id="send-code"
style="
background: #eb6f92;
border-radius: 3px;
border: transparent;
width: 268px;
font-size: 18px;
height: 69px;
cursor: pointer;
font-family: 'Roboto', sans-serif;
"
>
Send Verification Code
</button>
<svg
style="color: white; font-size: 10px; width: 53px"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="w-6 h-6"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M4.5 12h15m0 0l-6.75-6.75M19.5 12l-6.75 6.75"
/>
</svg>
<input
id="codeBox"
type="text"
placeholder="Enter the code sent to your email"
style="
width: 268px;
font-size: 18px;
height: 69px;
background: #1f1d2e;
border-color: #eb6f92;
border-width: 1px;
color: white;
font-style: italic;
border-radius: 6px;
text-align: center;
"
/>
<svg
style="color: white; font-size: 10px; width: 53px"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="w-6 h-6"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M4.5 12h15m0 0l-6.75-6.75M19.5 12l-6.75 6.75"
/>
</svg>
<button
id="checkCode"
style="
background: #eb6f92;
border-radius: 3px;
border: transparent;
width: 268px;
font-size: 18px;
height: 69px;
cursor: pointer;
font-family: 'Roboto', sans-serif;
"
>
Submit
</button>
</div>
<br />
<div
style="
display: flex;
align-items: center;
justify-content: center;
align-content: center;
flex-wrap: nowrap;
flex-direction: row;
color: white;
font-family: 'Roboto', sans-serif;
"
>
<p id="checked"></p>
</div>
<hr />
<div
style="
display: flex;
align-items: center;
justify-content: center;
align-content: center;
flex-wrap: nowrap;
flex-direction: row;
color: white;
font-family: 'Roboto', sans-serif;
"
>
<p id="checked">
You are seeing this screen because the owner of this website has set
this site to require email one time password upon entry.
</p>
</div>
<script src="resources/v.js"></script>
</body>
</html>

View file

@ -1 +1 @@
{"version":"7.10"}
{ "version": "7.11.6" }