This commit is contained in:
Green! 2022-06-07 01:54:29 -04:00
parent ef15e8819d
commit cd9737ddb7
29 changed files with 84099 additions and 37 deletions

74
app.js
View file

@ -12,54 +12,54 @@ const fakeServe = new nodeStatic.Server('fakeStatic/');
const server = https.createServer(); const server = https.createServer();
fs.readdir('/etc/letsencrypt/live', { withFileTypes: true }, (err, files) => { fs.readdir('/etc/letsencrypt/live', { withFileTypes: true }, (err, files) => {
if (!err) if (!err)
files files
.filter(file => file.isDirectory()) .filter(file => file.isDirectory())
.map(folder => folder.name) .map(folder => folder.name)
.forEach(dir => { .forEach(dir => {
server.addContext(dir, { server.addContext(dir, {
key: fs.readFileSync(`/etc/letsencrypt/live/${dir}/privkey.pem`), key: fs.readFileSync(`/etc/letsencrypt/live/${dir}/privkey.pem`),
cert: fs.readFileSync(`/etc/letsencrypt/live/${dir}/fullchain.pem`) cert: fs.readFileSync(`/etc/letsencrypt/live/${dir}/fullchain.pem`)
}); });
}); });
}); });
server.on('request', (request, response) => { server.on('request', (request, response) => {
const ip = request.headers['x-forwarded-for'] || request.connection.remoteAddress; const ip = request.headers['x-forwarded-for'] || request.connection.remoteAddress;
const isLS = ip.startsWith('34.216.110') || ip.startsWith('54.244.51') || ip.startsWith('54.172.60') || ip.startsWith('34.203.250') || ip.startsWith('34.203.254') || ['18.237.145.219', '34.213.241.18', '54.184.142.71', '34.219.54.89', '52.13.31.12', '52.89.157.185', '34.208.60.206', '3.80.101.141', '54.90.242.158', '54.172.185.65', '3.83.250.144', '18.209.180.25', '54.167.181.168', '54.166.136.197', '52.207.207.52', '54.252.242.153', '3.104.121.59', '34.253.198.121', '63.33.56.11', '34.250.114.219', '54.171.251.199'].includes(ip); const isLS = ip.startsWith('34.216.110') || ip.startsWith('54.244.51') || ip.startsWith('54.172.60') || ip.startsWith('34.203.250') || ip.startsWith('34.203.254') || ['18.237.145.219', '34.213.241.18', '54.184.142.71', '34.219.54.89', '52.13.31.12', '52.89.157.185', '34.208.60.206', '3.80.101.141', '54.90.242.158', '54.172.185.65', '3.83.250.144', '18.209.180.25', '54.167.181.168', '54.166.136.197', '52.207.207.52', '54.252.242.153', '3.104.121.59', '34.253.198.121', '63.33.56.11', '34.250.114.219', '54.171.251.199'].includes(ip);
const unlockNow = request.url === '/?unlock'; const unlockNow = request.url === '/?unlock';
if (unlockNow) if (unlockNow)
response.setHeader('Set-Cookie', ['key=standard; expires=Sun, 1 Jan 2023 00:00:00 UTC; path=/']); response.setHeader('Set-Cookie', ['key=standard; expires=Sun, 1 Jan 2023 00:00:00 UTC; path=/']);
const unlockPatronNow = request.url === '/?unlockPatron'; const unlockPatronNow = request.url === '/?unlockPatron';
if (unlockPatronNow) if (unlockPatronNow)
response.setHeader('Set-Cookie', ['key=patron; expires=Sun, 1 Jan 2023 00:00:00 UTC; path=/']); response.setHeader('Set-Cookie', ['key=patron; expires=Sun, 1 Jan 2023 00:00:00 UTC; path=/']);
const unlocked = request.headers['cookie'] === 'key=standard' || unlockNow; const unlocked = request.headers['cookie'] === 'key=standard' || unlockNow;
const patronUnlocked = request.headers['cookie'] === 'key=patron' || unlockPatronNow; const patronUnlocked = request.headers['cookie'] === 'key=patron' || unlockPatronNow;
if (bare.route_request(request, response)) if (bare.route_request(request, response))
return true; return true;
if (!(unlocked || patronUnlocked) && (isLS || request.headers.host === 'nebulaproxy.nebula.bio' && !request.headers['user-agent'].match(/CrOS/))) if (!(unlocked || patronUnlocked) && (isLS || request.headers.host === 'nebulaproxy.nebula.bio' && !request.headers['user-agent'].match(/CrOS/)))
fakeServe.serve(request, response); fakeServe.serve(request, response);
else { else {
if (bare.route_request(request, response)) if (bare.route_request(request, response))
return true; return true;
if (patronUnlocked) if (patronUnlocked)
patronServe.serve(request, response); patronServe.serve(request, response);
else else
serve.serve(request, response); serve.serve(request, response);
} }
}); });
server.on('upgrade', (req, socket, head) => { server.on('upgrade', (req, socket, head) => {
if (bare.route_upgrade(req, socket, head)) if (bare.route_upgrade(req, socket, head))
return; return;
socket.end(); socket.end();
}); });
server.listen(443); server.listen(443);

BIN
static/images/cur.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
static/images/cursor.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

BIN
static/images/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

65
static/index.html Normal file
View file

@ -0,0 +1,65 @@
<!DOCTYPE html>
<html>
<head>
<title>Nebula</title>
<link rel="icon" type="image/x-icon" href="/images/logo.png">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Stylesheets -->
<link rel="stylesheet" href="style/master.css">
<link rel="stylesheet" href="style/main.css">
<!-- Embed -->
<meta name="theme-color" content="#eb6f92">
<meta property="og:title" content="Nebula">
<meta property="og:type" content="website">
<meta property="og:image" content="/images/logo.png">
<meta property="og:description" content="">
</head>
<body>
<!-- Scripts -->
<script src="uv/uv.bundle.js"></script>
<script src="uv/uv.config.js"></script>
<div id="navbar">
<img src='/images/logo.png' id="thumbImg" style='height: 90%; margin-left: 5%; border-radius: 5px; '>
<h1 style='margin-left: .5%; font-family: "Roboto"; color: #4de0fa'>nebula</h1>
<ul>
<!--
<li>
<a onclick="href = '/go/' + __uv$config.encodeUrl('https://discord.gg/neb')">C <ubr>hat </a>
</li>
-->
<li>
<a href="options">Settings</a>
</li>
<li>
<a href="https://discord.gg/bZQxg6SkVp">Need Support?</a>
</li>
</ul>
</div>
<script src="resources/form.js"></script>
<script src="resources/deviceHandler.js"></script>
<div id="content">
<form class="url" action="" method="POST" id="unblocker-form">
<input type="text" id="url" name="url" autocomplete="off" placeholder="Explore the web freely">
</form>
</div>
<!-- Stamp -->
<p class="stamp"> &copy; Nebula Services. All rights reserved. </p>
<!-- Panelbear -->
<script async src="https://cdn.panelbear.com/analytics.js?site=AZa75ZyiRRZ"></script>
<script>
window.panelbear = window.panelbear || function() {
(window.panelbear.q = window.panelbear.q || []).push(arguments);
};
panelbear('config', {
site: 'AZa75ZyiRRZ'
});
</script>
</body>
</html>

BIN
static/mobile/.DS_Store vendored Normal file

Binary file not shown.

49
static/mobile/index.html Normal file
View file

