add web challenge

This commit is contained in:
2021-12-02 00:48:04 +01:00
parent 632fdd5b53
commit c0feed3487
38 changed files with 3199 additions and 0 deletions

View File

@@ -0,0 +1,41 @@
const puppeteer = require('puppeteer');
const browser_options = {
headless: true,
args: [
'--no-sandbox',
'--disable-background-networking',
'--disable-default-apps',
'--disable-extensions',
'--disable-gpu',
'--disable-sync',
'--disable-translate',
'--hide-scrollbars',
'--metrics-recording-only',
'--mute-audio',
'--no-first-run',
'--safebrowsing-disable-auto-update',
'--js-flags=--noexpose_wasm,--jitless'
]
};
const cookies = [{
'name': 'flag',
'value': 'HTB{f4k3_fl4g_f0r_t3st1ng}'
}];
const readQueries = async (db) => {
const browser = await puppeteer.launch(browser_options);
let context = await browser.createIncognitoBrowserContext();
let page = await context.newPage();
await page.goto('http://127.0.0.1:1337/');
await page.setCookie(...cookies);
await page.goto('http://127.0.0.1:1337/queries', {
waitUntil: 'networkidle2'
});
await browser.close();
await db.migrate();
};
module.exports = { readQueries };

View File

@@ -0,0 +1,48 @@
const sqlite = require('sqlite-async');
class Database {
constructor(db_file) {
this.db_file = db_file;
this.db = undefined;
}
async connect() {
this.db = await sqlite.open(this.db_file);
}
async migrate() {
return this.db.exec(`
DROP TABLE IF EXISTS queries;
CREATE TABLE IF NOT EXISTS queries (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
query VARCHAR(500) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
`);
}
async addQuery(query) {
return new Promise(async (resolve, reject) => {
try {
let stmt = await this.db.prepare('INSERT INTO queries (query) VALUES (?)');
resolve(await stmt.run(query));
} catch(e) {
reject(e);
}
});
}
async getQueries() {
return new Promise(async (resolve, reject) => {
try {
let stmt = await this.db.prepare('SELECT * FROM queries');
resolve(await stmt.all());
} catch(e) {
reject(e);
}
});
}
}
module.exports = Database;

View File

@@ -0,0 +1,27 @@
const express = require('express');
const app = express();
const path = require('path');
const routes = require('./routes');
const Database = require('./database');
const db = new Database('toy_workshop.db');
app.use(express.json());
app.set("view engine", "hbs");
app.set('views', './views');
app.use('/static', express.static(path.resolve('static')));
app.use(routes(db));
app.all('*', (req, res) => {
return res.status(404).send({
message: '404 page not found'
});
});
(async () => {
await db.connect();
await db.migrate();
app.listen(1337, '0.0.0.0', () => console.log('Listening on port 1337'));
})();

View File

@@ -0,0 +1,25 @@
{
"name": "web_toy_workshop",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"keywords": [],
"authors": [
"rayhan0x01",
"Makelaris",
"Makelaris jr"
],
"license": "ISC",
"dependencies": {
"express": "^4.17.1",
"sqlite-async": "^1.1.1",
"puppeteer": "^11.0.0",
"hbs": "^4.1.2"
},
"devDependencies": {
"nodemon": "^1.19.1"
}
}

View File

