This commit is contained in:
Russell2259
2023-12-21 00:05:11 +00:00
parent 00f29e2595
commit d2882efcb0
25 changed files with 550 additions and 241 deletions
+1 -1
View File
@@ -15,7 +15,7 @@
<!--el:navbar-->
<!--el:sidebar-->
<div class="content box">
<div class="container centered">
<h1 style="font-size: 50px;">404</h1>
<p>
+2 -2
View File
@@ -1,4 +1,4 @@
import configTemplate from './polaris.config.template.js';
import configTemplate from './polaris.config.template.js';
/**
* @type {configTemplate}
@@ -6,7 +6,7 @@ import configTemplate from './polaris.config.template.js';
export default {
port: 8080,
mode: 'dev',
minify: true,
minify: false,
assetScrambling: true,
allowDangerousTemplateInsert: true
};
+21 -15
View File
@@ -15,7 +15,7 @@ const app = express();
const server = http.createServer();
const bareServer = createBareServer('/bare/');
const mode = (process.argv[2] === 'prod' || process.argv[2] === 'dev' ? process.argv[2] : (process.argv[3] === 'prod' || process.argv[3] === 'dev' ? process.argv[3] : (config.mode === 'prod' || config.mode === 'dev' ? config.mode : 'prod')));
const port = (process.argv[2] !== 'prod' && process.argv[2] !== 'dev' && Boolean(Number(process.argv[2]))) ? process.argv[2] : (Boolean(Number(process.argv[3])) ? process.argv[3] : (Boolean(Number(config.port)) ? config.port : (mode === 'prod' ? 80 : 8080 ) ));
const port = (process.argv[2] !== 'prod' && process.argv[2] !== 'dev' && Boolean(Number(process.argv[2]))) ? process.argv[2] : (Boolean(Number(process.argv[3])) ? process.argv[3] : (Boolean(Number(config.port)) ? config.port : (mode === 'prod' ? 80 : 8080)));
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
app.get('/cdn/*', cors({
@@ -61,7 +61,7 @@ app.get('/asset/:token', async (req, res, next) => {
TokenManager.delete(req.params.token);
res.setHeader('content-type', token.data.type);
res.end(await rewriter.auto(fs.readFileSync(token.data.asset), token.data.type));
res.end(await rewriter.auto(fs.readFileSync(token.data.asset), token.data.type, token.data.asset.replace(path.join(__dirname, '../static'), '')));
} else next();
} else next();
}
@@ -73,21 +73,27 @@ app.get('/uv/service*', async (req, res) => {
});
app.use(async (req, res, next) => {
const {
exists,
path: filePath
} = pathToFile(req.path, path.join(__dirname, '../static'));
if (req.path === '/index') res.redirect('/');
else {
const {
exists,
path: filePath
} = pathToFile(req.path, path.join(__dirname, '../static'));
if (exists) {
res.setHeader('content-type', mime.getType(filePath));
if (exists) {
if (req.path.endsWith('.html')) res.redirect(req.path.slice(0, -5));
else {
res.setHeader('content-type', mime.getType(filePath));
if (mime.getType(filePath) === 'text/html') res.end(await rewriter.html(fs.readFileSync(filePath)));
else if (mime.getType(filePath) === 'text/javascript') res.end(await rewriter.javascript(fs.readFileSync(filePath)));
else if (mime.getType(filePath) === 'text/css') res.end(await rewriter.css(fs.readFileSync(filePath)));
else res.sendFile(filePath);
} else {
res.setHeader('content-type', 'text/html');
res.status(404).end(await rewriter.html(fs.readFileSync(path.join(__dirname, '../pages/404.html'))));
if (mime.getType(filePath) === 'text/html') res.end(await rewriter.html(fs.readFileSync(filePath), req.path));
else if (mime.getType(filePath) === 'text/javascript') res.end(await rewriter.javascript(fs.readFileSync(filePath), req.path));
else if (mime.getType(filePath) === 'text/css') res.end(await rewriter.css(fs.readFileSync(filePath), req.path));
else res.sendFile(filePath);
}
} else {
res.setHeader('content-type', 'text/html');
res.status(404).end(await rewriter.html(fs.readFileSync(path.join(__dirname, '../pages/404.html'))));
}
}
});
+64 -42
View File
@@ -92,43 +92,54 @@ const html = (data) => {
});
};
const javascript = (data) => {
const javascript = (data, filePath) => {
return new Promise((resolve, reject) => {
const imports = String(data).split('import ')
.map(data => data.split('from ')[1])
.filter(data => Boolean(data))
.map(data => data.split(';')[0]
.map(data => data.split('\n')[0]
.replaceAll('\'', '')
.replaceAll('`', '')
.replaceAll('"', ''))
.filter(data => fs.existsSync(path.join(__dirname, '../templates', data + '.javascript')));
.replaceAll('"', '')
.replaceAll(';', ''))
.map(data => {
if (data.startsWith('./')) return {
originalFile: data,
newFile: path.join(filePath.split('/').slice(0, -1).join('/'), data)
};
else if (data.startsWith('../')) return {
originalFile: data,
newFile: path.join(filePath.split('/').slice(0, -1).join('/'), data)
};
else return {
originalFile: data,
newFile: data
};
})
.filter(data => fs.existsSync(path.join(__dirname, '../static', data.newFile)));
let javascript = String(data);
if (config.assetScrambling) for (let i = 0; i < imports.length; i++) {
javascript = javascript.replace(imports[i], '/asset/' + TokenManager.generate('asset', 20000, {
asset: path.join(__dirname, '../static', imports[i]),
type: 'text/javascript'
}).token);
}
if (config.assetScrambling) for (let i = 0; i < imports.length; i++) javascript = javascript.replace(imports[i].originalFile, '/asset/' + TokenManager.generate('asset', 20000, {
asset: path.join(__dirname, '../static', imports[i].newFile),
type: 'text/javascript'
}).token);
if (config.minify) resolve(JavaScriptObfuscator.obfuscate(javascript,
{
compact: true,
controlFlowFlattening: true,
controlFlowFlatteningThreshold: 1,
numbersToExpressions: true,
simplify: true,
stringArrayShuffle: true,
splitStrings: true,
stringArrayThreshold: 1
}).getObfuscatedCode());
if (config.minify) resolve(JavaScriptObfuscator.obfuscate(javascript, {
compact: true,
controlFlowFlattening: true,
controlFlowFlatteningThreshold: 1,
numbersToExpressions: true,
simplify: true,
stringArrayShuffle: true,
splitStrings: true,
stringArrayThreshold: 1
}).getObfuscatedCode());
else resolve(javascript);
});
};
const css = (data) => {
const css = (data, filePath) => {
return new Promise((resolve, reject) => {
const imports = String(data).split('url(')
.map(data => {
@@ -143,37 +154,48 @@ const css = (data) => {
else return undefined;
})
.filter(data => {
if (data) {
try {
new URL(data);
if (data) try {
new URL(data);
return false;
} catch (e) {
if (data.startsWith('/')) return true;
else return false;
}
return false;
} catch (e) {
return true;
} else return false;
})
.filter(data => fs.existsSync(path.join(__dirname, '../templates', data + mime.getExtension(data))));
.map(data => {
// console.log(path.join(filePath.split('/').slice(0, -1).join('/')));
if (data.startsWith('./')) return {
originalFile: data,
newFile: path.join(filePath.split('/').slice(0, -1).join('/'), data)
};
else if (data.startsWith('../')) return {
originalFile: data,
newFile: path.join(filePath.split('/').slice(0, -1).join('/'), data)
};
else return {
originalFile: data,
newFile: data
};
})
.filter(data => fs.existsSync(path.join(__dirname, '../static', data.newFile)));
let css = String(data);
if (config.assetScrambling) for (let i = 0; i < imports.length; i++) {
css = css.replace(imports[i], '/asset/' + TokenManager.generate('asset', 20000, {
asset: path.join(__dirname, '../static', imports[i]),
type: mime.getType(path.join(__dirname, '../static', imports[i]))
}).token);
}
if (config.assetScrambling) for (let i = 0; i < imports.length; i++) css = css.replace(imports[i].originalFile, '/asset/' + TokenManager.generate('asset', 20000, {
asset: path.join(__dirname, '../static', imports[i].newFile),
type: mime.getType(path.join(__dirname, '../static', imports[i].newFile))
}).token);
if (config.minify) resolve(css.replace(/(\r\n|\n|\r)/gm, '').replaceAll(' ', ' '));
else resolve(css);
});
};
const auto = async (data, type) => {
const auto = async (data, type, filePath) => {
if (type === 'text/html') return await html(data);
else if (type === 'text/javascript' || type === 'application/javascript') return await javascript(data);
else if (type === 'text/css') return await css(data);
else if (type === 'text/javascript' || type === 'application/javascript') return await javascript(data, filePath);
else if (type === 'text/css') return await css(data, filePath);
else return data;
};
+3 -1
View File
@@ -15,12 +15,14 @@
<!--el:navbar-->
<!--el:sidebar-->
<div class="content">
<div class="content centered">
<h1>Apps</h1>
<br>
<div class="apps"></div>
</div>
<!--el:footer-->
<script src="/assets/js/main.js" type="module"></script>
<!--el:{{mode === 'dev'}}:development-->
+2 -2
View File
@@ -1,7 +1,7 @@
[
{
"date": "some/time/2023?",
"simpleDescription": "Version 1.2 Release"
"date": "1/1/2024",
"simpleDescription": "2024 Update!!!"
},
{
"date": "11/23/2023",
+89
View File
@@ -0,0 +1,89 @@
footer {
position: relative;
text-align: left;
background-image: url('/assets/img/background.jpeg');
background-attachment: fixed;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
user-select: none;
padding: 4% 5% 2% 5%;
color: #fff;
margin-top: 50px;
text-shadow: 0px 0px 20px rgba(0, 0, 0, 0.616);
}
footer p {
text-shadow: 0px 0px 20px rgba(0, 0, 0, 0.616);
}
footer h1 {
font-family: 'Lato-Black';
color: #fff;
margin: 0px;
margin-bottom: 10px;
}
footer::before {
display: block;
content: '';
height: 270px;
position: fixed;
bottom: 0;
left: 0;
width: 100vw;
z-index: -1;
background: linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, rgba(0, 0, 0, 0.8) 100%);
}
footer .socials {
margin-bottom: 20px;
}
footer .socials i {
margin: 10px;
margin-left: 5px;
margin-right: 5px;
font-size: 20px;
cursor: pointer;
}
footer .socials a {
color: #fff;
}
footer .socials a:hover {
color: #fff;
}
footer .socials a::before {
display: none;
}
footer .socials i:is(:first-child) {
margin-left: 0px;
}
footer .right {
position: absolute;
right: 5%;
text-align: right;
}
footer .right a {
display: block;
margin-top: 20px;
}
footer .title:not(:last-child) {
display: flex;
margin: 0px;
}
footer .title img {
width: 40px;
height: 40px;
margin-left: 10px;
filter: drop-shadow(0px 0px 20px rgba(0, 0, 0, 0.616));
border-radius: 1vh;
}
+15 -5
View File
@@ -1,9 +1,10 @@
@import url('https://site-assets.fontawesome.com/releases/v6.2.0/css/all.css');
@import url('/assets/css/fonts.css');
@import url('/assets/css/themes.css');
@import url('/assets/css/nav.css');
@import url('/assets/css/sidebar.css');
@import url('/assets/css/dropdown.css');
@import url('./fonts.css');
@import url('./themes.css');
@import url('./nav.css');
@import url('./sidebar.css');
@import url('./dropdown.css');
@import url('./footer.css');
* {
font-family: 'Lato';
@@ -21,6 +22,10 @@ body {
background-repeat: no-repeat;
}
.centered {
text-align: center;
}
html {
min-height: 100%;
}
@@ -517,6 +522,11 @@ img.featured:hover {
transition: border 0.5s linear;
}
.content {
margin-left: 100px;
margin-right: 100px;
}
@keyframes beat {
0%,
50%,
+5 -4
View File
@@ -1,5 +1,5 @@
import PolarisError from '/assets/js/error.js';
import { loadWorker } from '/assets/js/wpm.js';
import { loadProxyWorker } from './utils.js';
import PolarisError from './error.js';
const tiltEffectSettings = {
max: 8,
@@ -18,7 +18,8 @@ const load = () => {
document.querySelector('.apps').appendChild(el);
el.addEventListener('click', async () => {
await loadWorker('uv');
await loadProxyWorker('uv');
localStorage.setItem('frameData', JSON.stringify({
type: 'app',
app
@@ -67,4 +68,4 @@ function setTransition(event) {
export default {
load
};
};
+1 -1
View File
@@ -1,4 +1,4 @@
import PolarisError from '/assets/js/error.js';
import PolarisError from './error.js';
const tiltEffectSettings = {
max: 8,
+1 -1
View File
@@ -161,7 +161,7 @@ easterEggs.push({
font-size: 5.5vh;
left: 50%;
-ms-transform: translate(-50%);
transform: translate(-50%);">Hamster</span>`;
transform: translate(-50%);">Hamter</span>`;
menu.appendChild(caller);
const call = document.createElement('div');
+1 -2
View File
@@ -1,6 +1,5 @@
const load = () => {
let frameData = JSON.parse(localStorage.getItem('frameData'));
if (!frameData) location.href = '/';
const iframe = document.querySelector('.frame');
@@ -29,7 +28,7 @@ const load = () => {
document.querySelector('#gameicon').src = "https://cdn3.iconfinder.com/data/icons/feather-5/24/search-512.png";
document.querySelector('#gametitle').textContent = "Proxy";
} else document.querySelector('#gametitle').textContent = 'Failed to load proxy.';
} else location.href = '/';
}
document.querySelector('#fullscreen').addEventListener('click', () => {
const iframe = document.querySelector('.frame');
+38 -56
View File
@@ -1,31 +1,28 @@
import PolarisError from './error.js';
import { workerLoaded, loadWorker } from './wpm.js';
import PolarisError from '/assets/js/error.js';
import { loadProxyWorker } from '/assets/js/utils.js';
const tiltEffectSettings = {
max: 8, // max tilt rotation (degrees (deg))
perspective: 1000, // transform perspective, the lower the more extreme the tilt gets (pixels (px))
scale: 1.05, // transform scale - 2 = 200%, 1.5 = 150%, etc..
speed: 800, // speed (transition-duration) of the enter/exit transition (milliseconds (ms))
easing: 'cubic-bezier(.03,.98,.52,.99)' // easing (transition-timing-function) of the enter/exit transition
max: 8,
perspective: 1000,
scale: 1.05,
speed: 800,
easing: 'cubic-bezier(.03,.98,.52,.99)'
};
let games = []; // store all games
let filteredGames = []; // store filtered games
let games = [];
let filteredGames = [];
const load = () => {
fetch('/assets/JSON/games.json').then(res => res.json()).then(data => {
games = data;
filteredGames = games; // initialize filtered games with all games
filteredGames = games;
renderGames(filteredGames); // render games initially
renderGames(filteredGames);
// Add event listener to search input
const searchInput = document.getElementById('searchInput');
searchInput.addEventListener('input', filterGames);
})
.catch(e => {
new PolarisError('Failed to load games');
});
.catch(e => new PolarisError('Failed to load games'));
};
function filterGames() {
@@ -34,20 +31,14 @@ function filterGames() {
filteredGames = games.filter(game => game.name.toLowerCase().includes(searchTerm));
renderGames(filteredGames); // render filtered games
renderGames(filteredGames);
}
function renderGames(gamesToRender) {
const gamesContainer = document.querySelector('.games');
const popularGamesContainer = document.querySelector('.popular-games');
gamesContainer.innerHTML = ''; // clear previous games
popularGamesContainer.innerHTML = ''; // clear previous popular games
function openGameInNewTab(game) {
const x = window.open('about:blank', '_blank');
const index = game.source;
x.document.write(`<iframe src="${index}" style="position:fixed; top:0; left:0; bottom:0; right:0; width:100%; height:100%; border:none; margin:0; padding:0; overflow:hidden; z-index:999999;"></iframe>`);
}
gamesContainer.innerHTML = '';
popularGamesContainer.innerHTML = '';
gamesToRender.forEach(game => {
const el = document.createElement('div');
@@ -62,20 +53,15 @@ function renderGames(gamesToRender) {
popularGamesContainer.appendChild(popularEl);
popularEl.addEventListener('click', async () => {
if (!workerLoaded) await loadWorker();
const frameData = {
type: 'game',
game
};
if (game.openinnewtab === 'yes') {
window.open(game.source, '_blank');
console.log('Open game in new tab:', frameData);
} else if (game.openinaboutblank === 'yes') {
openGameInNewTab(game);
console.log('Open game in about:blank:', frameData);
} else {
localStorage.setItem('frameData', JSON.stringify(frameData));
location.href = '/view';
await loadProxyWorker('uv');
if (game.openinnewtab === 'yes') window.open(game.source);
else {
localStorage.setItem('frameData', JSON.stringify({
type: 'game',
game
}));
location.href = '/view';
}
});
@@ -85,21 +71,20 @@ function renderGames(gamesToRender) {
}
el.addEventListener('click', async () => {
if (!workerLoaded) await loadWorker();
await loadProxyWorker();
const frameData = {
type: 'game',
game
};
if (game.openinnewtab === 'yes') {
window.open(game.source, '_blank');
console.log('Open game in new tab:', frameData);
} else if (game.openinaboutblank === 'yes') {
openGameInNewTab(game);
console.log('Open game in about:blank:', frameData);
} else {
localStorage.setItem('frameData', JSON.stringify(frameData));
location.href = '/view';
}
window.open(game.source, '_blank');
console.log('Open game in new tab:', frameData);
} else {
localStorage.setItem('frameData', JSON.stringify(frameData));
location.href = '/view';
}
});
el.addEventListener('mouseenter', gameMouseEnter);
@@ -122,10 +107,8 @@ function gameMouseMove(event) {
const mouseY = event.clientY - centerY;
const rotateXUncapped = (+1) * tiltEffectSettings.max * mouseY / (gameHeight / 2);
const rotateYUncapped = (-1) * tiltEffectSettings.max * mouseX / (gameWidth / 2);
const rotateX = rotateXUncapped < -tiltEffectSettings.max ? -tiltEffectSettings.max :
(rotateXUncapped > tiltEffectSettings.max ? tiltEffectSettings.max : rotateXUncapped);
const rotateY = rotateYUncapped < -tiltEffectSettings.max ? -tiltEffectSettings.max :
(rotateYUncapped > tiltEffectSettings.max ? tiltEffectSettings.max : rotateYUncapped);
const rotateX = rotateXUncapped < -tiltEffectSettings.max ? -tiltEffectSettings.max : (rotateXUncapped > tiltEffectSettings.max ? tiltEffectSettings.max : rotateXUncapped);
const rotateY = rotateYUncapped < -tiltEffectSettings.max ? -tiltEffectSettings.max : (rotateYUncapped > tiltEffectSettings.max ? tiltEffectSettings.max : rotateYUncapped);
game.style.transform = `perspective(${tiltEffectSettings.perspective}px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) scale3d(${tiltEffectSettings.scale}, ${tiltEffectSettings.scale}, ${tiltEffectSettings.scale})`;
}
@@ -139,11 +122,10 @@ function setTransition(event) {
const game = event.currentTarget;
clearTimeout(game.transitionTimeoutId);
game.style.transition = `transform ${tiltEffectSettings.speed}ms ${tiltEffectSettings.easing}`;
game.transitionTimeoutId = setTimeout(() => {
game.style.transition = '';
}, tiltEffectSettings.speed);
game.transitionTimeoutId = setTimeout(() => game.style.transition = '', tiltEffectSettings.speed);
}
export default {
load
};
};
+39 -51
View File
@@ -1,15 +1,13 @@
// Don't touch
import { load } from './settings.js';
import Games from './games.js';
import Apps from './apps.js';
import loadEasterEggs from './eastereggs.js';
import PolarisError from './error.js';
import Settings from './settings.js';
import Search from './search.js';
import Cheats from './cheats.js';
import Games from './games.js';
import Frame from './frame.js';
import PolarisError from './error.js';
import Apps from './apps.js';
const Settings = {
load: load
};
loadEasterEggs();
onbeforeunload = (e) => {
if (localStorage.getItem('prevent_close') === 'true') {
@@ -25,62 +23,52 @@ window.onhashchange = () => {
else document.querySelector('.sidebar').classList.remove('active');
};
if (window.self === window.top) {
setTimeout(async () => {
Settings.load();
if (window.self === window.top) setTimeout(async () => {
Settings.load();
if (location.pathname === '/games') Games.load();
if (location.pathname === '/apps') Apps.load();
if (location.pathname === '/search') Search.load();
if (location.pathname === '/cheats') Cheats.load();
if (location.pathname === '/view') Frame.load();
}, 500);
}
if (location.pathname === '/games') Games.load();
if (location.pathname === '/apps') Apps.load();
if (location.pathname === '/search') Search.load();
if (location.pathname === '/cheats') Cheats.load();
if (location.pathname === '/view') Frame.load();
}, 500);
if (location.pathname === '/') {
fetch('/assets/JSON/games.json').then(res => res.json()).then(games => {
const gameName = 'Tiny Fishing';
const game = games.filter(g => g.name === gameName)[0];
document.querySelector('.featuredimg').addEventListener('click', () => {
document.querySelector('.featured').addEventListener('click', () => {
localStorage.setItem('frameData', JSON.stringify({
type: 'game',
game
}));
location.href = '/view';
});
document.querySelector('.featuredimg').src = '/assets/img/wide/tinyfishing.png';
document.querySelector('.featured').src = '/assets/img/wide/tinyfishing.png';
}).catch(e => new PolarisError('Failed to load featured game.'));
fetch('/assets/JSON/changelog.json').then(res => res.json()).then(changelog => changelog.forEach(change => {
const date = document.createElement('p');
date.textContent = change.date;
date.classList = 'small';
document.querySelector('#changelog').appendChild(date);
const descwrap = document.createElement('p');
fetch('/assets/JSON/changelog.json').then(res => res.json()).then(changelog => changelog.forEach(change => {
const date = document.createElement('p');
date.textContent = change.date;
date.classList = 'small';
document.querySelector('#changelog').appendChild(date);
const descwrap = document.createElement('p');
const description = document.createElement('i');
description.textContent = change.simpleDescription;
description.classList = 'small';
document.querySelector('#changelog').appendChild(description);
}));
/*
var items = ['the start', 'What are you doing here?', '"School"', 'I dont get paid enough','What Up Son?','help','i like bagle','3.14159265359','Who thought this was a good idea?','Stage 4','i have a concerning lump on my back','Bean was here','Your Mother','Pacer Test','Why did he leave','by the way...','Kilroy was here','Kilroy is here','look behind you','West Virginia','theres a reason','Country road','Thats a wrap','Pretty','No','Yes','leave me','What square?','uhhh','Plutocracy','Practically Free*','capitalize this','Place Holder','Try me','fine','Why are we doing this again?','half eaten saltine crackers are underated','Javascript > Java','L + Ratio','Cope','I Love Refrigerators','That Happened.','Pedicure','(insert message here)','terminal','💀💀💀','finnish','who writes these?','reference','I am going to peel the skin off your face (:','bye','no','the fact is','run','uh what','hello world','Positively awful','tax fraud','comatose state','Not me','my second job is a discord mod','kids bop','Is it just me or','Hello people','74% Incomplete','wake up','Monster Energy','ew','The amount of pain I am in right now is unimaginable','chicken','men','What?','Your opinion is invalid','gay pride','Im going','4skin','/0','Who said that?','No Fair.','Famous... Enough','Parent Approved!','Teacher Approved!','Treason','Just do it already!','You\'re Fired','Not worth it','was there a reason?','the egg came first','patriotism','Family Friendly','Do you ever feel like a plastic bag Drifting through the windWanting to start again? Do you ever feel, feel so paper thin Like a house of cards One blow from caving in?','Why?','discord is in the first o','Shane Dawson likes cats','who stole this','unblock linux','darn you','gushers','yummy','charles loves you','mekhi loves anime', 'pls dont type smurf :)'];
function getRandomFact() {
var randomIndex = Math.floor(Math.random() * items.length);
return items[randomIndex];
}
// When the page loads, set the innerHTML of elements with class 'blue' to a random item
window.addEventListener('load', function() {
var blue = document.getElementsByClassName('blue');
for (var i = 0; i < blue.length; i++) {
blue[i].innerHTML = getRandomFact();
}
});
*/
description.textContent = change.simpleDescription;
description.classList = 'small';
document.querySelector('#changelog').appendChild(description);
}));
}
const Polaris = { Settings, Games, Apps, Frame, PolarisError };
export default Polaris;
if (window.scrollY !== 0) document.querySelector('.navbar').classList.add('scrolling');
else document.querySelector('.navbar').classList.remove('scrolling');
window.onscroll = () => {
if (window.scrollY !== 0) document.querySelector('.navbar').classList.add('scrolling');
else document.querySelector('.navbar').classList.remove('scrolling');
}
export default { Settings, Games, Apps, Frame, PolarisError };
+131
View File
@@ -0,0 +1,131 @@
import PolarisError from '/assets/js/error.js';
import { loadProxyWorker } from '/assets/js/utils.js';
const tiltEffectSettings = {
max: 8,
perspective: 1000,
scale: 1.05,
speed: 800,
easing: 'cubic-bezier(.03,.98,.52,.99)'
};
let games = [];
let filteredGames = [];
const load = () => {
fetch('/assets/JSON/games.json').then(res => res.json()).then(data => {
games = data;
filteredGames = games;
renderGames(filteredGames);
const searchInput = document.getElementById('searchInput');
searchInput.addEventListener('input', filterGames);
})
.catch(e => new PolarisError('Failed to load games'));
};
function filterGames() {
const searchInput = document.getElementById('searchInput');
const searchTerm = searchInput.value.toLowerCase();
filteredGames = games.filter(game => game.name.toLowerCase().includes(searchTerm));
renderGames(filteredGames);
}
function renderGames(gamesToRender) {
const gamesContainer = document.querySelector('.games');
const popularGamesContainer = document.querySelector('.popular-games');
gamesContainer.innerHTML = '';
popularGamesContainer.innerHTML = '';
gamesToRender.forEach(game => {
const el = document.createElement('div');
el.classList = 'game';
el.innerHTML = `<img loading='lazy' src='${game.image}'><h3>${game.name}</h3>`;
gamesContainer.appendChild(el);
if (game.popular === 'yes') {
const popularEl = document.createElement('div');
popularEl.classList = 'game';
popularEl.innerHTML = `<img loading='lazy' src='${game.image}'><h3>${game.name}</h3>`;
popularGamesContainer.appendChild(popularEl);
popularEl.addEventListener('click', async () => {
await loadProxyWorker('uv');
if (game.openinnewtab === 'yes') window.open(game.source);
else {
localStorage.setItem('frameData', JSON.stringify({
type: 'game',
game
}));
location.href = '/view';
}
});
popularEl.addEventListener('mouseenter', gameMouseEnter);
popularEl.addEventListener('mousemove', gameMouseMove);
popularEl.addEventListener('mouseleave', gameMouseLeave);
}
el.addEventListener('click', async () => {
await loadProxyWorker();
const frameData = {
type: 'game',
game
};
if (game.openinnewtab === 'yes') {
window.open(game.source, '_blank');
console.log('Open game in new tab:', frameData);
} else {
localStorage.setItem('frameData', JSON.stringify(frameData));
location.href = '/view';
}
});
el.addEventListener('mouseenter', gameMouseEnter);
el.addEventListener('mousemove', gameMouseMove);
el.addEventListener('mouseleave', gameMouseLeave);
});
}
function gameMouseEnter(event) {
setTransition(event);
}
function gameMouseMove(event) {
const game = event.currentTarget;
const gameWidth = game.offsetWidth;
const gameHeight = game.offsetHeight;
const centerX = game.offsetLeft + gameWidth / 2;
const centerY = game.offsetTop + gameHeight / 2;
const mouseX = event.clientX - centerX;
const mouseY = event.clientY - centerY;
const rotateXUncapped = (+1) * tiltEffectSettings.max * mouseY / (gameHeight / 2);
const rotateYUncapped = (-1) * tiltEffectSettings.max * mouseX / (gameWidth / 2);
const rotateX = rotateXUncapped < -tiltEffectSettings.max ? -tiltEffectSettings.max : (rotateXUncapped > tiltEffectSettings.max ? tiltEffectSettings.max : rotateXUncapped);
const rotateY = rotateYUncapped < -tiltEffectSettings.max ? -tiltEffectSettings.max : (rotateYUncapped > tiltEffectSettings.max ? tiltEffectSettings.max : rotateYUncapped);
game.style.transform = `perspective(${tiltEffectSettings.perspective}px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) scale3d(${tiltEffectSettings.scale}, ${tiltEffectSettings.scale}, ${tiltEffectSettings.scale})`;
}
function gameMouseLeave(event) {
event.currentTarget.style.transform = `perspective(${tiltEffectSettings.perspective}px) rotateX(0deg) rotateY(0deg) scale3d(1, 1, 1)`;
setTransition(event);
}
function setTransition(event) {
const game = event.currentTarget;
clearTimeout(game.transitionTimeoutId);
game.style.transition = `transform ${tiltEffectSettings.speed}ms ${tiltEffectSettings.easing}`;
game.transitionTimeoutId = setTimeout(() => game.style.transition = '', tiltEffectSettings.speed);
}
export default {
load
};
+4 -3
View File
@@ -1,5 +1,5 @@
import PolarisError from '/assets/js/error.js';
import { loadWorker } from '/assets/js/wpm.js';
import PolarisError from './error.js';
import { loadProxyWorker } from './utils.js';
const load = () => {
const xor = {
@@ -20,7 +20,7 @@ const load = () => {
e.preventDefault();
if (typeof navigator.serviceWorker === 'undefined') new PolarisError('Failed to load Proxy');
await loadWorker('uv');
await loadProxyWorker('uv');
const url = /^(http(s)?:\/\/)?([\w-]+\.)+[\w]{2,}(\/.*)?$/.test(query.value) ? ((!query.value.startsWith('http://') && !query.value.startsWith('https://')) ? 'https://' + query.value : query.value) : 'https://www.google.com/search?q=' + encodeURIComponent(query.value);
@@ -28,6 +28,7 @@ const load = () => {
type: 'proxy',
source: `/uv/service/${xor.encode(url)}`
}));
location.href = '/view';
});
}
+3 -3
View File
@@ -1,5 +1,5 @@
import PolarisError from '/assets/js/error.js';
import Theme from '/assets/js/themes.js';
import PolarisError from './error.js';
import Theme from './themes.js';
const isScrollable = (element) => element.scrollWidth > element.clientWidth || element.scrollHeight > element.clientHeight;
@@ -205,4 +205,4 @@ const load = () => {
new Settings();
};
export { load, Settings };
export default { load, Settings };
+19 -32
View File
@@ -1,47 +1,34 @@
const set = (name, value) => {
if (!localStorage.getItem('settings')) {
localStorage.setItem('settings', JSON.stringify({}));
} else {
try {
JSON.parse(localStorage.getItem('settings'));
} catch (e) {
localStorage.setItem('settings', JSON.stringify({}));
}
}
import { storage } from './utils.js';
const settings = JSON.parse(localStorage.getItem('settings'));
settings[name] = value;
localStorage.setItem('settings', JSON.stringify(settings));
};
const get = (name) => {
if (!localStorage.getItem('settings')) {
localStorage.setItem('settings', JSON.stringify({}));
} else {
try {
JSON.parse(localStorage.getItem('settings'));
} catch (e) {
localStorage.setItem('settings', JSON.stringify({}));
}
}
const settings = JSON.parse(localStorage.getItem('settings'));
return settings[name];
}
const settingsStorage = storage('settings');
class Theme {
constructor() {
this.theme = get('theme');
this.theme = settingsStorage.get('theme');
if (this.theme) this.set(this.theme);
else this.set('system-default');
}
/**
* Set the theme of the page
* @param {string} theme The name of the theme
* @param {boolean} save Whether or not the theme should be saved
*/
set = (theme, save) => {
document.body.setAttribute('data-theme', theme);
this.theme = theme;
if (save !== false) set('theme', theme);
}
if (save !== false) settingsStorage.set('theme', theme);
};
/**
* Get the current theme
* @returns {string}
*/
get = () => {
return document.body.getAttribute('data-theme');
};
}
export default new Theme();
+72
View File
@@ -0,0 +1,72 @@
/**
* The storage interface for polaris
* @param {string} containerName
*/
const storage = (containerName) => {
return {
/**
* Get a value from the storage container
* @param {string} name The name of the value
* @returns {string}
*/
get: (name) => {
if (!localStorage.getItem(containerName)) localStorage.setItem(containerName, JSON.stringify({}));
else {
try {
JSON.parse(localStorage.getItem(containerName));
} catch (e) {
localStorage.setItem(containerName, JSON.stringify({}));
}
}
const container = JSON.parse(localStorage.getItem(containerName));
return container[name];
},
/**
* Set a value from a storage container
* @param {string} name The name of the value
* @param {string | object} value The value to be set
*/
set: (name, value) => {
if (!localStorage.getItem(containerName)) localStorage.setItem(containerName, JSON.stringify({}));
else {
try {
JSON.parse(localStorage.getItem(containerName));
} catch (e) {
localStorage.setItem(containerName, JSON.stringify({}));
}
}
const container = JSON.parse(localStorage.getItem(containerName));
container[name] = value;
localStorage.setItem(containerName, JSON.stringify(container));
}
};
};
/**
* Register a proxy service worker
* @param {'uv' | 'dynamic'} proxy
*/
const loadProxyWorker = async (proxy) => await navigator.serviceWorker.register(`/${proxy}/sw.js`, {
scope: `/${proxy}/service/`
});
/**
* Load the page javascript
*/
const loadPageScript = () => {
if (location.href) {
}
};
export default {
storage,
loadProxyWorker
};
export {
storage,
loadProxyWorker
};
-7
View File
@@ -1,7 +0,0 @@
const loadWorker = async (proxy) => await navigator.serviceWorker.register(`/${proxy}/sw.js`, {
scope: `/${proxy}/service/`,
});
export {
loadWorker
};
+3 -1
View File
@@ -11,7 +11,7 @@
<title>Cheats | Polaris</title>
</head>
<body>
<body class="centered">
<!--el:navbar-->
<!--el:sidebar-->
@@ -21,6 +21,8 @@
<div class="games"></div>
</div>
<!--el:footer-->
<script src="/assets/js/main.js" type="module"></script>
<!--el:{{mode === 'dev'}}:development-->
+2 -10
View File
@@ -15,7 +15,7 @@
<!--el:navbar-->
<!--el:sidebar-->
<div class="content">
<div class="content centered">
<h1 style="font-size: 6vh;">Games</h1>
<h1 style="font-size: 4vh;" class="gamesectionheader">Popular</h1>
@@ -27,18 +27,10 @@
<input type="text" id="searchInput" class="settings-input" placeholder="Search Games...">
<br>
<div style="padding-bottom: 2vh;">
</div>
<br>
<div class="games">
</div>
<div style="margin-top: 5vh;">
</div>
<!--el:footer-->
<script src="/assets/js/main.js" type="module"></script>
+1
View File
@@ -36,6 +36,7 @@
-
<a href="/tos" class="link">Terms of Service</a>
</p>
<hr>
<h2>Changelog</h2>
+2 -2
View File
@@ -1,3 +1,3 @@
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9661054437111080" crossorigin="anonymous"></script>
<script data-cfasync="false">window.nitroAds = window.nitroAds || { createAd: function () { return new Promise(e => { window.nitroAds.queue.push(["createAd", arguments, e]) }) }, addUserToken: function () { window.nitroAds.queue.push(["addUserToken", arguments]) }, queue: [] };</script>
<script data-cfasync="false" async src="https://s.nitropay.com/ads-1751.js"></script>
<script data-cfasync="false" async src="https://s.nitropay.com/ads-1751.js"></script>
<script data-cfasync="false">window.nitroAds = window.nitroAds || { createAd: function () { return new Promise(e => { window.nitroAds.queue.push(["createAd", arguments, e]) }) }, addUserToken: function () { window.nitroAds.queue.push(["addUserToken", arguments]) }, queue: [] };</script>
+31
View File
@@ -0,0 +1,31 @@
<footer>
<div class="title">
<h1>Polaris</h1>
<img src="/assets/img/logo.png" title="Polaris Logo">
</div>
<div class="socials">
<a href="https://discord.gg/RXBbxQ4wuJ" target="_blank" rel="noopener noreferrer" title="EmberNetwork Discord">
<i class="fa-brands fa-discord"></i>
</a>
<a href="https://github.com/Skoolgq/Polaris" target="_blank" rel="noopener noreferrer" title="Our Github">
<i class="fa-brands fa-github"></i>
</a>
<a href="mailto:support@polarislearning.org" target="_blank" title="Contact Email">
<i class="fa-solid fa-envelope"></i>
</a>
</div>
<div class="right">
<a href="https://forms.gle/9knPLmyAua5Z3wZv5">Suggest a Game</a>
<a href="/privacy">Privace Policy</a>
<a href="/TOS">Terms of Service</a>
</div>
<p>©2022-2023 Skool. All rights reserved.</p>
</footer>