@ -0,0 +1,49 @@
<!DOCTYPE html>
<html>
<head>
<title>Nebula</title>
<link rel="icon" type="image/x-icon" href="/images/logo.png">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Stylesheets -->
<link rel="stylesheet" href="style/master.css">
<link rel="stylesheet" href="style/main.css">
<!-- Embed -->
<meta name="theme-color" content="#eb6f92">
<meta property="og:title" content="Nebula">
<meta property="og:type" content="website">
<meta property="og:image" content="/images/logo.png">
<meta property="og:description" content="">
</head>
<body>
<!-- Scripts -->
<script src="uv/uv.bundle.js"></script>
<script src="uv/uv.config.js"></script>
<div id="navbar">
<img src='/images/logo.png' style='height: 90%; margin-left: 5%; border-radius: 5px; '>
<h1 style='margin-left: .5%; font-family: "Roboto"; color: #4de0fa'>nebula</h1>
<h1 style='margin-left: .5%; font-family: "Roboto"; color: #838282; font-size: 15px; bottom: 0; padding-top: 15px;'>mobile</h1>
</div>
<script src="resources/form.js"></script>
<div id="content">
<form class="url" action="" method="POST" id="unblocker-form">
<input type="text" id="url" name="url" autofocus="" autocomplete="off" placeholder="Explore the web freely">
</form>
</div>
<p class="stamp"> &copy; Nebula Services. All rights reserved. |</p>
<!-- Panelbear -->
<script async src="https://cdn.panelbear.com/analytics.js?site=AZa75ZyiRRZ"></script>
<script>
window.panelbear = window.panelbear || function() {
(window.panelbear.q = window.panelbear.q || []).push(arguments);
};
panelbear('config', {
site: 'AZa75ZyiRRZ'
});
</script>
</body>
</html>

View file

@ -0,0 +1 @@
(function(a,b){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))window.location=b})(navigator.userAgent||navigator.vendor||window.opera,'/mobile');

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,197 @@
:root {
--background-primary: #191724;
--navbar-color: #26233a;
--navbar-height: 4em;
--navbar-text-color: #e0def4;
--input-text-color: #e0def4;
--input-placeholder-color: #6e6a86;
--input-background-color: #1f1d2e;
--input-border-color: #eb6f92;
--input-border-size: 0.1em;
}
::-webkit-input-placeholder {
text-align: center;
font-family: 'Roboto';
}
:-moz-placeholder {
text-align: center;
}
#navbar {
height: 60px;
text-align: center;
align-items: center;
display: flex;
position: fixed;
top: 0;
left: 0;
right: 0;
background-color: var(--navbar-color);
}
a {
color: white;
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';
background-color: var(--navbar-color);
/* box-shadow: 2px 2px rgb(0 0 0 / 20%); */
color: white;
margin-left: auto;
list-style-type: none;
float: right !important;
margin-right: 5%;
}
#navbar ul li {
float: left;
padding-top: 1em;
padding-bottom: 1em;
padding-right: 1em;
padding-left: 1em;
padding: 1rem;
}
::placeholder,
input[type='text'] {
color: white;
font-size: 20px;
text-align: center;
font-family: 'Roboto';
}
#navbar ul p,
ul a {
font-weight: bold;
}
*/
/*
#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: .5em;
filter: brightness(0) invert(1);
}
#content input {
font-size: 20px;
text-align: center;
font-family: 'Calibri';
border-style: solid !important;
border: 1.3px 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;
color: white;
text-align: center;
font-family: 'Roboto';
animation-name: inputwide;
animation-duration: 2s;
}
/*
--input-text-color: #e0def4;
--input-placeholder-color: #6e6a86;
--input-background-color: #1f1d2e;
--input-border-color: #eb6f92;
--input-border-size: 0.1em;
*/
#content input:focus {
/* outline: 1.3px solid #eb6f9; !important;*/
outline: none;
box-shadow: none !important;
}
@keyframes inputwide {
0% {
width: 0px;
transition-duration: 0.5s;
}
100% {
width: 300px;
transition-duration: 0.5s;
}
}

View file

@ -0,0 +1,72 @@
@import url("https://fonts.googleapis.com/css2?family=Dongle&family=Roboto:wght@100&display=swap");
:root {
--background-primary: #191724;
--text-color-primary: #31748f;
--text-color-secondary: #9ccfd8;
--header-color: #26233a;
--header-height: 4em;
--header-text-color: #e0def4;
--input-text-color: white;
--input-placeholder-color: #6e6a86;
--input-background-color: #1f1d2e;
--input-border-color: #eb6f92;
--input-border-size: 0.1em;
}
*,
*::before,
*::after {
padding: 0;
margin: 0;
box-sizing: border-box;
}
html,
body {
margin: 0;
padding: 0;
height: 100%;
}
body {
background-color: var(--background-primary);
color: var(--text-color-primary);
animation: fadeInAnimation ease 3s;
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;
}
#navbar #thumbImg:hover {
transform: rotate(360deg);
}
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@1,100&display=swap');
.stamp {
text-align: left;
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;
}

View file

@ -0,0 +1,230 @@
@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';
}
/*
body {
background-color: var(--background-primary);
}*/
#sidebar {
animation: fadeIn 750ms ease-in 300ms forwards;
-webkit-animation: fadeIn 750ms 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 {
display: flex;
align-items: center;
flex-direction: column;
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%;
}
.name {
color: var(--text-color-primary);
font-size: 2vmax;
margin: 0;
font-family: var(--setting-name-font);
}
.description {
color: var(--text-color-secondary);
margin: 0;
font-size: 2vmax;
font-family: var(--setting-desc-font);
}
.setting-input {
/* left: 100%; */
color: black !important;
position: relative;
/* right: 0; */
transform: translateY(-1.5em);
float: right;
margin-right: 5%;
}
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);
justify-self: end;
font-family: var(--setting-desc-font);
align-self: flex-end;
color: white;
}
@-webkit-keyframes fadeIn {
0% {
opacity: 0.01;
}
100% {
opacity: 1;
}
}
@keyframes fadeIn {
0% {
opacity: 0.01;
}
100% {
opacity: 1;
}
}
.container {
display: flex;
height: 100%;
justify-content: left;
align-items: left;
}
.rectangle {
display: flex;
align-items: center;
justify-content: flex-start;
position: relative;
width: 50px;
margin-left: auto;
margin-top: auto;
height: 50px;
background: #380848;
transform: scale(0);
border-radius: 50%;
color: white;
opacity: 0;
overflow: hidden;
animation: scale-in 0.3s ease-out forwards, expand 0.35s 0.25s ease-out forwards;
}
.notification-text {
display: flex;
align-items: center;
padding: 0 16px;
font-family: 'Roboto', sans-serif;
font-size: 14px;
animation: fade-in 0.65s ease-in forwards;
}
@keyframes scale-in {
100% {
transform: scale(1);
opacity: 1;
}
}
@keyframes expand {
50% {
width: 350px;
border-radius: 6px;
}
100% {
width: 300px;
border-radius: 4px;
box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, .2), 0px 1px 1px 0px rgba(0, 0, 0, .14), 0px 3px 3px -1px rgba(0, 0, 0, .12);
}
}
@keyframes fade-in {
0% {
opacity: 0;
}
100% {
opacity: 0.8;
}
}
.stamp {
text-align: left;
position: fixed;
bottom: 0;
}

5
static/mobile/sw.js Normal file
View file

@ -0,0 +1,5 @@
importScripts('./uv/uv.sw.js');
const sw = new UVServiceWorker();
self.addEventListener('fetch', event => event.respondWith(sw.fetch(event)));

39304
static/mobile/uv/uv.bundle.js Normal file

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,10 @@
self.__uv$config = {
prefix: '/mobile/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',
};

File diff suppressed because it is too large Load diff

789
static/mobile/uv/uv.sw.js Normal file
View file