@@ -0,0 +1,39 @@
const express = require('express');
const router = express.Router();
const bot = require('../bot');
let db;
const response = data => ({ message: data });
router.get('/', (req, res) => {
return res.render('index');
});
router.post('/api/submit', async (req, res) => {
const { query } = req.body;
if(query){
return db.addQuery(query)
.then(() => {
bot.readQueries(db);
res.send(response('Your message is delivered successfully!'));
});
}
return res.status(403).send(response('Please write your query first!'));
});
router.get('/queries', async (req, res, next) => {
if(req.ip != '127.0.0.1') return res.redirect('/');
return db.getQueries()
.then(queries => {
res.render('queries', { queries });
})
.catch(() => res.status(500).send(response('Something went wrong!')));
});
module.exports = database => {
db = database;
return router;
};

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,189 @@
/* @import url('https://fonts.googleapis.com/css2?family=VT323&display=swap'); */
@import url('https://fonts.googleapis.com/css2?family=Caveat&display=swap');
body {
font-family: 'Caveat', cursive;
font-size: 18pt;
color: #fff;
background-color: #c09277;
height: 100%;
overflow: hidden;
min-height: 800px;
max-height: 800px;
}
p {
text-align: center;
margin: 0 auto;
}
.main-logo {
display: flex;
min-width: 150px;
width: 150px;
margin: 0 auto;
margin-top: 2rem;
margin-bottom: 20px;
}
.login-form {
display: flex;
min-width: 400px;
width: 400px;
margin: 0 auto;
margin-top: 20px;
flex-direction: column;
}
.login-form>input {
margin-bottom: 1.5rem;
}
.submit-btns {
width: 100%;
text-align: center;
}
.submit-btns>button {
width: 45%;
}
.submit-btn.is-primary {
background-color: #ca8055 !important;
border-color: #f4b798 !important;
}
.submit-btn.is-primary::after {
box-shadow:inset -4px -4px #a86136 !important;
}
.submit-btn.is-primary:hover::after {
box-shadow:inset -6px -6px #a86136 !important;
}
.submit-btn.is-primary:focus {
box-shadow:0 0 0 3px transparent !important;
}
/* query-msg */
#resp-msg {
display: none;
margin-top: 1.5rem;
}
.alert {
position: relative;
padding: .50rem 1.25rem;
margin-bottom: 1rem;
border: 1px solid transparent;
border-radius: .25rem;
}
.alert-success {
color: #155724;
background-color: #d4edda;
border-color: #c3e6cb;
}
.alert-danger {
color: #721c24;
background-color: #f8d7da;
border-color: #f5c6cb;
}
.alert-info {
color: #0c5460;
background-color: #d1ecf1;
border-color: #bee5eb;
}
.login-frame {
position: relative;
background-color: #a27256;
min-height: 380px;
width: 480px;
margin: 0 auto;
padding-top: 10px;
margin-top: 40px;
margin-bottom: 40px;
}
.login-frame::before{
content: '';
position: absolute;
bottom: -40px;
left: 0;
width: 100%;
height: 40px;
background: #925f41;
}
.login-frame::after{
content: '';
position: absolute;
top: -40px;
left: 0;
width: 100%;
height: 40px;
background: #925f41;
}
.pb-3 {
display: block;
padding-bottom: 30px;
}
#fireplace {
position: absolute;
bottom: -5px;
left: 5%;
height: 250px;
z-index: -1;
}
@media (max-height: 800px){
body {
overflow: scroll;
}
#fireplace {
display: none;
}
}
.dash-frame {
position: relative;
background-color: #a27256;
width: 480px;
margin: 0 auto;
padding-top: 10px;
margin-top: 40px;
margin-bottom: 40px;
}
.dash-frame::before{
content: '';
position: absolute;
bottom: -40px;
left: 0;
width: 100%;
height: 40px;
background: #925f41;
}
.dash-frame::after{
content: '';
position: absolute;
top: -40px;
left: 0;
width: 100%;
height: 40px;
background: #925f41;
}
@media (max-height: 800px){
body {
overflow: scroll;
}
#fireplace {
display: block;
}
}
@media (max-height: 660px){
body {
overflow: scroll;
}
#fireplace {
display: none;
}
}

View File