@ -0,0 +1,789 @@
importScripts('/uv/uv.bundle.js');
importScripts('/uv/uv.config.js');
class UVServiceWorker extends EventEmitter {
constructor(config = __uv$config) {
super();
if (!config.bare) config.bare = '/bare/';
this.addresses = typeof config.bare === 'string' ? [ new URL(config.bare, location) ] : config.bare.map(str => new URL(str, location));
this.headers = {
csp: [
'cross-origin-embedder-policy',
'cross-origin-opener-policy',
'cross-origin-resource-policy',
'content-security-policy',
'content-security-policy-report-only',
'expect-ct',
'feature-policy',
'origin-isolation',
'strict-transport-security',
'upgrade-insecure-requests',
'x-content-type-options',
'x-download-options',
'x-frame-options',
'x-permitted-cross-domain-policies',
'x-powered-by',
'x-xss-protection',
],
forward: [
'accept-encoding',
'connection',
'content-length',
],
};
this.method = {
empty: [
'GET',
'HEAD'
]
};
this.statusCode = {
empty: [
204,
304,
],
};
this.config = config;
this.browser = Ultraviolet.Bowser.getParser(self.navigator.userAgent).getBrowserName();
if (this.browser === 'Firefox') {
this.headers.forward.push('user-agent');
this.headers.forward.push('content-type');
};
};
async fetch({ request }) {
if (!request.url.startsWith(location.origin + (this.config.prefix || '/service/'))) {
return fetch(request);
};
try {
const ultraviolet = new Ultraviolet(this.config);
if (typeof this.config.construct === 'function') {
this.config.construct(ultraviolet, 'service');
};
const db = await ultraviolet.cookie.db();
ultraviolet.meta.origin = location.origin;
ultraviolet.meta.base = ultraviolet.meta.url = new URL(ultraviolet.sourceUrl(request.url));
const requestCtx = new RequestContext(
request,
this,
ultraviolet,
!this.method.empty.includes(request.method.toUpperCase()) ? await request.blob() : null
);
if (ultraviolet.meta.url.protocol === 'blob:') {
requestCtx.blob = true;
requestCtx.base = requestCtx.url = new URL(requestCtx.url.pathname);
};
if (request.referrer && request.referrer.startsWith(location.origin)) {
const referer = new URL(ultraviolet.sourceUrl(request.referrer));
if (requestCtx.headers.origin || ultraviolet.meta.url.origin !== referer.origin && request.mode === 'cors') {
requestCtx.headers.origin = referer.origin;
};
requestCtx.headers.referer = referer.href;
};
const cookies = await ultraviolet.cookie.getCookies(db) || [];
const cookieStr = ultraviolet.cookie.serialize(cookies, ultraviolet.meta, false);
if (this.browser === 'Firefox' && !(request.destination === 'iframe' || request.destination === 'document')) {
requestCtx.forward.shift();
};
if (cookieStr) requestCtx.headers.cookie = cookieStr;
requestCtx.headers.Host = requestCtx.url.host;
const reqEvent = new HookEvent(requestCtx, null, null);
this.emit('request', reqEvent);
if (reqEvent.intercepted) return reqEvent.returnValue;
const response = await fetch(requestCtx.send);
if (response.status === 500) {
return Promise.reject('');
};
const responseCtx = new ResponseContext(requestCtx, response, this);
const resEvent = new HookEvent(responseCtx, null, null);
this.emit('beforemod', resEvent);
if (resEvent.intercepted) return resEvent.returnValue;
for (const name of this.headers.csp) {
if (responseCtx.headers[name]) delete responseCtx.headers[name];
};
if (responseCtx.headers.location) {
responseCtx.headers.location = ultraviolet.rewriteUrl(responseCtx.headers.location);
};
if (responseCtx.headers['set-cookie']) {
Promise.resolve(ultraviolet.cookie.setCookies(responseCtx.headers['set-cookie'], db, ultraviolet.meta)).then(() => {
self.clients.matchAll().then(function (clients){
clients.forEach(function(client){
client.postMessage({
msg: 'updateCookies',
url: ultraviolet.meta.url.href,
});
});
});
});
delete responseCtx.headers['set-cookie'];
};
if (responseCtx.body) {
switch(request.destination) {
case 'script':
case 'worker':
responseCtx.body = `if (!self.__uv && self.importScripts) importScripts('${__uv$config.bundle}', '${__uv$config.config}', '${__uv$config.handler}');\n`;
responseCtx.body += ultraviolet.js.rewrite(
await response.text()
);
break;
case 'style':
responseCtx.body = ultraviolet.rewriteCSS(
await response.text()
);
break;
case 'iframe':
case 'document':
if (isHtml(ultraviolet.meta.url, (responseCtx.headers['content-type'] || ''))) {
responseCtx.body = ultraviolet.rewriteHtml(
await response.text(),
{
document: true ,
injectHead: ultraviolet.createHtmlInject(
this.config.handler,
this.config.bundle,
this.config.config,
ultraviolet.cookie.serialize(cookies, ultraviolet.meta, true),
request.referrer
)
}
);
};
};
};
if (requestCtx.headers.accept === 'text/event-stream') {
responseCtx.headers['content-type'] = 'text/event-stream';
};
this.emit('response', resEvent);
if (resEvent.intercepted) return resEvent.returnValue;
return new Response(responseCtx.body, {
headers: responseCtx.headers,
status: responseCtx.status,
statusText: responseCtx.statusText,
});
} catch(err) {
return new Response(err.toString(), {
status: 500,
});
};
};
getBarerResponse(response) {
const headers = {};
const raw = JSON.parse(response.headers.get('x-bare-headers'));
for (const key in raw) {
headers[key.toLowerCase()] = raw[key];
};
return {
headers,
status: +response.headers.get('x-bare-status'),
statusText: response.headers.get('x-bare-status-text'),
body: !this.statusCode.empty.includes(+response.headers.get('x-bare-status')) ? response.body : null,
};
};
get address() {
return this.addresses[Math.floor(Math.random() * this.addresses.length)];
};
static Ultraviolet = Ultraviolet;
};
self.UVServiceWorker = UVServiceWorker;
class ResponseContext {
constructor(request, response, worker) {
const { headers, status, statusText, body } = !request.blob ? worker.getBarerResponse(response) : {
status: response.status,
statusText: response.statusText,
headers: Object.fromEntries([...response.headers.entries()]),
body: response.body,
};
this.request = request;
this.raw = response;
this.ultraviolet = request.ultraviolet;
this.headers = headers;
this.status = status;
this.statusText = statusText;
this.body = body;
};
get url() {
return this.request.url;
}
get base() {
return this.request.base;
};
set base(val) {
this.request.base = val;
};
};
class RequestContext {
constructor(request, worker, ultraviolet, body = null) {
this.ultraviolet = ultraviolet;
this.request = request;
this.headers = Object.fromEntries([...request.headers.entries()]);
this.method = request.method;
this.forward = [...worker.headers.forward];
this.address = worker.address;
this.body = body || null;
this.redirect = request.redirect;
this.credentials = 'omit';
this.mode = request.mode === 'cors' ? request.mode : 'same-origin';
this.blob = false;
};
get send() {
return new Request((!this.blob ? this.address.href + 'v1/' : 'blob:' + location.origin + this.url.pathname), {
method: this.method,
headers: {
'x-bare-protocol': this.url.protocol,
'x-bare-host': this.url.hostname,
'x-bare-path': this.url.pathname + this.url.search,
'x-bare-port': this.url.port || (this.url.protocol === 'https:' ? '443' : '80'),
'x-bare-headers': JSON.stringify(this.headers),
'x-bare-forward-headers': JSON.stringify(this.forward),
},
redirect: this.redirect,
credentials: this.credentials,
mode: location.origin !== this.address.origin ? 'cors' : this.mode,
body: this.body
});
};
get url() {
return this.ultraviolet.meta.url;
};
set url(val) {
this.ultraviolet.meta.url = val;
};
get base() {
return this.ultraviolet.meta.base;
};
set base(val) {
this.ultraviolet.meta.base = val;
};
}
function isHtml(url, contentType = '') {
return (Ultraviolet.mime.contentType((contentType || url.pathname)) || 'text/html').split(';')[0] === 'text/html';
};
class HookEvent {
#intercepted;
#returnValue;
constructor(data = {}, target = null, that = null) {
this.#intercepted = false;
this.#returnValue = null;
this.data = data;
this.target = target;
this.that = that;
};
get intercepted() {
return this.#intercepted;
};
get returnValue() {
return this.#returnValue;
};
respondWith(input) {
this.#returnValue = input;
this.#intercepted = true;
};
};
var R = typeof Reflect === 'object' ? Reflect : null
var ReflectApply = R && typeof R.apply === 'function'
? R.apply
: function ReflectApply(target, receiver, args) {
return Function.prototype.apply.call(target, receiver, args);
}
var ReflectOwnKeys
if (R && typeof R.ownKeys === 'function') {
ReflectOwnKeys = R.ownKeys
} else if (Object.getOwnPropertySymbols) {
ReflectOwnKeys = function ReflectOwnKeys(target) {
return Object.getOwnPropertyNames(target)
.concat(Object.getOwnPropertySymbols(target));
};
} else {
ReflectOwnKeys = function ReflectOwnKeys(target) {
return Object.getOwnPropertyNames(target);
};
}
function ProcessEmitWarning(warning) {
if (console && console.warn) console.warn(warning);
}
var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {
return value !== value;
}
function EventEmitter() {
EventEmitter.init.call(this);
}
// Backwards-compat with node 0.10.x
EventEmitter.EventEmitter = EventEmitter;
EventEmitter.prototype._events = undefined;
EventEmitter.prototype._eventsCount = 0;
EventEmitter.prototype._maxListeners = undefined;
// By default EventEmitters will print a warning if more than 10 listeners are
// added to it. This is a useful default which helps finding memory leaks.
var defaultMaxListeners = 10;
function checkListener(listener) {
if (typeof listener !== 'function') {
throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
}
}
Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
enumerable: true,
get: function() {
return defaultMaxListeners;
},
set: function(arg) {
if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) {
throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.');
}
defaultMaxListeners = arg;
}
});
EventEmitter.init = function() {
if (this._events === undefined ||
this._events === Object.getPrototypeOf(this)._events) {
this._events = Object.create(null);
this._eventsCount = 0;
}
this._maxListeners = this._maxListeners || undefined;
};
// Obviously not all Emitters should be limited to 10. This function allows
// that to be increased. Set to zero for unlimited.
EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) {
throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.');
}
this._maxListeners = n;
return this;
};
function _getMaxListeners(that) {
if (that._maxListeners === undefined)
return EventEmitter.defaultMaxListeners;
return that._maxListeners;
}
EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
return _getMaxListeners(this);
};
EventEmitter.prototype.emit = function emit(type) {
var args = [];
for (var i = 1; i < arguments.length; i++) args.push(arguments[i]);
var doError = (type === 'error');
var events = this._events;
if (events !== undefined)
doError = (doError && events.error === undefined);
else if (!doError)
return false;
// If there is no 'error' event listener then throw.
if (doError) {
var er;
if (args.length > 0)
er = args[0];
if (er instanceof Error) {
// Note: The comments on the `throw` lines are intentional, they show
// up in Node's output if this results in an unhandled exception.
throw er; // Unhandled 'error' event
}
// At least give some kind of context to the user
var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));
err.context = er;
throw err; // Unhandled 'error' event
}
var handler = events[type];
if (handler === undefined)
return false;
if (typeof handler === 'function') {
ReflectApply(handler, this, args);
} else {
var len = handler.length;
var listeners = arrayClone(handler, len);
for (var i = 0; i < len; ++i)
ReflectApply(listeners[i], this, args);
}
return true;
};
function _addListener(target, type, listener, prepend) {
var m;
var events;
var existing;
checkListener(listener);
events = target._events;
if (events === undefined) {
events = target._events = Object.create(null);
target._eventsCount = 0;
} else {
// To avoid recursion in the case that type === "newListener"! Before
// adding it to the listeners, first emit "newListener".
if (events.newListener !== undefined) {
target.emit('newListener', type,
listener.listener ? listener.listener : listener);
// Re-assign `events` because a newListener handler could have caused the
// this._events to be assigned to a new object
events = target._events;
}
existing = events[type];
}
if (existing === undefined) {
// Optimize the case of one listener. Don't need the extra array object.
existing = events[type] = listener;
++target._eventsCount;
} else {
if (typeof existing === 'function') {
// Adding the second element, need to change to array.
existing = events[type] =
prepend ? [listener, existing] : [existing, listener];
// If we've already got an array, just append.
} else if (prepend) {
existing.unshift(listener);
} else {
existing.push(listener);
}
// Check for listener leak
m = _getMaxListeners(target);
if (m > 0 && existing.length > m && !existing.warned) {
existing.warned = true;
// No error code for this since it is a Warning
// eslint-disable-next-line no-restricted-syntax
var w = new Error('Possible EventEmitter memory leak detected. ' +
existing.length + ' ' + String(type) + ' listeners ' +
'added. Use emitter.setMaxListeners() to ' +
'increase limit');
w.name = 'MaxListenersExceededWarning';
w.emitter = target;
w.type = type;
w.count = existing.length;
ProcessEmitWarning(w);
}
}
return target;
}
EventEmitter.prototype.addListener = function addListener(type, listener) {
return _addListener(this, type, listener, false);
};
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
EventEmitter.prototype.prependListener =
function prependListener(type, listener) {
return _addListener(this, type, listener, true);
};
function onceWrapper() {
if (!this.fired) {
this.target.removeListener(this.type, this.wrapFn);
this.fired = true;
if (arguments.length === 0)
return this.listener.call(this.target);
return this.listener.apply(this.target, arguments);
}
}
function _onceWrap(target, type, listener) {
var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };
var wrapped = onceWrapper.bind(state);
wrapped.listener = listener;
state.wrapFn = wrapped;
return wrapped;
}
EventEmitter.prototype.once = function once(type, listener) {
checkListener(listener);
this.on(type, _onceWrap(this, type, listener));
return this;
};
EventEmitter.prototype.prependOnceListener =
function prependOnceListener(type, listener) {
checkListener(listener);
this.prependListener(type, _onceWrap(this, type, listener));
return this;
};
// Emits a 'removeListener' event if and only if the listener was removed.
EventEmitter.prototype.removeListener =
function removeListener(type, listener) {
var list, events, position, i, originalListener;
checkListener(listener);
events = this._events;
if (events === undefined)
return this;
list = events[type];
if (list === undefined)
return this;
if (list === listener || list.listener === listener) {
if (--this._eventsCount === 0)
this._events = Object.create(null);
else {
delete events[type];
if (events.removeListener)
this.emit('removeListener', type, list.listener || listener);
}
} else if (typeof list !== 'function') {
position = -1;
for (i = list.length - 1; i >= 0; i--) {
if (list[i] === listener || list[i].listener === listener) {
originalListener = list[i].listener;
position = i;
break;
}
}
if (position < 0)
return this;
if (position === 0)
list.shift();
else {
spliceOne(list, position);
}
if (list.length === 1)
events[type] = list[0];
if (events.removeListener !== undefined)
this.emit('removeListener', type, originalListener || listener);
}
return this;
};
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
EventEmitter.prototype.removeAllListeners =
function removeAllListeners(type) {
var listeners, events, i;
events = this._events;
if (events === undefined)
return this;
// not listening for removeListener, no need to emit
if (events.removeListener === undefined) {
if (arguments.length === 0) {
this._events = Object.create(null);
this._eventsCount = 0;
} else if (events[type] !== undefined) {
if (--this._eventsCount === 0)
this._events = Object.create(null);
else
delete events[type];
}
return this;
}
// emit removeListener for all listeners on all events
if (arguments.length === 0) {
var keys = Object.keys(events);
var key;
for (i = 0; i < keys.length; ++i) {
key = keys[i];
if (key === 'removeListener') continue;
this.removeAllListeners(key);
}
this.removeAllListeners('removeListener');
this._events = Object.create(null);
this._eventsCount = 0;
return this;
}
listeners = events[type];
if (typeof listeners === 'function') {
this.removeListener(type, listeners);
} else if (listeners !== undefined) {
// LIFO order
for (i = listeners.length - 1; i >= 0; i--) {
this.removeListener(type, listeners[i]);
}
}
return this;
};
function _listeners(target, type, unwrap) {
var events = target._events;
if (events === undefined)
return [];
var evlistener = events[type];
if (evlistener === undefined)
return [];
if (typeof evlistener === 'function')
return unwrap ? [evlistener.listener || evlistener] : [evlistener];
return unwrap ?
unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
}
EventEmitter.prototype.listeners = function listeners(type) {
return _listeners(this, type, true);
};
EventEmitter.prototype.rawListeners = function rawListeners(type) {
return _listeners(this, type, false);
};
EventEmitter.listenerCount = function(emitter, type) {
if (typeof emitter.listenerCount === 'function') {
return emitter.listenerCount(type);
} else {
return listenerCount.call(emitter, type);
}
};
EventEmitter.prototype.listenerCount = listenerCount;
function listenerCount(type) {
var events = this._events;
if (events !== undefined) {
var evlistener = events[type];
if (typeof evlistener === 'function') {
return 1;
} else if (evlistener !== undefined) {
return evlistener.length;
}
}
return 0;
}
EventEmitter.prototype.eventNames = function eventNames() {
return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];
};
function arrayClone(arr, n) {
var copy = new Array(n);
for (var i = 0; i < n; ++i)
copy[i] = arr[i];
return copy;
}
function spliceOne(list, index) {
for (; index + 1 < list.length; index++)
list[index] = list[index + 1];
list.pop();
}
function unwrapListeners(arr) {
var ret = new Array(arr.length);
for (var i = 0; i < ret.length; ++i) {
ret[i] = arr[i].listener || arr[i];
}
return ret;
}
function once(emitter, name) {
return new Promise(function (resolve, reject) {
function errorListener(err) {
emitter.removeListener(name, resolver);
reject(err);
}
function resolver() {
if (typeof emitter.removeListener === 'function') {
emitter.removeListener('error', errorListener);
}
resolve([].slice.call(arguments));
};
eventTargetAgnosticAddListener(emitter, name, resolver, { once: true });
if (name !== 'error') {
addErrorHandlerIfEventEmitter(emitter, errorListener, { once: true });
}
});
}
function addErrorHandlerIfEventEmitter(emitter, handler, flags) {
if (typeof emitter.on === 'function') {
eventTargetAgnosticAddListener(emitter, 'error', handler, flags);
}
}
function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
if (typeof emitter.on === 'function') {
if (flags.once) {
emitter.once(name, listener);
} else {
emitter.on(name, listener);
}
} else if (typeof emitter.addEventListener === 'function') {
// EventTarget does not have `error` event semantics like Node
// EventEmitters, we do not listen for `error` events here.
emitter.addEventListener(name, function wrapListener(arg) {
// IE does not have builtin `{ once: true }` support so we
// have to do it manually.
if (flags.once) {
emitter.removeEventListener(name, wrapListener);
}
listener(arg);
});
} else {
throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type ' + typeof emitter);
}
}

85
static/options/index.html Normal file
View file

@ -0,0 +1,85 @@
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<head>
<title>Nebula</title>
<link rel="icon" type="image/x-icon" href="../images/fav.png">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Stylesheets -->
<link rel="stylesheet" href="../style/master.css">
<link rel="stylesheet" href="../style/main.css">
<link rel="stylesheet" href="../style/options.css">
<!-- Embed -->
<meta name="theme-color" content="#5a189a">
<meta property=og:title content=Nebula>
<meta property="og:type" content="website" />
<meta property="og:url" content="https://thatonewebsite.mathhelpbeta.gq/images/fav.png" />
<meta property="og:image" content="https://thatonewebsite.mathhelpbeta.gq/images/fav.png" />
<meta property="og:description" content="Welcome To Nebula, Explore the Web. Freely." />
</head>
<body>
<!-- Scripts -->
<script src="../uv/uv.bundle.js"></script>
<script src="../uv/uv.config.js"></script>
<div>
</div>
<div id="navbar" style='background: none;'>
<div>
</div>
</div>
<div class="setting">
<div onclick="window.location ='/';" class="bk-btn">
<div onclick="window.location ='/';" class="bk-btn-triangle"></div>
<div onclick="window.location ='/';" class="bk-btn-bar"></div>
</div>
<div class="settings-cont">
<p class="name"> Stealth Mode <b style="font-size:19px; color: rgb(226, 68, 68);"> NEW </b> </p>
<p class="description"> Prevents teachers, administrators and analytic collection extensions from gathering information, viewing your screen via Browser extension, or browser recording (history) </p>
<input class="setting-input" id="undefined" type="checkbox" onclick="saveIc();toggleNoGG()">
<label for="undefined" class="toogle-button"></label>
</div>
</div>
<div class="settings-cont" style="display: inline-block;">
<p class="name"> Proxy <b style="font-size:19px; color: rgb(226, 68, 68);"> NEW </b> </p>
<p class="description"> Choose the proxy that fits you! </p>
<input class="setting-input" type="checkbox" onclick="saveIc();">
<label for="undefined" class="toogle-button"></label>
</div>
</div>
<div id='sidebar'>
</div>
<p class="stamp"> Version 7.0.4 (Public Release) | &copy; Nebula Services 2021 - Present</p>
<!-- Panelbear -->
<script async src="https://cdn.panelbear.com/analytics.js?site=AZa75ZyiRRZ">
</script>
<script src="../resources/options.js">
</script>
<script>
window.panelbear = window.panelbear || function() {
(window.panelbear.q = window.panelbear.q || []).push(arguments);
};
panelbear('config', {
site: 'AZa75ZyiRRZ'
});
</script>
</body>
</html>