@@ -0,0 +1,706 @@
@import url('https://fonts.googleapis.com/css2?family=Mountains+of+Christmas&display=swap');
body {
background: #111;
background-size: 100%;
height: 100%;
width:100%;
overflow: scroll;
margin: 0;
min-width: 1300px !important;
font-family: 'Mountains of Christmas', cursive;
font-size: 28px;
}
/***************************
The DIV for the SVG wall. As I want the snow to show through the windows, I need to place this layer with a higher z-index then Miss Tiff's snow ---> https://codepen.io/tmrDevelops/pen/PPgjwz
***************************/
#Workshop_Back {
position: absolute;
width: 100%;
height: 779px;
margin: 0;
z-index: 200;
min-width: 1300px;
}
#Workshop_Animations {
position: absolute;
width: 100%;
height: 712px;
margin: 0;
z-index: 3000;
}
#Candy_Gears {position:absolute;width:100%;height:100%;margin:0;z-index:999999999999;}
/***************************
Styles for the SVG Wall. Created the wall in illustrator and then knocked out the window panes so the snow (and other festive surprises) would show through.
***************************/
#Workshop_Wall {
position: absolute;
width: 100%;
height: 100%;
margin: 0;
z-index: 1000;
}
.Workshop_Wall_0{fill:#c09277;}
.Workshop_Wall_1{fill:#8C5A3C;}
.Workshop_Wall_2{fill:#60462F;}
.Workshop_Wall_3{fill:#B96636;}
.Workshop_Wall_4{fill:#D3814D;}
.Workshop_Wall_5{fill:#B0581F;}
.Workshop_Wall_6{fill:#DE1516;}
.Workshop_Wall_7{fill:#F4F4F4;}
.Workshop_Wall_8{fill:#BD0302;}
.Workshop_Wall_9{fill:#C1652F;}
.Workshop_Wall_10{fill:#C66225;}
.Workshop_Wall_11{fill:#1F01FB;}
.Workshop_Wall_12{fill:#AD7964;}
.Workshop_Wall_13{fill:#9E99BC;}
.Workshop_Wall_14{fill:#8587AC;}
.Workshop_Wall_15{fill:#A58175;}
/***************************
Snow. Positioned layer using a low z-index in the very back.
***************************/
#tiffany_snow {
position: fixed;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
z-index: 100;
pointer-events: none;
}
#Front_Elves {position:absolute;width:100%;height:100%;margin:0;z-index:9000;}
.elves_front0{fill:#815330;}
.elves_front1{fill:#654227;}
.elves_front2{fill:#F9FAF8;}
.elves_front3{fill:#757578;}
.elves_front4{fill:#6A8F27;}
.elves_front5{fill:#DA4937;}
.elves_front6{fill:#924493;}
.elves_front7{fill:#4BB882;}
.elves_front8{fill:#06AAE9;}
.elves_front9{fill:#FCDD03;}
.elves_front10{fill:#E91D25;}
.elves_front11{fill:#CB1A22;}
.elves_front12{fill:#5B5A5C;}
.elves_front13{fill:#3CB34B;}
.elves_front14{fill:#E4C184;}
/***************************
Santa Magic Machine
***************************/
#Toy-A-Matic {position:absolute;width:100%;height:621px;margin:0;z-index:6000}
#Santa_Factory {
width: 100%;
height: 100%;
position: absolute;
margin: 0 0 0 0;
overflow: hidden;
background-color: #815330;
}
.Santa_Magical_Toy_Machine {
position: absolute;
width: 100%;
margin-top: 0px;
height: 578px;
z-index: 2000;
}
.Santa_Magical_Toy_Machine:active .trash-in, .Santa_Magical_Toy_Machine:active .toy-out, .Santa_Magical_Toy_Machine:active .conveyor:before {
animation-play-state: paused;
}
.factory {
overflow: hidden;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 9000;
}
.converter {
width: 20vw;
min-width: 200px;
height: 100%;
animation: 3s magic_Border infinite;
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
}
.converter .attention {
width: 18vw;
opacity: 0.5;
height: 100%;
position: absolute;
bottom: 0;
left: 0;
z-index: 0;
animation: attention 10s infinite ease;
}
/***************************
Recycle Presents. The CSS swap is triggered by the JS. The background of the divs are just swapped out to create this incredible holiday illusion.
***************************/
.ChristmasPresents {
display: none;
}
.ChristmasPresents.active {
display: block;
}
.ChristmasPresents:nth-child(1) .trash-in{
background-image: url(/static/images/bin2.png)
}
.ChristmasPresents:nth-child(1) .toy-out {
background-image: url(/static/images/trainset.png)
}
.ChristmasPresents:nth-child(2) .trash-in{
background-image: url(/static/images/bin2.png)
}
.ChristmasPresents:nth-child(2) .toy-out {
background-image: url(/static/images/bearset.png)
}
.ChristmasPresents:nth-child(3) .trash-in{
background-image: url(/static/images/bin2.png)
}
.ChristmasPresents:nth-child(3) .toy-out {
background-image: url(/static/images/gameset.png)
}
.ChristmasPresents:nth-child(4) .trash-in{
background-image: url(/static/images/bin2.png)
}
.ChristmasPresents:nth-child(4) .toy-out {
background-image: url(/static/images/ballset.png)
}
.ChristmasPresents:nth-child(5) .trash-in{
background-image: url(/static/images/bin2.png)
}
.ChristmasPresents:nth-child(5) .toy-out {
background-image: url(/static/images/bearset.png)
}
.ChristmasPresents .item {
margin-left: -20vw;
width: 200px;
max-width: 200px;
height: 50%;
max-height: 300px;
background-repeat: no-repeat;
background-position: bottom left;
background-size: contain;
}
.ChristmasPresents .trash-in{
position: absolute;
left: 0;
bottom: 18px;
animation: input-slide 10s infinite linear;
}
.ChristmasPresents .toy-out {
position: absolute;
bottom: 18px;
animation: output-slide 10s infinite linear;
}
.conveyor {
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 12px;
width: 100%;
min-width: 1300px;
background: #3e3e66;
}
.conveyor:before {
content: '';
display: block;
position: absolute;
bottom: 100%;
right: 0;
width: 430vw;
background: repeating-linear-gradient(90deg, #3e3e66 0, #3e3e66 20px, transparent 20px, transparent 30px);
height: 6px;
animation: conveyor 10s infinite linear;
}
@keyframes input-slide {
0% {
visibility: visible;
}
50%, 100% {
visibility: hidden;
}
100% {
transform: translateX(130vw);
}
}
@keyframes output-slide {
0%, 49% {
visibility: hidden;
}
50% {
visibility: visible;
}
100% {
transform: translateX(130vw);
}
}
@keyframes conveyor {
100% {
transform: translateX(130vw);
}
}
@keyframes attention {
0%, 48%, 52%, 100% {
opacity: 0;
}
50% {
opacity: 1;
transform: scale(1.2);
}
}
#Left_Cane {
transform: translateY(5px);
animation: leftcane 3s ease infinite;
animation-delay: 1.5s;
}
@keyframes rightcane {
50% {
transform: translateY(-30px);
}
}
#Right_Cane {
transform: translateY(10px);
animation: rightcane 3s ease infinite;
}
@keyframes leftcane {
50% {
transform: translateY(-20px);
}
}
.Candy_Cane_Magic {
position: absolute;
width:100%;
height:100%;
margin:0;
overflow:hidden;
background:rgba(0,116,38,0.5);
animation: 3s Magic_Border infinite;
}
.magic_stripe {
height: 100%;
width: 3%;
max-width:15px;
position: absolute;
-webkit-animation: toy_magic 4s infinite alternate;
animation: toy_magic 4s infinite alternate;
}
@-webkit-keyframes toy_magic {
100% {
top: 100%;
}
}
@keyframes toy_magic {
100% {
top: 100%;
}
}
.magic_stripe:nth-child(1) {
left: 41%;
background: rgba(255, 255, 255, 0.8);
top: -100%;
-webkit-animation-delay: 0.1s;
animation-delay: 0.1s;
}
.magic_stripe:nth-child(2) {
left: 23%;
background: rgba(254,0,4,0.8);
top: -100%;
-webkit-animation-delay: 0.2s;
animation-delay: 0.2s;
}
.magic_stripe:nth-child(3) {
left: 34%;
background: rgba(255, 255, 255, 0.8);
top: -100%;
-webkit-animation-delay: 0.3s;
animation-delay: 0.3s;
}
.magic_stripe:nth-child(4) {
left: 39%;
background: rgba(254,0,4,0.8);
top: -100%;
-webkit-animation-delay: 0.4s;
animation-delay: 0.4s;
}
.magic_stripe:nth-child(5) {
left: 51%;
background: rgba(255, 255, 255, 0.8);
top: -100%;
-webkit-animation-delay: 0.5s;
animation-delay: 0.5s;
}
.magic_stripe:nth-child(6) {
left: 42%;
background: rgba(254,0,4,0.8);
top: -100%;
-webkit-animation-delay: 0.6s;
animation-delay: 0.6s;
}
.magic_stripe:nth-child(7) {
left: 93%;
background: rgba(255, 255, 255, 0.8);
top: -100%;
-webkit-animation-delay: 0.7s;
animation-delay: 0.7s;
}
.magic_stripe:nth-child(8) {
left: 20%;
background: rgba(254,0,4,0.8);
top: -100%;
-webkit-animation-delay: 0.8s;
animation-delay: 0.8s;
}
.magic_stripe:nth-child(9) {
left: 23%;
background: rgba(255, 255, 255, 0.8);
top: -100%;
-webkit-animation-delay: 0.9s;
animation-delay: 0.9s;
}
.magic_stripe:nth-child(10) {
left: 50%;
background: rgba(254,0,4,0.8);
top: -100%;
-webkit-animation-delay: 1s;
animation-delay: 1s;
}
.magic_stripe:nth-child(11) {
left: 75%;
background: rgba(255, 255, 255, 0.8);
top: -100%;
-webkit-animation-delay: 1.1s;
animation-delay: 1.1s;
}
.magic_stripe:nth-child(12) {
left: 37%;
background: rgba(254,0,4,0.8);
top: -100%;
-webkit-animation-delay: 1.2s;
animation-delay: 1.2s;
}
.magic_stripe:nth-child(13) {
left: 40%;
background: rgba(255, 255, 255, 0.8);
top: -100%;
-webkit-animation-delay: 1.3s;
animation-delay: 1.3s;
}
.magic_stripe:nth-child(14) {
left: 90%;
background: rgba(254,0,4,0.8);
top: -100%;
-webkit-animation-delay: 1.4s;
animation-delay: 1.4s;
}
.magic_stripe:nth-child(15) {
left: 92%;
background: rgba(254,0,4,0.8);
top: -100%;
-webkit-animation-delay: 1.5s;
animation-delay: 1.5s;
}
.magic_stripe:nth-child(16) {
left: 80%;
background: rgba(255, 255, 255, 0.8);
top: -100%;
-webkit-animation-delay: 1.6s;
animation-delay: 1.6s;
}
.magic_stripe:nth-child(17) {
left: 5%;
background: rgba(254,0,4,0.8);
top: -100%;
-webkit-animation-delay: 1.7s;
animation-delay: 1.7s;
}
.magic_stripe:nth-child(18) {
left: 79%;
background: rgba(255, 255, 255, 0.8);
top: -100%;
-webkit-animation-delay: 1.8s;
animation-delay: 1.8s;
}
.magic_stripe:nth-child(19) {
left: 20%;
background: rgba(254,0,4,0.8);
top: -100%;
-webkit-animation-delay: 1.9s;
animation-delay: 1.9s;
}
.magic_stripe:nth-child(20) {
left: 11%;
background: rgba(255, 255, 255, 0.8);
top: -100%;
-webkit-animation-delay: 2s;
animation-delay: 2s;
}
.magic_stripe:nth-child(21) {
left: 14%;
background: rgba(254,0,4,0.8);
top: -100%;
-webkit-animation-delay: 2.1s;
animation-delay: 2.1s;
}
.magic_stripe:nth-child(22) {
left: 58%;
background: rgba(255, 255, 255, 0.8);
top: -100%;
-webkit-animation-delay: 2.2s;
animation-delay: 2.2s;
}
.magic_stripe:nth-child(23) {
left: 51%;
background: rgba(254,0,4,0.8);
top: -100%;
-webkit-animation-delay: 2.3s;
animation-delay: 2.3s;
}
.magic_stripe:nth-child(24) {
left: 27%;
background: rgba(254,0,4,0.8);
top: -100%;
-webkit-animation-delay: 2.4s;
animation-delay: 2.4s;
}
.magic_stripe:nth-child(25) {
left: 34%;
background: rgba(255, 255, 255, 0.8);
top: -100%;
-webkit-animation-delay: 2.5s;
animation-delay: 2.5s;
}
.Candy_Cane_Machine {
-webkit-animation: 2s wobble infinite;
animation: 2s wobble infinite;
}
.magic_border {
width: 100%;
height: 100%;
animation: 3s Magic_Border infinite;
}
@-webkit-keyframes Magic_Border {
0% {
outline: 10px dashed red;
box-shadow: 0 0 0 10px green;
}
50% {
outline: 10px dashed green;
box-shadow: 0 0 0 10px red;
}
100% {
outline: 10px dashed red;
box-shadow: 0 0 0 10px green;
}
}
@keyframes Magic_Border {
0% {
outline: 10px dashed red;
box-shadow: 0 0 0 10px green;
}
50% {
outline: 10px dashed green;
box-shadow: 0 0 0 10px red;
}
100% {
outline: 10px dashed red;
box-shadow: 0 0 0 10px green;
}
}
#elf_small_stack {animation: whiz; }
@keyframes whiz {
0% {
left: 250%;
}
100% {
left: -250%;
}
}
@-webkit-keyframes whiz {
0% {
left: 250%;
}
100% {
left: -250%;
}
}
/* SVG Candy Cane Stripes CSS */
.Red_Candy_Stripe{fill:#E11F26;}
.White_Candy Stripe {fill:#F6F6F0;}
/* SVG Elfs with Presents Fills CSS */
.Elves_with_Presents_0{fill:#EAB67D;}
.Elves_with_Presents_1{fill:#D18654;}
.Elves_with_Presents_2{fill:#F7C992;}
.Elves_with_Presents_3{fill:#303030;}
.Elves_with_Presents_4{fill:#FF9494;}
.Elves_with_Presents_5{fill:#B1C927;}
.Elves_with_Presents_6{fill:#A8B523;}
.Elves_with_Presents_7{fill:#DB2E2A;}
.Elves_with_Presents_8{fill:#56B3BF;}
.Elves_with_Presents_9{fill:#F9BD6E;}
.Elves_with_Presents_10{fill:#FFA6C6;}
.Elves_with_Presents_11{fill:#FF8DBB;}
.Elves_with_Presents_12{fill:#EA98B9;}
.Elves_with_Presents_13{fill:#FFBC6C;}
.Elves_with_Presents_14{fill:#FFD19F;}
.Elves_with_Presents_15{fill:#97DDC2;}
.Elves_with_Presents_16{fill:#EAA459;}
.Elves_with_Presents_17{fill:#7EC4A8;}
.Elves_with_Presents_18{fill:#C72E6F;}
.Elves_with_Presents_19{fill:#AD175F;}
.Elves_with_Presents_20{fill:#EA78B4;}
.Elves_with_Presents_21{fill:#991111;}
.Elves_with_Presents_22{fill:#FFE7CF;}
.Elves_with_Presents_23{fill:#AD1212;}
.Elves_with_Presents_24{fill:#C11F1F;}
.Elves_with_Presents_25{fill:#302E2E;}
.Elves_with_Presents_26{fill:#8BE2E8;}
.Elves_with_Presents_27{fill:#4DA6AD;}
.Elves_with_Presents_28{fill:#FFC91F;}
.Elves_with_Presents_29{fill:#EFB614;}
.Elves_with_Presents_30{fill:#8F76AD;}
.Elves_with_Presents_31{fill:#B8DB49;}
.Elves_with_Presents_32{fill:#AFC457;}
.Elves_with_Presents_33{fill:#A1BC2E;}
.Elves_with_Presents_34{fill:#A2BC35;}
.Elves_with_Presents_35{fill:#F991AC;}
.Elves_with_Presents_36{fill:#FFD2E0;}
.Elves_with_Presents_37{fill:#F9CDDB;}
.Elves_with_Presents_38{fill:#AA62B7;}
.Elves_with_Presents_39{fill:#FF648D;}
.Elves_with_Presents_40{fill:#C92323;}
.Elves_with_Presents_41{fill:#EDD1B7;}
.Elves_with_Presents_42{fill:#515050;}
/* ===================================================*
."". ."",
| | / /
| | / /
| | / /
| |/ ;-._
} ` _/ / ;
| /` ) / / PEACE and LOVE
| / /_/\_/\
|/ / | Mark in New Orleans
( ' \ '- |
\ `. /
| |
| |
/* ===================================================*/
.login_frame {
position: absolute;
right: 140px;
top: 0px;
z-index: 9999;
}
.login_frame img {
position: absolute;
height: 120px;
top: 6px;
right: 0px;
}
#mainwrapper {
position: relative;
height: 730px;
width: 100%;
}
#padding {
position: absolute;
height: 40%;
width: 100%;
background-color: #c09277;
z-index: 199;
bottom: 0;
}
.sm-fw {
font-size: 20px;
}
#resp-msg {
margin: 0;
margin-top: 15px;
padding: 5px;
font-size: 20px;
display: none;
}
@media (min-height: 800px) {
body{
overflow: hidden;
}
}
@media (max-height: 800px) {
#padding{
display:none;
}
}
@media (max-width: 800px) {
body{
overflow-x:scroll;
}
#padding{
display: block;
width: 1300px;
}
}

View File

@@ -0,0 +1,323 @@
/*
* Remodal - v1.1.1
* Responsive, lightweight, fast, synchronized with CSS animations, fully customizable modal window plugin with declarative configuration and hash tracking.
* http://vodkabears.github.io/remodal/
*
* Made by Ilya Makarov
* Under MIT License
*/
/* ==========================================================================
Remodal's default mobile first theme
========================================================================== */
/* Default theme styles for the background */
.remodal-bg.remodal-is-opening,
.remodal-bg.remodal-is-opened {
-webkit-filter: blur(3px);
filter: blur(3px);
}
/* Default theme styles of the overlay */
.remodal-overlay {
background: rgba(43, 46, 56, 0.9);
}
.remodal-overlay.remodal-is-opening,
.remodal-overlay.remodal-is-closing {
-webkit-animation-duration: 0.3s;
animation-duration: 0.3s;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
}
.remodal-overlay.remodal-is-opening {
-webkit-animation-name: remodal-overlay-opening-keyframes;
animation-name: remodal-overlay-opening-keyframes;
}
.remodal-overlay.remodal-is-closing {
-webkit-animation-name: remodal-overlay-closing-keyframes;
animation-name: remodal-overlay-closing-keyframes;
}
/* Default theme styles of the wrapper */
.remodal-wrapper {
padding: 10px 10px 0;
}
/* Default theme styles of the modal dialog */
.remodal {
box-sizing: border-box;
width: 100%;
margin-bottom: 10px;
padding: 25px;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
color: #2b2e38;
background: #c09277;
}
.remodal.remodal-is-opening,
.remodal.remodal-is-closing {
-webkit-animation-duration: 0.3s;
animation-duration: 0.3s;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
}
.remodal.remodal-is-opening {
-webkit-animation-name: remodal-opening-keyframes;
animation-name: remodal-opening-keyframes;
}
.remodal.remodal-is-closing {
-webkit-animation-name: remodal-closing-keyframes;
animation-name: remodal-closing-keyframes;
}
/* Vertical align of the modal dialog */
.remodal,
.remodal-wrapper:after {
vertical-align: middle;
}
/* Close button */
.remodal-close {
position: absolute;
top: 0;
left: 0;
display: block;
overflow: visible;
width: 35px;
height: 35px;
margin: 0;
padding: 0;
cursor: pointer;
-webkit-transition: color 0.2s;
transition: color 0.2s;
text-decoration: none;
color: #95979c;
border: 0;
outline: 0;
background: transparent;
}
.remodal-close:hover,
.remodal-close:focus {
color: #2b2e38;
}
.remodal-close:before {
font-family: Arial, "Helvetica CY", "Nimbus Sans L", sans-serif !important;
font-size: 25px;
line-height: 35px;
position: absolute;
top: 0;
left: 0;
display: block;
width: 35px;
content: "\00d7";
text-align: center;
}
/* Dialog buttons */
.remodal-confirm,
.remodal-cancel {
font: inherit;
display: inline-block;
overflow: visible;
min-width: 110px;
margin: 0;
padding: 12px 0;
cursor: pointer;
-webkit-transition: background 0.2s;
transition: background 0.2s;
text-align: center;
vertical-align: middle;
text-decoration: none;
border: 0;
outline: 0;
}
.remodal-confirm {
color: #fff;
background: #81c784;
}
.remodal-confirm:hover,
.remodal-confirm:focus {
background: #66bb6a;
}
.remodal-cancel {
color: #fff;
background: #e57373;
}
.remodal-cancel:hover,
.remodal-cancel:focus {
background: #ef5350;
}
/* Remove inner padding and border in Firefox 4+ for the button tag. */
.remodal-confirm::-moz-focus-inner,
.remodal-cancel::-moz-focus-inner,
.remodal-close::-moz-focus-inner {
padding: 0;
border: 0;
}
/* Keyframes
========================================================================== */
@-webkit-keyframes remodal-opening-keyframes {
from {
-webkit-transform: scale(1.05);
transform: scale(1.05);
opacity: 0;
}
to {
-webkit-transform: none;
transform: none;
opacity: 1;
-webkit-filter: blur(0);
filter: blur(0);
}
}
@keyframes remodal-opening-keyframes {
from {
-webkit-transform: scale(1.05);
transform: scale(1.05);
opacity: 0;
}
to {
-webkit-transform: none;
transform: none;
opacity: 1;
-webkit-filter: blur(0);
filter: blur(0);
}
}
@-webkit-keyframes remodal-closing-keyframes {
from {
-webkit-transform: scale(1);
transform: scale(1);
opacity: 1;
}
to {
-webkit-transform: scale(0.95);
transform: scale(0.95);
opacity: 0;
-webkit-filter: blur(0);
filter: blur(0);
}
}
@keyframes remodal-closing-keyframes {
from {
-webkit-transform: scale(1);
transform: scale(1);
opacity: 1;
}
to {
-webkit-transform: scale(0.95);
transform: scale(0.95);
opacity: 0;
-webkit-filter: blur(0);
filter: blur(0);
}
}
@-webkit-keyframes remodal-overlay-opening-keyframes {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes remodal-overlay-opening-keyframes {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@-webkit-keyframes remodal-overlay-closing-keyframes {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
@keyframes remodal-overlay-closing-keyframes {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
/* Media queries
========================================================================== */
@media only screen and (min-width: 641px) {
.remodal {
max-width: 700px;
}
}
/* IE8
========================================================================== */
.lt-ie9 .remodal-overlay {
background: #2b2e38;
}
.lt-ie9 .remodal {
width: 700px;
}

View File

@@ -0,0 +1,93 @@
/*
* Remodal - v1.1.1
* Responsive, lightweight, fast, synchronized with CSS animations, fully customizable modal window plugin with declarative configuration and hash tracking.
* http://vodkabears.github.io/remodal/
*
* Made by Ilya Makarov
* Under MIT License
*/
/* ==========================================================================
Remodal's necessary styles
========================================================================== */
/* Hide scroll bar */
html.remodal-is-locked {
overflow: hidden;
-ms-touch-action: none;
touch-action: none;
}
/* Anti FOUC */
.remodal,
[data-remodal-id] {
display: none;
}
/* Necessary styles of the overlay */
.remodal-overlay {
position: fixed;
z-index: 9999;
top: -5000px;
right: -5000px;
bottom: -5000px;
left: -5000px;
display: none;
}
/* Necessary styles of the wrapper */
.remodal-wrapper {
position: fixed;
z-index: 10000;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: none;
overflow: auto;
text-align: center;
-webkit-overflow-scrolling: touch;
}
.remodal-wrapper:after {
display: inline-block;
height: 100%;
margin-left: -0.05em;
content: "";
}
/* Fix iPad, iPhone glitches */
.remodal-overlay,
.remodal-wrapper {
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
/* Necessary styles of the modal dialog */
.remodal {
position: relative;
outline: none;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
text-size-adjust: 100%;
}
.remodal-is-initialized {
/* Disable Anti-FOUC */
display: inline-block;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 467 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,89 @@
// Conveyor inspired from https://codepen.io/dariocorsi/pen/yOOBJK
var inputItem = document.getElementsByClassName('trash-in')[0];
var outputItem = document.getElementsByClassName('toy-out')[0];
var index = 0;
var ChristmasPresents = document.getElementsByClassName('ChristmasPresents');
function cycleChristmasPresents(){
setInterval(function(){
for (var i = 0; i < ChristmasPresents.length; ++i){
ChristmasPresents[i].classList.remove('active');
ChristmasPresents[i].classList.remove('active');
};
ChristmasPresents[index].classList.add('active');
ChristmasPresents[index].classList.add('active');
if(index < ChristmasPresents.length -1 ){
index = index + 1;
} else{
index = 0;
}
console.log('index', index);
}, 10000);
};
cycleChristmasPresents();
// JavaScript Document
var c = document.getElementById('tiffany_snow'),
$c = c.getContext("2d");
var w = c.width = window.innerWidth,
h = c.height = window.innerHeight;
Snowy();
function Snowy() {
var snow, arr = [];
var num = 600, tsc = 1, sp = 1;
var sc = 1.3, t = 0, mv = 20, min = 1;
for (var i = 0; i < num; ++i) {
snow = new Flake();
snow.y = Math.random() * (h + 50);
snow.x = Math.random() * w;
snow.t = Math.random() * (Math.PI * 2);
snow.sz = (100 / (10 + (Math.random() * 100))) * sc;
snow.sp = (Math.pow(snow.sz * .8, 2) * .15) * sp;
snow.sp = snow.sp < min ? min : snow.sp;
arr.push(snow);
}
go();
function go(){
window.requestAnimationFrame(go);
$c.clearRect(0, 0, w, h);
$c.fillStyle = 'hsla(242, 95%, 3%, 1)';
$c.fillRect(0, 0, w, h);
$c.fill();
for (var i = 0; i < arr.length; ++i) {
f = arr[i];
f.t += .05;
f.t = f.t >= Math.PI * 2 ? 0 : f.t;
f.y += f.sp;
f.x += Math.sin(f.t * tsc) * (f.sz * .3);
if (f.y > h + 50) f.y = -10 - Math.random() * mv;
if (f.x > w + mv) f.x = - mv;
if (f.x < - mv) f.x = w + mv;
f.draw();}
}
function Flake() {
this.draw = function() {
this.g = $c.createRadialGradient(this.x, this.y, 0, this.x, this.y, this.sz);
this.g.addColorStop(0, 'hsla(255,255%,255%,1)');
this.g.addColorStop(1, 'hsla(255,255%,255%,0)');
$c.moveTo(this.x, this.y);
$c.fillStyle = this.g;
$c.beginPath();
$c.arc(this.x, this.y, this.sz, 0, Math.PI * 2, true);
$c.fill();}
}
}
/*________________________________________*/
// window.addEventListener('resize', function(){
// c.width = w = window.innerWidth;
// c.height = h = window.innerHeight;
// }, false);

View File

@@ -0,0 +1,53 @@
$(document).ready(() => {
$('#submit-btn').on('click', submit);
});
const elf_info = (elf_id) => {
inst = $('[data-remodal-id=modal]').remodal();
inst.open();
$('#elfavatar').attr('src',`/static/images/elf${elf_id}.png`);
$('#elfname').text((elf_id == 1) ? 'Lhoris Farrie' : 'Ievis Chaeqirelle');
}
const submit = async () => {
$('#submit-btn').prop('disabled', true);
// prepare alert
let card = $('#resp-msg');
card.attr('class', 'alert alert-info');
card.hide();
// validate
let query = $('#query').val();
if ($.trim(query) === '') {
$('#submit-btn').prop('disabled', false);
card.text('Please input your query first!');
card.attr('class', 'alert alert-danger');
card.show();
return;
}
await fetch('/api/submit', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({query: query}),
})
.then((response) => response.json()
.then((resp) => {
card.attr('class', 'alert alert-danger');
if (response.status == 200) {
card.attr('class', 'alert alert-success');
}
card.text(resp.message);
card.show();
}))
.catch((error) => {
card.text(error);
card.attr('class', 'alert alert-danger');
card.show();
});
$('#submit-btn').prop('disabled', false);
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,23 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Toy Workshop</title>
<link rel="icon" href="/static/images/logo.png" />
<link rel="stylesheet" type="text/css" href="/static/css/nes-core.min.css" />
<link rel="stylesheet" type="text/css" href="/static/css/dashboard.css" />
</head>
<body>
<img src="/static/images/cflower.png" class="main-logo" />
<p class="pb-3">Welcome back, admin!</p>
<div class="dash-frame">
{{#each queries}}
<p>{{{this.query}}}</p>
{{else}}
<p class="empty">No content</p>
{{/each}}
</div>
</body>
<script type="text/javascript" src="/static/js/jquery-3.6.0.min.js"></script>
<script type="text/javascript" src="/static/js/auth.js"></script>
</html>