View file

@ -0,0 +1 @@
(function(a,b){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))window.location=b})(navigator.userAgent||navigator.vendor||window.opera,'/mobile');

77
static/resources/form.js Normal file
View file

@ -0,0 +1,77 @@
var option = localStorage.getItem('nogg');
window.addEventListener('load', () => {
function isUrl(val = '') {
if (/^http(s?):\/\//.test(val) || val.includes('.') && val.substr(0, 1) !== ' ') return true;
return false;
};
// NOGG
const useNoGG = false;
const form = document.querySelector('form');
form.addEventListener('submit', event => {
event.preventDefault();
if (typeof navigator.serviceWorker === 'undefined')
alert('Your browser does not support service workers or you are in private browsing!');
navigator.serviceWorker.register('./sw.js', {
scope: __uv$config.prefix
}).then(() => {
const value = event.target.firstElementChild.value;
let url = value.trim();
if (!isUrl(url))
url = 'https://www.google.com/search?q=' + url;
else
if (!(url.startsWith('https://') || url.startsWith('http://'))) url = 'http://' + url;
const redirectTo = __uv$config.prefix + __uv$config.encodeUrl(url);
const option = localStorage.getItem('nogg');
if (option === 'on') {
stealthEngine(redirectTo);
} else location.href = redirectTo;
});
});
// NoGG Engine
function stealthEngine(encodedURL){
// The URL must be encoded ^
let inFrame
try {
inFrame = window !== top
} catch (e) {
inFrame = true
}
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")
const link = location.href
img.rel = "icon"
img.href = "https://ssl.gstatic.com/images/branding/product/1x/drive_2020q4_32dp.png"
doc.title = "Google Drive"
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)
}
}
}});

View file

@ -0,0 +1,52 @@
// Set the option
var option = localStorage.getItem('nogg')
function toggleNoGG() {
if (option === 'on') {
option = 'off';
localStorage.setItem('nogg', 'off');
} else {
option = 'on';
localStorage.setItem('nogg', 'on');
}
}
console.log(localStorage.getItem('nogg'))
// Notification Banner
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('navbar').innerHTML = notification
setTimeout(() => {
var NotificationOBJ = document.getElementById('notif')
}, 2000);
};
// Update the CheckBox to match the settings
window.onload = function() {
console.log("Current Settings: ")
console.log("NoGG = ", localStorage.getItem('nogg'))
if (localStorage.getItem('nogg') == 'on') {
setTimeout(() => {
var item = document.getElementById("undefined");
document.getElementById("undefined").checked = true;}, 600);
}};

197
static/style/main.css Normal file
View file

@ -0,0 +1,197 @@
:root {
--background-primary: #191724;
--navbar-color: #26233a;
--navbar-height: 4em;
--navbar-text-color: #e0def4;
--input-text-color: #e0def4;
--input-placeholder-color: #6e6a86;
--input-background-color: #1f1d2e;
--input-border-color: #eb6f92;
--input-border-size: 0.1em;
}
::-webkit-input-placeholder {
text-align: center;
font-family: 'Roboto';
}
:-moz-placeholder {
text-align: center;
}
#navbar {
height: 60px;
text-align: center;
align-items: center;
display: flex;
position: fixed;
top: 0;
left: 0;
right: 0;
background-color: var(--navbar-color);
}
a {
color: white;
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';
background-color: var(--navbar-color);
/* box-shadow: 2px 2px rgb(0 0 0 / 20%); */
color: white;
margin-left: auto;
list-style-type: none;
float: right !important;
margin-right: 5%;
}
#navbar ul li {
float: left;
padding-top: 1em;
padding-bottom: 1em;
padding-right: 1em;
padding-left: 1em;
padding: 1rem;
}
::placeholder,
input[type='text'] {
color: white;
font-size: 20px;
text-align: center;
font-family: 'Roboto';
}
#navbar ul p,
ul a {
font-weight: bold;
}
*/
/*
#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: .5em;
filter: brightness(0) invert(1);
}
#content input {
font-size: 20px;
text-align: center;
font-family: 'Calibri';
border-style: solid !important;
border: 1.3px 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;
color: white;
text-align: center;
font-family: 'Roboto';
animation-name: inputwide;
animation-duration: 2s;
}
/*
--input-text-color: #e0def4;
--input-placeholder-color: #6e6a86;
--input-background-color: #1f1d2e;
--input-border-color: #eb6f92;
--input-border-size: 0.1em;
*/
#content input:focus {
/* outline: 1.3px solid #eb6f9; !important;*/
outline: none;
box-shadow: none !important;
}
@keyframes inputwide {
0% {
width: 0px;
transition-duration: 0.5s;
}
100% {
width: 300px;
transition-duration: 0.5s;
}
}

74
static/style/master.css Normal file
View file

@ -0,0 +1,74 @@
@import url("https://fonts.googleapis.com/css2?family=Dongle&family=Roboto:wght@100&display=swap");
:root {
--background-primary: #191724;
--text-color-primary: #31748f;
--text-color-secondary: #9ccfd8;
--header-color: #26233a;
--header-height: 4em;
--header-text-color: #e0def4;
--input-text-color: white;
--input-placeholder-color: #6e6a86;
--input-background-color: #1f1d2e;
--input-border-color: #eb6f92;
--input-border-size: 0.1em;
}
*,
*::before,
*::after {
padding: 0;
margin: 0;
box-sizing: border-box;
}
html,
body {
margin: 0;
padding: 0;
height: 100%;
cursor: url("../images/cur.gif"), url("../images/cursor.cur"), default;
}
body {
background-color: var(--background-primary);
color: var(--text-color-primary);
animation: fadeInAnimation ease 3s;
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;
}
#navbar #thumbImg:hover {
transform: rotate(360deg);
}
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@1,100&display=swap');
.stamp {
text-align: left;
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;
}

328
static/style/options.css Normal file
View file

@ -0,0 +1,328 @@
@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;
overflow: hidden;
}
/*
body {
background-color: var(--background-primary);
}*/
#sidebar {
animation: fadeIn 750ms ease-in 300ms forwards;
-webkit-animation: fadeIn 750ms 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 {
display: flex;
align-items: center;
flex-direction: column;
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);
justify-self: end;
font-family: var(--setting-desc-font);
align-self: flex-end;
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: 15px;
right: 15px;
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: #55b559;
}
.notification-warning {
background-color: #ff9e0f;
}
.notification-danger {
background-color: #f55145;
}
@keyframes fade-in {
0% {
opacity: 0;
}
100% {
opacity: 0.8;
}
}
.stamp {
text-align: left;
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;
}
.settings-cont {
box-sizing: border-box;
width: 300px;
height: 246px;
padding: 30px;
border: 2px solid rgb(121 103 221);
border-radius: 9px;
margin-top: 20px;
}
.name {
color: var(--text-color-primary);
font-size: 2vmax;
margin: 0;
font-family: var(--setting-name-font);
}
.description {
color: var(--text-color-secondary);
margin: 0;
font-size: 17px;
font-family: var(--setting-desc-font);
}

5
static/sw.js Normal file
View file

@ -0,0 +1,5 @@
importScripts('./uv/uv.sw.js');
const sw = new UVServiceWorker();
self.addEventListener('fetch', event => event.respondWith(sw.fetch(event)));

39304
static/uv/uv.bundle.js Normal file

File diff suppressed because one or more lines are too long

10
static/uv/uv.config.js Normal file
View file

@ -0,0 +1,10 @@
self.__uv$config = {
prefix: '/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',
};

1129
static/uv/uv.handler.js Normal file

File diff suppressed because it is too large Load diff

789
static/uv/uv.sw.js Normal file
View file

@ -0,0 +1,789 @@
importScripts('/uv/uv.bundle.js');
importScripts('/uv/uv.config.js');
class UVServiceWorker extends EventEmitter {
constructor(config = __uv$config) {
super();
if (!config.bare) config.bare = '/bare/';
this.addresses = typeof config.bare === 'string' ? [ new URL(config.bare, location) ] : config.bare.map(str => new URL(str, location));
this.headers = {
csp: [
'cross-origin-embedder-policy',
'cross-origin-opener-policy',
'cross-origin-resource-policy',
'content-security-policy',
'content-security-policy-report-only',
'expect-ct',
'feature-policy',
'origin-isolation',
'strict-transport-security',
'upgrade-insecure-requests',
'x-content-type-options',
'x-download-options',
'x-frame-options',
'x-permitted-cross-domain-policies',
'x-powered-by',
'x-xss-protection',
],
forward: [
'accept-encoding',
'connection',
'content-length',
],
};
this.method = {
empty: [
'GET',
'HEAD'
]
};
this.statusCode = {
empty: [
204,
304,
],
};
this.config = config;
this.browser = Ultraviolet.Bowser.getParser(self.navigator.userAgent).getBrowserName();
if (this.browser === 'Firefox') {
this.headers.forward.push('user-agent');
this.headers.forward.push('content-type');
};
};
async fetch({ request }) {
if (!request.url.startsWith(location.origin + (this.config.prefix || '/service/'))) {
return fetch(request);
};
try {
const ultraviolet = new Ultraviolet(this.config);
if (typeof this.config.construct === 'function') {
this.config.construct(ultraviolet, 'service');
};
const db = await ultraviolet.cookie.db();
ultraviolet.meta.origin = location.origin;
ultraviolet.meta.base = ultraviolet.meta.url = new URL(ultraviolet.sourceUrl(request.url));
const requestCtx = new RequestContext(
request,
this,
ultraviolet,
!this.method.empty.includes(request.method.toUpperCase()) ? await request.blob() : null
);
if (ultraviolet.meta.url.protocol === 'blob:') {
requestCtx.blob = true;
requestCtx.base = requestCtx.url = new URL(requestCtx.url.pathname);
};
if (request.referrer && request.referrer.startsWith(location.origin)) {
const referer = new URL(ultraviolet.sourceUrl(request.referrer));
if (requestCtx.headers.origin || ultraviolet.meta.url.origin !== referer.origin && request.mode === 'cors') {
requestCtx.headers.origin = referer.origin;
};
requestCtx.headers.referer = referer.href;
};
const cookies = await ultraviolet.cookie.getCookies(db) || [];
const cookieStr = ultraviolet.cookie.serialize(cookies, ultraviolet.meta, false);
if (this.browser === 'Firefox' && !(request.destination === 'iframe' || request.destination === 'document')) {
requestCtx.forward.shift();
};
if (cookieStr) requestCtx.headers.cookie = cookieStr;
requestCtx.headers.Host = requestCtx.url.host;
const reqEvent = new HookEvent(requestCtx, null, null);
this.emit('request', reqEvent);
if (reqEvent.intercepted) return reqEvent.returnValue;
const response = await fetch(requestCtx.send);
if (response.status === 500) {
return Promise.reject('');
};
const responseCtx = new ResponseContext(requestCtx, response, this);
const resEvent = new HookEvent(responseCtx, null, null);
this.emit('beforemod', resEvent);
if (resEvent.intercepted) return resEvent.returnValue;
for (const name of this.headers.csp) {
if (responseCtx.headers[name]) delete responseCtx.headers[name];
};
if (responseCtx.headers.location) {
responseCtx.headers.location = ultraviolet.rewriteUrl(responseCtx.headers.location);
};
if (responseCtx.headers['set-cookie']) {
Promise.resolve(ultraviolet.cookie.setCookies(responseCtx.headers['set-cookie'], db, ultraviolet.meta)).then(() => {
self.clients.matchAll().then(function (clients){
clients.forEach(function(client){
client.postMessage({
msg: 'updateCookies',
url: ultraviolet.meta.url.href,
});
});
});
});
delete responseCtx.headers['set-cookie'];
};
if (responseCtx.body) {
switch(request.destination) {
case 'script':
case 'worker':
responseCtx.body = `if (!self.__uv && self.importScripts) importScripts('${__uv$config.bundle}', '${__uv$config.config}', '${__uv$config.handler}');\n`;
responseCtx.body += ultraviolet.js.rewrite(
await response.text()
);
break;
case 'style':
responseCtx.body = ultraviolet.rewriteCSS(
await response.text()
);
break;
case 'iframe':
case 'document':
if (isHtml(ultraviolet.meta.url, (responseCtx.headers['content-type'] || ''))) {
responseCtx.body = ultraviolet.rewriteHtml(
await response.text(),
{
document: true ,
injectHead: ultraviolet.createHtmlInject(
this.config.handler,
this.config.bundle,
this.config.config,
ultraviolet.cookie.serialize(cookies, ultraviolet.meta, true),
request.referrer
)
}
);
};
};
};
if (requestCtx.headers.accept === 'text/event-stream') {
responseCtx.headers['content-type'] = 'text/event-stream';
};
this.emit('response', resEvent);
if (resEvent.intercepted) return resEvent.returnValue;
return new Response(responseCtx.body, {
headers: responseCtx.headers,
status: responseCtx.status,
statusText: responseCtx.statusText,
});
} catch(err) {
return new Response(err.toString(), {
status: 500,
});
};
};
getBarerResponse(response) {
const headers = {};
const raw = JSON.parse(response.headers.get('x-bare-headers'));
for (const key in raw) {
headers[key.toLowerCase()] = raw[key];
};
return {
headers,
status: +response.headers.get('x-bare-status'),
statusText: response.headers.get('x-bare-status-text'),
body: !this.statusCode.empty.includes(+response.headers.get('x-bare-status')) ? response.body : null,
};
};
get address() {
return this.addresses[Math.floor(Math.random() * this.addresses.length)];
};
static Ultraviolet = Ultraviolet;
};
self.UVServiceWorker = UVServiceWorker;
class ResponseContext {
constructor(request, response, worker) {
const { headers, status, statusText, body } = !request.blob ? worker.getBarerResponse(response) : {
status: response.status,
statusText: response.statusText,
headers: Object.fromEntries([...response.headers.entries()]),
body: response.body,
};
this.request = request;
this.raw = response;
this.ultraviolet = request.ultraviolet;
this.headers = headers;
this.status = status;
this.statusText = statusText;
this.body = body;
};
get url() {
return this.request.url;
}
get base() {
return this.request.base;
};
set base(val) {
this.request.base = val;
};
};
class RequestContext {
constructor(request, worker, ultraviolet, body = null) {
this.ultraviolet = ultraviolet;
this.request = request;
this.headers = Object.fromEntries([...request.headers.entries()]);
this.method = request.method;
this.forward = [...worker.headers.forward];
this.address = worker.address;
this.body = body || null;
this.redirect = request.redirect;
this.credentials = 'omit';
this.mode = request.mode === 'cors' ? request.mode : 'same-origin';
this.blob = false;
};
get send() {
return new Request((!this.blob ? this.address.href + 'v1/' : 'blob:' + location.origin + this.url.pathname), {
method: this.method,
headers: {
'x-bare-protocol': this.url.protocol,
'x-bare-host': this.url.hostname,
'x-bare-path': this.url.pathname + this.url.search,
'x-bare-port': this.url.port || (this.url.protocol === 'https:' ? '443' : '80'),
'x-bare-headers': JSON.stringify(this.headers),
'x-bare-forward-headers': JSON.stringify(this.forward),
},
redirect: this.redirect,
credentials: this.credentials,
mode: location.origin !== this.address.origin ? 'cors' : this.mode,
body: this.body
});
};
get url() {
return this.ultraviolet.meta.url;
};
set url(val) {
this.ultraviolet.meta.url = val;
};
get base() {
return this.ultraviolet.meta.base;
};
set base(val) {
this.ultraviolet.meta.base = val;
};
}
function isHtml(url, contentType = '') {
return (Ultraviolet.mime.contentType((contentType || url.pathname)) || 'text/html').split(';')[0] === 'text/html';
};
class HookEvent {
#intercepted;
#returnValue;
constructor(data = {}, target = null, that = null) {
this.#intercepted = false;
this.#returnValue = null;
this.data = data;
this.target = target;
this.that = that;
};
get intercepted() {
return this.#intercepted;
};
get returnValue() {
return this.#returnValue;
};
respondWith(input) {
this.#returnValue = input;
this.#intercepted = true;
};
};
var R = typeof Reflect === 'object' ? Reflect : null
var ReflectApply = R && typeof R.apply === 'function'
? R.apply
: function ReflectApply(target, receiver, args) {
return Function.prototype.apply.call(target, receiver, args);
}
var ReflectOwnKeys
if (R && typeof R.ownKeys === 'function') {
ReflectOwnKeys = R.ownKeys
} else if (Object.getOwnPropertySymbols) {
ReflectOwnKeys = function ReflectOwnKeys(target) {
return Object.getOwnPropertyNames(target)
.concat(Object.getOwnPropertySymbols(target));
};
} else {
ReflectOwnKeys = function ReflectOwnKeys(target) {
return Object.getOwnPropertyNames(target);
};
}
function ProcessEmitWarning(warning) {
if (console && console.warn) console.warn(warning);
}
var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {
return value !== value;
}
function EventEmitter() {
EventEmitter.init.call(this);
}
// Backwards-compat with node 0.10.x
EventEmitter.EventEmitter = EventEmitter;
EventEmitter.prototype._events = undefined;
EventEmitter.prototype._eventsCount = 0;
EventEmitter.prototype._maxListeners = undefined;
// By default EventEmitters will print a warning if more than 10 listeners are
// added to it. This is a useful default which helps finding memory leaks.
var defaultMaxListeners = 10;
function checkListener(listener) {
if (typeof listener !== 'function') {
throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
}
}
Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
enumerable: true,
get: function() {
return defaultMaxListeners;
},
set: function(arg) {
if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) {
throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.');
}
defaultMaxListeners = arg;
}
});
EventEmitter.init = function() {
if (this._events === undefined ||
this._events === Object.getPrototypeOf(this)._events) {
this._events = Object.create(null);
this._eventsCount = 0;
}
this._maxListeners = this._maxListeners || undefined;
};
// Obviously not all Emitters should be limited to 10. This function allows
// that to be increased. Set to zero for unlimited.
EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) {
throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.');
}
this._maxListeners = n;
return this;
};
function _getMaxListeners(that) {
if (that._maxListeners === undefined)
return EventEmitter.defaultMaxListeners;
return that._maxListeners;
}
EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
return _getMaxListeners(this);
};
EventEmitter.prototype.emit = function emit(type) {
var args = [];
for (var i = 1; i < arguments.length; i++) args.push(arguments[i]);
var doError = (type === 'error');
var events = this._events;
if (events !== undefined)
doError = (doError && events.error === undefined);
else if (!doError)
return false;
// If there is no 'error' event listener then throw.
if (doError) {
var er;
if (args.length > 0)
er = args[0];
if (er instanceof Error) {
// Note: The comments on the `throw` lines are intentional, they show
// up in Node's output if this results in an unhandled exception.
throw er; // Unhandled 'error' event
}
// At least give some kind of context to the user
var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));
err.context = er;
throw err; // Unhandled 'error' event
}
var handler = events[type];
if (handler === undefined)
return false;
if (typeof handler === 'function') {
ReflectApply(handler, this, args);
} else {
var len = handler.length;
var listeners = arrayClone(handler, len);
for (var i = 0; i < len; ++i)
ReflectApply(listeners[i], this, args);
}
return true;
};
function _addListener(target, type, listener, prepend) {
var m;
var events;
var existing;
checkListener(listener);
events = target._events;
if (events === undefined) {
events = target._events = Object.create(null);
target._eventsCount = 0;
} else {
// To avoid recursion in the case that type === "newListener"! Before
// adding it to the listeners, first emit "newListener".
if (events.newListener !== undefined) {
target.emit('newListener', type,
listener.listener ? listener.listener : listener);
// Re-assign `events` because a newListener handler could have caused the
// this._events to be assigned to a new object
events = target._events;
}
existing = events[type];
}
if (existing === undefined) {
// Optimize the case of one listener. Don't need the extra array object.
existing = events[type] = listener;
++target._eventsCount;
} else {
if (typeof existing === 'function') {
// Adding the second element, need to change to array.
existing = events[type] =
prepend ? [listener, existing] : [existing, listener];
// If we've already got an array, just append.
} else if (prepend) {
existing.unshift(listener);
} else {
existing.push(listener);
}
// Check for listener leak
m = _getMaxListeners(target);
if (m > 0 && existing.length > m && !existing.warned) {
existing.warned = true;
// No error code for this since it is a Warning
// eslint-disable-next-line no-restricted-syntax
var w = new Error('Possible EventEmitter memory leak detected. ' +
existing.length + ' ' + String(type) + ' listeners ' +
'added. Use emitter.setMaxListeners() to ' +
'increase limit');
w.name = 'MaxListenersExceededWarning';
w.emitter = target;
w.type = type;
w.count = existing.length;
ProcessEmitWarning(w);
}
}
return target;
}
EventEmitter.prototype.addListener = function addListener(type, listener) {
return _addListener(this, type, listener, false);
};
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
EventEmitter.prototype.prependListener =
function prependListener(type, listener) {
return _addListener(this, type, listener, true);
};
function onceWrapper() {
if (!this.fired) {
this.target.removeListener(this.type, this.wrapFn);
this.fired = true;
if (arguments.length === 0)
return this.listener.call(this.target);
return this.listener.apply(this.target, arguments);
}
}
function _onceWrap(target, type, listener) {
var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };
var wrapped = onceWrapper.bind(state);
wrapped.listener = listener;
state.wrapFn = wrapped;
return wrapped;
}
EventEmitter.prototype.once = function once(type, listener) {
checkListener(listener);
this.on(type, _onceWrap(this, type, listener));
return this;
};
EventEmitter.prototype.prependOnceListener =
function prependOnceListener(type, listener) {
checkListener(listener);
this.prependListener(type, _onceWrap(this, type, listener));
return this;
};
// Emits a 'removeListener' event if and only if the listener was removed.
EventEmitter.prototype.removeListener =
function removeListener(type, listener) {
var list, events, position, i, originalListener;
checkListener(listener);
events = this._events;
if (events === undefined)
return this;
list = events[type];
if (list === undefined)
return this;
if (list === listener || list.listener === listener) {
if (--this._eventsCount === 0)
this._events = Object.create(null);
else {
delete events[type];
if (events.removeListener)
this.emit('removeListener', type, list.listener || listener);
}
} else if (typeof list !== 'function') {
position = -1;
for (i = list.length - 1; i >= 0; i--) {
if (list[i] === listener || list[i].listener === listener) {
originalListener = list[i].listener;
position = i;
break;
}
}
if (position < 0)
return this;
if (position === 0)
list.shift();
else {
spliceOne(list, position);
}
if (list.length === 1)
events[type] = list[0];
if (events.removeListener !== undefined)
this.emit('removeListener', type, originalListener || listener);
}
return this;
};
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
EventEmitter.prototype.removeAllListeners =
function removeAllListeners(type) {
var listeners, events, i;
events = this._events;
if (events === undefined)
return this;
// not listening for removeListener, no need to emit
if (events.removeListener === undefined) {
if (arguments.length === 0) {
this._events = Object.create(null);
this._eventsCount = 0;
} else if (events[type] !== undefined) {
if (--this._eventsCount === 0)
this._events = Object.create(null);
else
delete events[type];
}
return this;
}
// emit removeListener for all listeners on all events
if (arguments.length === 0) {
var keys = Object.keys(events);
var key;
for (i = 0; i < keys.length; ++i) {
key = keys[i];
if (key === 'removeListener') continue;
this.removeAllListeners(key);
}
this.removeAllListeners('removeListener');
this._events = Object.create(null);
this._eventsCount = 0;
return this;
}
listeners = events[type];
if (typeof listeners === 'function') {
this.removeListener(type, listeners);
} else if (listeners !== undefined) {
// LIFO order
for (i = listeners.length - 1; i >= 0; i--) {
this.removeListener(type, listeners[i]);
}
}
return this;
};
function _listeners(target, type, unwrap) {
var events = target._events;
if (events === undefined)
return [];
var evlistener = events[type];
if (evlistener === undefined)
return [];
if (typeof evlistener === 'function')
return unwrap ? [evlistener.listener || evlistener] : [evlistener];
return unwrap ?
unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
}
EventEmitter.prototype.listeners = function listeners(type) {
return _listeners(this, type, true);
};
EventEmitter.prototype.rawListeners = function rawListeners(type) {
return _listeners(this, type, false);
};
EventEmitter.listenerCount = function(emitter, type) {
if (typeof emitter.listenerCount === 'function') {
return emitter.listenerCount(type);
} else {
return listenerCount.call(emitter, type);
}
};
EventEmitter.prototype.listenerCount = listenerCount;
function listenerCount(type) {
var events = this._events;
if (events !== undefined) {
var evlistener = events[type];
if (typeof evlistener === 'function') {
return 1;
} else if (evlistener !== undefined) {
return evlistener.length;
}
}
return 0;
}
EventEmitter.prototype.eventNames = function eventNames() {
return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];
};
function arrayClone(arr, n) {
var copy = new Array(n);
for (var i = 0; i < n; ++i)
copy[i] = arr[i];
return copy;
}
function spliceOne(list, index) {
for (; index + 1 < list.length; index++)
list[index] = list[index + 1];
list.pop();
}
function unwrapListeners(arr) {
var ret = new Array(arr.length);
for (var i = 0; i < ret.length; ++i) {
ret[i] = arr[i].listener || arr[i];
}
return ret;
}
function once(emitter, name) {
return new Promise(function (resolve, reject) {
function errorListener(err) {
emitter.removeListener(name, resolver);
reject(err);
}
function resolver() {
if (typeof emitter.removeListener === 'function') {
emitter.removeListener('error', errorListener);
}
resolve([].slice.call(arguments));
};
eventTargetAgnosticAddListener(emitter, name, resolver, { once: true });
if (name !== 'error') {
addErrorHandlerIfEventEmitter(emitter, errorListener, { once: true });
}
});
}
function addErrorHandlerIfEventEmitter(emitter, handler, flags) {
if (typeof emitter.on === 'function') {
eventTargetAgnosticAddListener(emitter, 'error', handler, flags);
}
}
function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
if (typeof emitter.on === 'function') {
if (flags.once) {
emitter.once(name, listener);
} else {
emitter.on(name, listener);
}
} else if (typeof emitter.addEventListener === 'function') {
// EventTarget does not have `error` event semantics like Node
// EventEmitters, we do not listen for `error` events here.
emitter.addEventListener(name, function wrapListener(arg) {
// IE does not have builtin `{ once: true }` support so we
// have to do it manually.
if (flags.once) {
emitter.removeEventListener(name, wrapListener);
}
listener(arg);
});
} else {
throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type ' + typeof emitter);
}
}